Purge死锁

场景说明

Purge死锁说明

表中存在记录(unique key) 10,20,30,40 (且有 自增主键 ),现在删除记录 20 ,并且已经 提交 了该事物。 purge 线程此时还 没有回收 该记录,且此时又 插入 新的记录 20 。

+------+------+------+------+

orignal | 10 | 20 | 30 | 40 |

unique +------+------+------+------+

delete 20 +------+------+------+------+

| 10 | 20* | 30 | 40 | (20 : delete-mark)

and commit +------+^----^+------+------+

| |

non happen | +--insert new 20

|

Purge

# 自增主键图中没有给出

回顾插入过程 完整的插入过程如下:

假设现在有记录 10,30,50,70 ;且为 unique key ,需要插入记录 25 。

1. 找到 小于等于25的记录 ,这里是 10

如果记录中已经 存在记录25 ,且带有 唯一性约束 ,则需要在 记录25 上增加 S Gap-lock (purge的案例中,老 记录20* 要加S lock的原因)

不直接报错退出或者提示已存在的原因,是因为有可能之前的 记录25 标记为删除( delete-mark ),然后等待 purge

如果 假设 这里 没有S Gap-Lock ,此时 记录30 上也 没有锁 的,按照下面的步骤,可以插入 两个25 ,这样就 破坏了唯一性约束

2. 找到 记录10的下一条记录 ,这里是 30

3. 判断 下一条记录30 上是否有锁(如果有=25的情况,后面再讨论)

判断 30 上面如果 没有锁 ,则 可以插入

判断 30 上面如果有 Record Lock ,则 可以插入

判断 30 上面如果有 Gap Lock / Next-Key Lock ,则无法插入,因为锁的范围是 (10,30) / (10,30] ;在 30 上增加 insert intention lock (此时处于 waiting 状态),当 Gap Lock / Next-Key Lock 释放时,等待的事物(transaction)将被 唤醒 ,此时 记录30 上才能获得 insert intention lock ,然后再插入 记录25

在这个场景中,新插入的记录 20 ,和已经存在的记录 20* 相等,且带有唯一约束,那此时就需要在记录 20* 上增加 S lock(with gap)

演示

因为要模拟插入记录 20* 的时候,老的 记录20 要存在,所以使用debug版本,将 purge线程停掉 。

[root@MyServer ~]> mysqld-debug --version

mysqld-debug Ver 5.7.11-debug for linux-glibc2.5 on x86_64 (MySQL Community Server - Debug (GPL))

[root@MyServer ~]> mysqld-debug --datadir=/data/mysql_data/5.7.11/ &

[1] 1493

[root@MyServer ~]> netstat -tunlp | grep 3306

tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1493/mysqld-debug

--

-- 终端会话1

mysql> create table test_purge(a int auto_increment primary key,b int,unique key(b));

Query OK,0 rows affected (0.20 sec)

mysql> insert into test_purge(b) values (10),(20),(30),(40);

Query OK,4 rows affected (0.05 sec)

mysql> commit; -- autocommit=0 in my.cnf

Query OK,0 rows affected (0.03 sec)

mysql> set global innodb_purge_stop_now=1;

-- show这个变量,结果还是off,这个不用管,purge线程已经停止了

Query OK,0 rows affected (0.00 sec)

mysql> begin;

mysql> delete from test_purge where b=20;

Query OK,1 row affected (0.00 sec)

mysql> commit;

Query OK,0 rows affected (0.02 sec)

-- 终端会话2

mysql> select * from test_purge;

+---+------+

| a | b | -- 20的那条记录已经删除,但是还没有被purge(purge线程停止)

| 1 | 10 |

| 3 | 30 |

| 4 | 40 |

3 rows in set (0.00 sec)

mysql> insert into test_purge(b) values(20);

Query OK,1 row affected (0.04 sec)

-- 终端会话3

mysql> show engine innodb status\G

-- ----------------省略其他输出----------------

---TRANSACTION 9497,ACTIVE 19 sec

3 lock struct(s),heap size 1160,3 row lock(s),undo log entries 1

