文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

浅谈MySql update会锁定哪些范围的数据

2022-06-24 10:00

关注

1、背景

在项目中,我们经常使用到update语句,那么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 锁是加在记录上还是索引上

锁是加在索引上,那如果表中没有建立索引,是否就是加在表上的呢?其实不是,也是加在索引的,会存在一个默认的。

Record locks always lock index records, even if a table is defined with no indexes. For such cases, InnoDB creates a hidden clustered index and uses this index for record locking

参考链接: https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html

2.5 update...where加锁的基本单位是

UPDATE ... WHERE ... sets an exclusive next-key lock on every record the search encounters
此处可以理解加锁的单位是: next-key

2.6 行级锁

2.6.1 Record Locks

记录锁,即只会锁定一条记录。其实是锁定这条记录的索引。

A record lock is a lock on an index record. For example, SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; prevents any other transaction from inserting, updating, or deleting rows where the value of t.c1 is 10.

2.6.2 Gap Locks

间隙锁,间隙锁是在索引记录之间的间隙上的锁,即锁定一个区间。前开后开区间,不包括记录本身。

间隙锁如果是使用单列唯一索引值进行更新的话,是会退化Record Lock

间隙锁的目的

Gap locking is not needed for statements that lock rows using a unique index to search > for a unique row. (This does not include the case that the search condition includes only > some columns of a multiple-column unique index; in that case, gap locking does occur.)

2.6.3 Next-Key Locks

Next-Key Lock 是索引记录上记录锁索引记录之前间隙上的间隙锁的组合。也是锁定一个区间,前开后闭区间。包括记录本身。

如果索引值包括 1,5,10,30,那么next key 锁可能涵盖如下区间

(negative infinity, 1]
(1, 115
(5, 10]
(10, 30]
(30, positive infinity)

negative infinity指的是负无穷。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 查看数据库中当前的锁

select * from performance_schema.data_locks;

字段解释:

字段解释
lock_typeTABLE锁是加在表上
 RECORD锁加在记录上
lock_modeIX意向排他锁
 X或者Snext-key lock 
锁定记录本身和记录之前的间隙
 X,REC_NOT_GAPRecord Lock 只锁记录自身
 S,REC_NOT_GAPRecord Lock 只锁记录自身
 X,GAPgap lock
 X,INSERT_INTENTION插入意向锁
lock_data具体的某个数字表示主键的值
 值,值第一个值:普通索引的值
第二个值:主键值

疑问:X,GAP是否可以理解成X锁退化成了GAP锁。

3、测试数据加锁

3.1 唯一索引测试

此处适用单个字段的唯一索引,不适合多个字段的唯一索引

3.1.1 等值更新-记录存在

浅谈MySqlupdate会锁定哪些范围的数据

解释:

加next-key lock,那么锁定的记录范围为 (1,5]。

因为是唯一索引,且查询的值存在,next-key lock退化成record lock,即最终只锁定了id=5的这一行数据。其余的数据不影响。

3.1.2 等值查询-记录不存在-01

浅谈MySqlupdate会锁定哪些范围的数据

解释:

3.1.3 等值更新-记录不存在-02

浅谈MySqlupdate会锁定哪些范围的数据

3.1.4 范围更新

1、小于或等于最大临界值

浅谈MySqlupdate会锁定哪些范围的数据

此时可以发现表中扫描到的记录都加上了next key lock(锁加在索引上)

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、正常范围

浅谈MySqlupdate会锁定哪些范围的数据

3.2 普通索引测试

3.2.1 等值更新-记录存在

浅谈MySqlupdate会锁定哪些范围的数据

解释:

3.2.2 等值更新-记录不存在

浅谈MySqlupdate会锁定哪些范围的数据

解释:

3.2.3 范围更新

浅谈MySqlupdate会锁定哪些范围的数据

解释:

普通索引的范围更新,next-key-lock不回退化成 gap lock。

3.3 无索引更新

浅谈MySqlupdate会锁定哪些范围的数据

从上图中可知,无索引更新数据表危险,需要谨慎处理。无索引更新,会导致全表扫描,导致将扫描到的所有记录都加上next-key lock

4、参考链接

1、https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html
2、https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html

到此这篇关于浅谈MySql update会锁定哪些范围的数据的文章就介绍到这了,更多相关MySql update锁定范围内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