返回顶部
首页 > 资讯 > 数据库 >MySQL在RR隔离级别下的unique失效和死锁模拟
  • 864
分享到

MySQL在RR隔离级别下的unique失效和死锁模拟

2024-04-02 19:04:59 864人浏览 八月长安
摘要

今天在测试Mysql事务隔离级别的时候,发现了一个有趣的问题,也参考了杨一之前总结的一篇。Http://blog.itpub.net/22664653/viewspace-1612574/ &nb

今天在测试Mysql事务隔离级别的时候,发现了一个有趣的问题,也参考了杨一之前总结的一篇。Http://blog.itpub.net/22664653/viewspace-1612574/

    问题的背景是在mysql隔离级别为RR(Repeatable Read)时,唯一性约束没有失效,多并发的场景下能够复现出下面的问题。

  这样一个看起来不可能的事情,能否复现呢。

MySQL在RR隔离级别下的unique失效和死锁模拟

  我都这么问了,潜台词就是可以,要不今天的笔记就一个问题就结束了。

  为了模拟这个问题,我们打开两个会话窗口,来模拟一下这个问题。

mysql> create table test3(id1 int primary key,id2 int unique,id3 int);
Query OK, 0 rows affected (0.01 sec)

#会话1
set autocommit=0;
mysql> insert into test3 values(1,20170831,1);
Query OK, 1 row affected (0.00 sec)
commit;


#会话2

这个时候充分利用了mvcC的特性,这是一个快照读。

