MySql更新锁定哪些数据范围?
1。背景
在项目中,我们经常使用更新
短语。那么update
语句锁定了哪些表记录呢?这里我们通过一些简单的案例来模拟一下。 这是我自己的看法。如果理解有误,请指出。
2。所需信息
2.1 数据库隔离级别
mysql> show variables like 'transaction_isolation'; +-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set (0.00 sec)
2.2 数据库版本
mysql> select version(); +-----------+ | version() | +-----------+ | 8.0.28 | +-----------+ 1 row in set (0.00 sec)
2.3 数据库存储引擎
mysql> show variables like '%storage_engine%'; +---------------------------------+-----------+ | Variable_name | Value | +---------------------------------+-----------+ | default_storage_engine | InnoDB | | default_tmp_storage_engine | InnoDB | | disabled_storage_engines | | | internal_tmp_mem_storage_engine | TempTable | +---------------------------------+-----------+ 4 rows in set (0.01 sec)
2.4 是否对记录或索引添加了锁? 到索引中,那么如果表上没有创建索引,是否会添加到表中呢?其实不是,它也被添加到目录中并且有一个默认值。
记录锁始终锁定索引记录,即使表定义为没有索引。在这种情况下,InnoDB会创建一个隐藏的聚集索引,并使用该索引来锁定记录
参考链接:https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html#innodb-intention -locks
2.5 update...其中锁定的基本单位是
UPDATE ... WHERE ... 对搜索遇到的每条记录设置独占的 next key 锁
这里可以理解为锁定的单位是:下一个键
锁
2.6行级锁
2.6.1记录锁
使用唯一索引锁定行来查找唯一行的语句不需要间隙锁定。 (此 下一键锁位于 如果索引值包含 问题: 说明: 此时可以发现表中扫描到的所有记录都已添加。下一个键锁(该锁添加到索引中) 目前只能将小于最小临界值的记录添加到表中。 ,正常范围正 3.2 正常指标测试 说明:先到常规目录 说明: 说明: 1。 https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html#innodb-intention-locks仅存储一个,编辑。它实际上锁定了该记录的索引。
记录锁是目录记录锁。例如 SELECT c1 FROM t WHERE c1 = 10 UPDATE;防止其他事务添加、更新或删除 t.c1 值为 10 的行。
2.6.2 间隙锁
间隙锁
,间隙锁是记录中目录之间的间隙,即锁定间隙。 开合前后开合间隔
,不包括盘本身。如果使用 一列的唯一索引值
更新间隙锁定
,则 会锁定
。 。
光圈锁定目的
: 不包括
情况,其中搜索条件仅包含多列唯一索引
中的一些列;在这种情况下会发生间隙锁定。)❙❙❀。 .3 下一键锁 索引记录中。 记录锁定
和间隙锁定 的组合,在
索引记录之前有间隙。它还锁定间隙,
从前面打开并在
之间闭合。包括光盘本身。 1,5,10,30
,则下一个键锁可以跨越下一个区间(negative infinity, 1]
(1, 115
(5, 10]
(10, 30]
(30, positive infinity)
到负无穷大❀到负无穷大。
正无穷大
指的是正无穷大。2.6.4 测试锁表的表结构
create table test_record_lock
(
id int not null comment '主键',
age int null comment '年龄,普通索引',
name varchar(10) null comment '姓名,无索引',
constraint test_record_lock_pk
primary key (id)
)
comment '测试记录锁';
create index test_record_lock_age_index
on test_record_lock (age);
2.6.5 测试表中的数据
mysql> select * from test_record_lock;
+----+------+--------+
| id | age | name |
+----+------+--------+
| 1 | 10 | 张三 |
| 5 | 20 | 李四 |
| 8 | 25 | 王五 |
+----+------+--------+
3 rows in set (0.00 sec)
2.7 查看数据库当前的锁
selectda_performance;说明:
字段 值 说明 lock_type
TABLE CLock锁定已添加到记录中 锁定模式
IX 目的锁定 X或S 下一个键锁定
锁定记录本身以及记录之前的间隙AP X,REC_NOT锁定记录本身 S,REC_NOT_GAP 记录锁定只锁定记录本身 X,GAP 开锁 表示主键值❙值:常规索引的值
第二个值:主键值X,GAP
能否理解X
GAP
锁。 ? 说明:3.1.2对应的查询记录不存在 -01
3.1.3 对应更新-记录不存在-02
3.1.4 区域更新
1.小于等于最大临界值
2,大于等于最小临界值
mysql> begin;
Query OK, 0 rows affected (0.01 sec)
mysql> update test_record_lock set name = 'aaa' where id >= 1;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select LOCK_TYPE,INDEX_NAME,LOCK_MODE,LOCK_DATA from performance_schema.data_locks;
+-----------+------------+---------------+------------------------+
| LOCK_TYPE | INDEX_NAME | LOCK_MODE | LOCK_DATA |
+-----------+------------+---------------+------------------------+
| TABLE | NULL | IX | NULL |
| RECORD | PRIMARY | X,REC_NOT_GAP | 1 |
| RECORD | PRIMARY | X | supremum pseudo-record |
| RECORD | PRIMARY | X | 8 |
| RECORD | PRIMARY | X | 5 |
+-----------+------------+---------------+------------------------+
5 rows in set (0.01 sec)
3.2.1 对应更新记录是否存在
AGE
加Next-Key锁定,锁定范围为(10,20]3.2.2 对应更新 - 记录不存在
3.2.3 范围更新
3.3 无索引更新
如上图所示,在没有索引的情况下更新数据表是危险的,需谨慎处理
。没有索引更新会导致全表扫描,添加所有扫描记录next-key lock
.3.参考链接
2,https://dev.mysql.com/doc/refman/8.0/ fi/innodb-locking.html
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。