ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RR|RC隔离级别下行锁的情况

2021-06-10 21:35:27  阅读:254  来源: 互联网

标签:隔离 RR hex len asc name2 RC id name


测试准备

test库下建表tt

CREATE TABLE `tt` (
  `id` int(11) NOT NULL,
  `code` int(11) DEFAULT NULL,
  `name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `vers` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `version` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_code` (`code`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci 

插入值

INSERT INTO TEST.TT VALUES(1,1,'name1','5.7.11', '7');
INSERT INTO TEST.TT VALUES(2,2,'name2','5.7.12','8');
INSERT INTO TEST.TT VALUES(3,3,'name2','V5.7','9');
INSERT INTO TEST.TT VALUES(4,3,'name4','5.7.15','10');
INSERT INTO TEST.TT VALUES(5,6,'name6','5.7.16','11');
INSERT INTO TEST.TT VALUES(6,7,'name7','v5.7','12');

打开InnoDB锁监控,具体参考https://dev.mysql.com/doc/refman/8.0/en/innodb-enabling-monitors.html:

SET GLOBAL innodb_status_output=ON;
SET GLOBAL innodb_status_output_locks=ON;

RR(repeatable-read)隔离级别

情况一

session1:

sql>begin;
sql>update tt set vers='vsss' where code=3 and name='name2'; ##执行计划是index merge(两个索引联合了)

session2:

sql>update tt set vers='xx' where name='name2' and version=8;
...等待,直到50s超时

查看show engine innodb status \G

=====================================
2021-06-10 17:31:37 0x7f2fac9aa700 INNODB MONITOR OUTPUT
=====================================
...
...
MySQL thread id 24, OS thread handle 139842735195904, query id 219 localhost root updating
update tt set vers='xx' where name='name2' and version=8
------- TRX HAS BEEN WAITING 14 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 34 page no 5 n bits 80 index idx_name of table `test`.`tt` trx id 6977 lock_mode X waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 5; hex 6e616d6532; asc name2;;
 1: len 4; hex 80000002; asc     ;;
...

结论:上述dml,会话1 update所更改的二级索引值所在的gap范围会加锁,假如会话2更改的行所在的二级索引值在会话1的gap范围,则会话2在会话1的二级索引上等待锁。二级索引会对(单独用该索引)搜索到的行加锁(其他过滤条件不影响加锁行的范围)(此种情况为二级索引情况)

情况二

session1

sql>begin;
sql>update tt set vers='vsss' where code=3 and name<='name2' and name >'name1'; ##执行计划走code索引

session2

sql>update tt set vers='ssss' where name='name2' and version=8; ##执行计划走name索引

查看show engine innodb status \G

=====================================
2021-06-10 19:44:29 0x7f2fac9aa700 INNODB MONITOR OUTPUT
=====================================
...
...
MySQL thread id 26, OS thread handle 139842735736576, query id 252 localhost root updating
update tt set vers='ssss' where name='name2' and version=8
------- TRX HAS BEEN WAITING 6 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 34 page no 3 n bits 96 index PRIMARY of table `test`.`tt` trx id 6990 lock_mode X locks rec but not gap waiting
Record lock, heap no 15 PHYSICAL RECORD: n_fields 7; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 6; hex 000000001b4b; asc      K;;
 2: len 7; hex 32000001410282; asc 2   A  ;;
 3: len 4; hex 80000003; asc     ;;
 4: len 5; hex 6e616d6532; asc name2;;
 5: len 4; hex 76737373; asc vsss;;
 6: len 1; hex 39; asc 9;;
...

结论:session1和session2采用的是不同索引,索引session2是在等待session1的primary值为9的行记录的锁。(此种情况为主键锁等待)

RC(read-commit)隔离级别

情况一

session1

sql>begin;
sql>update tt set vers='vsss' where version='9' and name='name2';

session2

sql>update tt set vers='XXXXXcccc' where name='name2' and version='8';
...等待,直到50s超时

sql>update tt force index(idx_name) set vers='XXXXXcccc' where name='name2' and id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
[可以成功执行]

查看show engine innodb status \G

=====================================
2021-06-10 20:31:13 0x7f58d064d700 INNODB MONITOR OUTPUT
=====================================
...
...
------------
TRANSACTIONS
------------...
---TRANSACTION 7947, ACTIVE 8 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 2, OS thread handle 140019430659840, query id 24 localhost root updating
update tt set vers='XXXXXcccc' where name='name2' and version=8
------- TRX HAS BEEN WAITING 8 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 34 page no 5 n bits 80 index idx_name of table `test`.`tt` trx id 7947 lock_mode X locks rec but not gap waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 5; hex 6e616d6532; asc name2;;
 1: len 4; hex 80000003; asc     ;;

------------------
TABLE LOCK table `test`.`tt` trx id 7947 lock mode IX
RECORD LOCKS space id 34 page no 5 n bits 80 index idx_name of table `test`.`tt` trx id 7947 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 5; hex 6e616d6532; asc name2;;
 1: len 4; hex 80000002; asc     ;;

RECORD LOCKS space id 34 page no 3 n bits 96 index PRIMARY of table `test`.`tt` trx id 7947 lock_mode X locks rec but not gap
Record lock, heap no 31 PHYSICAL RECORD: n_fields 7; compact format; info bits 0
 0: len 4; hex 80000002; asc     ;;
 1: len 6; hex 000000001f0b; asc       ;;
 2: len 7; hex 280000016001ca; asc (   `  ;;
 3: len 4; hex 80000002; asc     ;;
 4: len 5; hex 6e616d6532; asc name2;;
 5: len 9; hex 585858585863636363; asc XXXXXcccc;;
 6: len 1; hex 38; asc 8;;

RECORD LOCKS space id 34 page no 5 n bits 80 index idx_name of table `test`.`tt` trx id 7947 lock_mode X locks rec but not gap waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 5; hex 6e616d6532; asc name2;;
 1: len 4; hex 80000003; asc     ;;

---TRANSACTION 7946, ACTIVE 99 sec
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 3, OS thread handle 140019430389504, query id 22 localhost root
TABLE LOCK table `test`.`tt` trx id 7946 lock mode IX
RECORD LOCKS space id 34 page no 5 n bits 80 index idx_name of table `test`.`tt` trx id 7946 lock_mode X locks rec but not gap
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 5; hex 6e616d6532; asc name2;;
 1: len 4; hex 80000003; asc     ;;

RECORD LOCKS space id 34 page no 3 n bits 96 index PRIMARY of table `test`.`tt` trx id 7946 lock_mode X locks rec but not gap
Record lock, heap no 15 PHYSICAL RECORD: n_fields 7; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 6; hex 000000001f0a; asc       ;;
 2: len 7; hex 270000013a031e; asc '   :  ;;
 3: len 4; hex 80000003; asc     ;;
 4: len 5; hex 6e616d6532; asc name2;;
 5: len 4; hex 76737373; asc vsss;;
 6: len 1; hex 39; asc 9;;
...
...

结论:会话1通过name索引(和version=9)找到一行记录,并在该二级索引值([name='name2',id=3])上加锁;这时会话2通过name索引(找到两行:[name='name2',id=2] [name='name2',id=3]),这时会等待 [name='name2',id=3]二级索引值记录行上的锁。(此种情况一开始会对二级索引所检索的值加锁 [例如有2行],根据其他条件 [过滤了一行] 找到的primary key [1行],则在这行primary key和二级索引 [过滤了一行] 的key上加锁,过滤掉的一行二级索引值的锁释放)

 

标签:隔离,RR,hex,len,asc,name2,RC,id,name
来源: https://www.cnblogs.com/jiangxm157/p/14872860.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有