mysql> select *from test3;
+-----+----------+------+
| id1 | id2      | id3  |
+-----+----------+------+
|   1 | 20170831 |    1 |
+-----+----------+------+
1 row in set (0.00 sec)
会话1插入了一条数据,我们在会话2中删除。
mysql> delete from test3 where id1=1;
Query OK, 1 row affected (0.01 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
提交之后,会话2中就修改完毕了。

#会话1

这个时候根据MVCC的特点,会话2中已经删除了id1=1的记录。所以主键列相关数据是插入不了了,那么唯一性索引呢。根据MVCC的特点,能够保证重复读的特点,读到的数据还是不变。

mysql> select *from test3;
+-----+----------+------+
| id1 | id2      | id3  |
+-----+----------+------+
|   1 | 20170831 |    1 |
+-----+----------+------+
1 row in set (0.00 sec)

现在的关键就来了,我们插入一条数据,主键不冲突,唯一性索引冲突,看看是否能够插入成功。

mysql> insert into test3 values(2,20170831,2);
Query OK, 1 row affected (0.00 sec)

魔性的一幕上演了。

mysql> select *from test3;
+-----+----------+------+
| id1 | id2      | id3  |
+-----+----------+------+
|   1 | 20170831 |    1 |
|   2 | 20170831 |    2 |
+-----+----------+------+
2 rows in set (0.00 sec)

当然到了这里,我们继续玩一玩,常规来说,插入主键列冲突数据可能是行不通的,比如id1=1,id2=20170831,id3=1,客户端很快会反馈失败。但是在这里做唯一性校验时,因为id1=1的数据已经被物理删除了。

mysql>  insert into test3 values(1,20170831,1);
ERROR 1062 (23000): Duplicate entry '20170831' for key 'id2'


我们就来继续模拟个死锁吧。

会话2:

这个步骤是做一次数据清理,where条件中是根据主键来查找删除。

mysql> delete from test3 where id1=1;
Query OK, 0 rows affected (0.00 sec)


会话1:

mysql> insert into test3 values(1,20170831,1);

这个时候会话会被阻塞


会话2:

这个时候在会话2继续插入这个值,就会报出死问题。

mysql> insert into test3 values(1,20170831,1);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

--产生死锁


会话1:

这个时候死锁有了,事务也自动回滚了。再次插入违反约束的数据,就不行了。

mysql> insert into test3 values(1,20170831,1);
ERROR 1062 (23000): Duplicate entry '20170831' for key 'id2'


我们来看看在上面的测试过程中,关于死锁的日志
2017-08-28T07:27:48.329631Z 14140 [Note] InnoDB: Transactions deadlock detected, dumping detailed infORMation.
2017-08-28T07:27:48.329740Z 14140 [Note] InnoDB:
*** (1) TRANSACTION:

TRANSACTION 31790, ACTIVE 315 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1
MySQL thread id 14138, OS thread handle 139809903986432, query id 108686 localhost root update
insert into test3 values(1,20170831,1)
2017-08-28T07:27:48.329801Z 14140 [Note] InnoDB: *** (1) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 36 page no 3 n bits 72 index PRIMARY of table `test`.`test3` trx id 31790 lock mode S waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000001; asc     ;;
 1: len 6; hex 000000007c2f; asc     |/;;
 2: len 7; hex 33000001ac2f63; asc 3    /c;;
 3: len 4; hex 8133c84f; asc  3 O;;
 4: len 4; hex 80000001; asc     ;;

2017-08-28T07:27:48.330040Z 14140 [Note] InnoDB: *** (2) TRANSACTION:

TRANSACTION 31791, ACTIVE 51 sec inserting
mysql tables in use 1, locked 1
5 lock struct(s), heap size 1136, 4 row lock(s), undo log entries 1
MySQL thread id 14140, OS thread handle 139809903720192, query id 108687 localhost root update
insert into test3 values(1,20170831,1)
2017-08-28T07:27:48.330084Z 14140 [Note] InnoDB: *** (2) HOLDS THE LOCK(S):

RECORD LOCKS space id 36 page no 3 n bits 72 index PRIMARY of table `test`.`test3` trx id 31791 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000001; asc     ;;
 1: len 6; hex 000000007c2f; asc     |/;;
 2: len 7; hex 33000001ac2f63; asc 3    /c;;
 3: len 4; hex 8133c84f; asc  3 O;;
 4: len 4; hex 80000001; asc     ;;

2017-08-28T07:27:48.330342Z 14140 [Note] InnoDB: *** (2) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 36 page no 4 n bits 72 index id2 of table `test`.`test3` trx id 31791 lock mode S waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 8133c84f; asc  3 O;;
 1: len 4; hex 80000002; asc     ;;
2017-08-28T07:27:48.330470Z 14140 [Note] InnoDB: *** WE ROLL BACK TRANSACTION (2)

这里会充分把x,s锁,细粒度锁的知识联系起来,搞明白又进步了一大截。


会话1:

最后,我们提交一下事务,再次查看数据,一切又恢复了平静。

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select *from test3;
+-----+----------+------+
| id1 | id2      | id3  |
+-----+----------+------+
|   2 | 20170831 |    2 |
+-----+----------+------+
1 row in set (0.00 sec)





您可能感兴趣的文档:

--结束END--

本文标题: MySQL在RR隔离级别下的unique失效和死锁模拟

本文链接: https://lsjlt.com/news/47511.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MySQL在RR隔离级别下的unique失效和死锁模拟
    今天在测试MySQL事务隔离级别的时候,发现了一个有趣的问题,也参考了杨一之前总结的一篇。http://blog.itpub.net/22664653/viewspace-1612574/ &nb...
    99+
    2024-04-02
  • Innodb中RR隔离级别下insert...select 对select表加锁模型和死锁案列分析
    这篇文章主要介绍“Innodb中RR隔离级别下insert...select 对select表加锁模型和死锁案列分析”,在日常操作中,相信很多人在Innodb中RR隔离级别下insert...se...
    99+
    2024-04-02
  • RR与RC隔离级别下MySQL不同的加锁解锁方式有哪些
    小编给大家分享一下RR与RC隔离级别下MySQL不同的加锁解锁方式有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!|  RC与RR隔离级别下MySQL不同的加锁解锁方式MyS...
    99+
    2024-04-02
  • MVCC 在RC 和 RR 隔离等级下的工作机制
    一.数据行隐藏列 innodb为每行记录都实现了三个隐藏字段 6字节的事务ID(DB_TRX_ID) 7字节的回滚指针(DB_ROLL_PTR) 隐藏的ID 事务1修改行值过程: X锁锁定该行 ...
    99+
    2024-04-02
  • RR与RC隔离级别下索引和锁的测试脚本示例代码
    基本概念 当前读与快照读 在MVCC中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)。 快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁...
    99+
    2024-04-02
  • MySQL的在RC和RR模式下的锁
    InnoDB的锁机制:数据库使用所是为了支持更好的并发,提供数据的完整性和一致性。InnoDB是一个支持锁的存储引擎,锁的类型有:共享锁(S)、排它锁(X)、意向共享锁(IS)、意向排它锁(IX)。为了支持...
    99+
    2024-04-02
  • MySQL中的锁和事务隔离级别是什么
    MySQL中的锁和事务隔离级别是什么?可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。锁数据库的锁机制是区别于文件系统的一个关键特性。用于管理对共享资源...
    99+
    2024-04-02
  • MySQL隔离级别和锁机制的深入讲解
    目录简述:1. 事务的四大特性2.多事务并发带来的问题3.事务的隔离级别4.演示不同隔离级别出现的问题读未提交读已提交可重复读串行化5.锁机制间隙锁临建锁排他锁总结简述: 我们的M...
    99+
    2024-04-02
  • 怎样解决MySQL数据库在RR隔离级别下容易产生幻读的问题
    这篇文章将为大家详细讲解有关怎样解决MySQL数据库在RR隔离级别下容易产生幻读的问题,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的...
    99+
    2024-04-02
  • 分析MySQL数据库Innodb中的事务隔离级别和锁的关系
    本篇内容主要讲解“分析MySQL数据库Innodb中的事务隔离级别和锁的关系”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“分析MySQL数据库Innodb中的事...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作