加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

两个小器材,MySQL死锁说明,新手艺又Get!

发布时间:2019-07-11 21:59:09 所属栏目:编程 来源:58沈剑
导读:数据库死锁,是最难调试与追踪的。 场景如下: 统一个表,事宜内先插入一笔记录,再更新这笔记录,并发时会死锁。 而且可以或许复现。 可以通过什么器材模仿并发事宜,查察信息,办理题目呢?这是本日要分享的内容。 一、前置筹备 setsessiontransactionisolati

第二部门,要害词是:

  • Transaction 2,事宜3999;
  • 正在执行
    1. update t set cell=456 where cell=55555555555; 
  • 持有锁(holds the lock),记录锁(record locks),主键索引上(index primary),互斥锁(lock_mode X),物理记录(physical record),asc 55555555555;
  • 正在守候锁开释(waiting for this lock to be granted),记录锁(record locks),主键索引上(index primary),互斥锁(lock_mode X),物理记录(physical record),asc 11111111111;
  • 事宜2回滚(we roll back transaction 2);

通过show engine innodb status; 可以或许看到许多事宜与锁之间的信息,对说明题目异常有辅佐,这些信息,可以或许表明一些题目,但仍有两个迷惑:

(1)事宜1为啥想拿55555555555的锁?

画外音:这正是,事宜1被阻塞的缘故起因。

(2)事宜2为啥想拿11111111111的锁?死锁的产生,声名事宜1此时真占着11111111111的锁,这又是为什么呢?

画外音:第一个事宜占111抢555,第二个事宜占555抢111,轮回嵌套,才会死锁。

器材二:

  1. explain 

为了进一步探求缘故起因,可以通过explain看下导致死锁语句的执行打算。

  1. explain update t set cell=456 where cell=55555555555; 

两个小器材,MySQL死锁说明,新手艺又Get!

(1) select_type:SIMPLE

这是一个简朴范例的SQL语句,不含子查询可能UNION。

(2) type:index

会见范例,即找到所需数据行使的遍历方法,隐藏的方法有:

  • ALL(Full Table Scan):全表扫描;
  • index:走索引的全表扫描;
  • range:掷中where子句的范畴索引扫描;
  • ref/eq_ref:非独一索引/独一索引单值扫描;
  • const/system:常量扫描;
  • NULL:不消会见表;

上述扫描方法,ALL最慢,慢慢变快,NULL最快。

猜疑点1:显着cell字段有uniq索引,为何要举办走PK索引的全表扫描呢?

(3) possible_keys:NULL

也许在哪个索引找到记录。

(4) key:PRIMARY

现实行使索引。

画外音:行使PK举办的全表扫描。

(5) ref:NULL

哪些列,可能常量用于查找索引上的值。

猜疑点2:where前提中的查询前提55555555555,原来应该作为在索引上被检索的值呀?

(6) rows:5

找到所需记录,预估必要读取的行数。

猜疑点3:显着修改的是5,为何初始化的1,2,3,以及第一个事宜插入的4,以及第二个事宜插入的5,都要被读取呢?不该该全表扫描呀。

通过explain,根基已经可以判定:

  1. update t set cell=456 where cell=55555555555; 

并没有和我们预想一样,走cell索引举办查询,而是走了PK索引举办了全表扫描。

再细心一看:

  1. create table t ( 
  2. id int(20) primary key AUTO_INCREMENT, 
  3. cell varchar(20) unique 
  4. )engine=innodb; 

建表的时辰cell界说的是字符串范例。

而更新的时辰,

  1. update t set cell=456 where cell=55555555555; 

行使的是整数范例。

范例转换,会导致全表扫描,呈现锁进级,锁住所有记录。

加上引号,再次通过explain验证一下:

  1. explain update t set cell= '456 ' where cell= '55555555555 '; 

两个小器材,MySQL死锁说明,新手艺又Get!

公然印证了意料:

  • type:range,变为了走索引的字符串比对,范畴扫描;
  • possible_keys:cell,通过cell索引找到了记录;
  • key:cell,现实行使cell索引;
  • ref:const,行使了常量' 555'举办比对;
  • rows:1,预估读取行数是1;

这下所有可以表明白。

两个小器材,MySQL死锁说明,新手艺又Get!

总结

就本例而言:必要留意字符串与整数之间的逼迫范例转换,偶然辰少一个引号,就会使得行锁进级为表锁。

死锁是MySQL中很是难调试的题目,常见的思绪与要领有:

  • 通过多终端模仿并发事宜,复现死锁;
  • 通过show engine innodb status; 可以查察事宜与锁的信息;
  • 通过explain可以查察执行打算;

思绪比结论更重要,但愿各人有收成。

【本文为51CTO专栏作者“58沈剑”原创稿件,转载请接洽原作者】

两个小器材,MySQL死锁说明,新手艺又Get!

戳这里,看该作者更多好文

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读