MySQL thread id 3,OS thread handle 139922002294528,query id 26 localhost root cleaning up

TABLE LOCK table `burn_test`.`test_purge` trx id 9497 lock mode IX

RECORD LOCKS space id 47 page no 4 n bits 72 index b of table `burn_test`.`test_purge` trx id 9497 lock mode S -- S lock (with gap)

Record lock,heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32

-- heap no=3表示是第二个插入的记录20

-- 且info bits为32,表示记录被标记删除了

0: len 4; hex 80000014; asc ;; -- 记录为20

1: len 4; hex 80000002; asc ;; -- 对应的主键为2

Record lock,heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0

-- heap no=4表示的是20的下一个记录30

-- 且该记录上也有S lock

0: len 4; hex 8000001e; asc ;;

1: len 4; hex 80000003; asc ;;

RECORD LOCKS space id 47 page no 4 n bits 72 index b of table `burn_test`.`test_purge` trx id 9497 lock mode S locks gap before rec

Record lock,heap no 6 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 -- heap no=6为新插入的记录20,从隐式锁提升为显示锁

0: len 4; hex 80000014; asc ;;

1: len 4; hex 80000005; asc ;;

1. 因为是唯一索引,需要做唯一性检查,从老的记录 20* 开始检查(第一个小于等于自己的值),则此时 20* 上要加上一把 S lock ,然后往下检查到第一个不相等的记录,即 记录30 ,然后退出,但是这个 记录30 也要 加上S lock

2. 在插入 新的记录20 的时候,发现下一条记录30上有锁,则自己插入的时的 隐式锁 提升为 显示锁 (见插入步骤)

3. 目前锁住的范围是 (10,20],(20,30]

4. 新插入的记录20本身是一把 S-Gap Lock (前面20*的有S lock了,由于是唯一索引,本身其实就不需要有记录锁了,有GAP就够了)

所以记录25无法插入(锁等待)

mysql> insert into test_purge(b) values(25);

ERROR 1205 (HY000): Unknown error 1205 -- 等待了一段时间后,超时

---TRANSACTION 9508,ACTIVE 3 sec inserting

mysql tables in use 1,locked 1

LOCK WAIT 2 lock struct(s),1 row lock(s),undo log entries 1

MySQL thread id 5,OS thread handle 139922002560768,query id 46 localhost root update

insert into test_purge(b) values(25) -- 插入的25在等待

------- TRX HAS BEEN WAITING 3 SEC FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 47 page no 4 n bits 72 index b of table `burn_test`.`test_purge` trx id 9508 lock_mode X locks gap before rec insert intention waiting

------------------

TABLE LOCK table `burn_test`.`test_purge` trx id 9508 lock mode IX

---TRANSACTION 9503,ACTIVE 10 sec

MySQL thread id 7,OS thread handle 139922002028288,query id 44 localhost root cleaning up

TABLE LOCK table `burn_test`.`test_purge` trx id 9503 lock mode IX

RECORD LOCKS space id 47 page no 4 n bits 72 index b of table `burn_test`.`test_purge` trx id 9503 lock mode S

1: len 4; hex 80000002; asc ;;

RECORD LOCKS space id 47 page no 4 n bits 72 index b of table `burn_test`.`test_purge` trx id 9503 lock mode S locks gap before rec

Record lock,heap no 6 PHYSICAL RECORD: n_fields 2; compact format; info bits 0

1: len 4; hex 80000007; asc ;;

这个例子中出现了 锁等待 ,就要 警惕 了,如果有 两个事物相互等待 ,就是 死锁 了

总结

以上所述是小编给大家介绍的MySQL数据库之Purge死锁问题解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

