前言
前段时间遇到了一个 Mysql 死锁相干的问题,整顿一下。
问题形容:Mysql 的批改语句仿佛都没有失效,同时应用 Mysql GUI 工具编辑字段的值时会弹出异样。
什么是死锁
在解决 Mysql 死锁的问题之前,还是先来理解一下什么是死锁。
死锁是指两个或两个以上的过程在执行过程中, 因抢夺资源而造成的一种相互期待的景象, 若无外力作用, 它们都将无奈推动上来. 此时称零碎处于死锁状态或零碎产生了死锁, 这些永远在相互等的过程称为死锁过程。
死锁的体现
死锁的具体表现有两种:
- Mysql 增改语句无奈失常失效
- 应用 Mysql GUI 工具编辑字段的值时,会出现异常。
如何防止死锁
阻止死锁的路径就是防止满足死锁条件的状况产生,为此咱们在开发的过程中须要遵循如下准则:
1. 尽量避免并发的执行波及到批改数据的语句。
2. 要求每一个事务一次就将所有要应用到的数据全副加锁,否则就不容许执行。
3. 预先规定一个加锁程序,所有的事务都必须依照这个程序对数据执行封闭。如不同的过程在事务外部对对象的更新执行程序应尽量保障统一。
查看死锁
Mysql 查问是否存在锁表有多种形式,这里只介绍一种最罕用的。
1. 查看正在进行中的事务
SELECT * FROM information_schema.INNODB_TRX
能够看到 过程 id 为 3175 的事务在锁住了,而另一个 id 为 3173 的事务正在执行,然而没有提交事务。
2. 查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
3. 查看期待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
4. 查问是否锁表
SHOW OPEN TABLES where In_use > 0;
在产生死锁时,这几种形式都能够查问到和以后死锁相干的信息。
5. 查看最近死锁的日志
show engine innodb status
解除死锁
如果须要解除死锁,有一种最简略粗犷的形式,那就是找到过程 id 之后,间接干掉。
查看以后正在进行中的过程
show processlist
// 也能够应用
SELECT * FROM information_schema.INNODB_TRX;
这两个命令找进去的过程 id 是同一个。
杀掉过程对应的过程 id
kill id
验证(kill 后再看是否还有锁)
SHOW OPEN TABLES where In_use > 0;
参考链接
- Mysql 查看表和解锁表
- Mysql 死锁是什么?