mysql purge进程_MySQL数据库之Purge死锁问题解析相关推荐

  1. mysql密码安全级别_Mysql数据库的安全性问题释疑

    数据库系统的安全性包括很多方面.由于很多情况下,数据库服务器容许客户机从网络上连接,因此客户机连接的安全对MySQL数据库安全有很重要的影响. 不在客户机的命令行上提供密码 使用mysql.mysql ...

  2. mysql case默认_MySQL数据库架构和同步复制流程

    在分布式系统里面,往往制约整个系统发展的瓶颈点就是数据库,所以数据库的架构和高可用以及数据库的切分都是我们值得花大力气去学习的. 首先我们来说说数据库的架构. 1.mysql主从架构,如图: 这种架构 ...

  3. mysql安全模式登录_MySQL数据库安全模式登陆

    当使用mysql数据库提示密码错误或无权限等问题时,可以通过mysql的安全模式启动数据库,使所有用户可以完全访问所有的表,可以对 当使用mysql数据库提示密码错误或无权限等问题时,,可以通过mys ...

  4. mysql删除原则_MySQL数据库的增删选查

    数据库是专门存储数据对象的容器,这里的数据对象包括表.视图.触发器.存储过程等,其中表是最基本的数据对象. 创建数据库 在 MySQL 数据库中存储数据对象之前,先要创建好数据库. 语法: creat ...

  5. mysql select表达式_MySQL数据库SELECT查询表达式解析

    数据的管理在很大一部分是在进行查找工作,而SELECT占据了很大的一部分 SELECT select_expr [,select_expr...] [ FROM table_reference WHE ...

  6. mysql断网_mysql数据库断网链接

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  7. centos72安装mysql配置密码_MySQL数据库之170419、Centos7下完美安装并配置mysql5.6

    本文主要向大家介绍了MySQL数据库之170419.Centos7下完美安装并配置mysql5.6 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. linxu环境: centos ...

  8. mysql 关闭锁_mysql数据库取消锁

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  9. mysql权限表_MySQL 数据库赋予用户权限操作表

    MySQL清空数据库的操作:truncate table tablename; MySQL 赋予用户权限命令的简单格式可概括为:grant 权限 on 数据库对象 to 用户 一.grant 普通数据 ...

  10. mysql客户端查询_MySQL数据库之利用mysql客户端查询UCSC数据库

    本文主要向大家介绍了MySQL数据库之利用mysql客户端查询UCSC数据库 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. UCSC Genome Browser是由Unive ...

最新文章

  1. Linux Shell ssh登录脚本
  2. Asp.Net页面输出到EXCEL
  3. 仿麦包包首页table轮换图jQuery(转自www.jqueryba.com)
  4. 如何检测Safari,Chrome,IE,Firefox和Opera浏览器?
  5. Calendar.clear(int field)的陷阱
  6. GEEK学习笔记— —程序猿面试宝典笔记(二)
  7. Shell sed命令,替换文件内容、替换目录下所有文件内容、读取文件内容
  8. ubuntu vim配置所有用户生效
  9. Scorm标准学习——Scorm RTE API与数据模型
  10. 超频,如何超频CPU和显卡?
  11. mugen4g补丁如何使用_《守望先锋联赛》宣布采用英雄池机制及游戏补丁更新方式详解...
  12. 计算机应用键盘的组成指导书,《计算机应用基础》实验指导书.doc
  13. SpringBoot启动流程原理+自动装配原理
  14. 电容屏通用测试软件,测试屏幕触控的软件 屏幕触控检测软件
  15. Django之wagtail安装及配置
  16. 英语魔法师之语法俱乐部阅读笔记
  17. 网站虚拟服务器共享ip与独立ip,误区解读:独立IP与共享IP虚拟主机哪个更好?...
  18. Salesforce的V2MOM工作法:明确企业在做什么
  19. 天猫爬虫--爬取天猫评论中的图片
  20. 修改andriod模拟器的IMEI,IMSI,手机号,SIM卡号

热门文章

  1. J2EE基础之EJB
  2. Linux内核分析——第四周学习笔记
  3. android studio 新建的项目无法绘制界面
  4. HDU 4540 威威猫系列故事——打地鼠(DP)
  5. 格式转换------用C#代码生成一个简单的PDF文件
  6. 字节码指令之异常处理指令
  7. FunctionalInterface注解
  8. linux版wps无法输入中文的解决办法
  9. Linux开发环境的搭建和使用——Linux本必备软件SSH
  10. 输出svn版本号到头文件