死锁(Deadlock)


什么是死锁

所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

死锁的影响

当产生某表死锁的一开始,所有涉及这张表的操作都将受到阻塞。假设这张表在业务逻辑上是读写频繁的,那就会使很多操作在那里排队等待,而排队等待会占用数据库连接,当该达到该数据库连接数的最大承载数之后,就会使所有数据库操作均无法再继续下去,致使数据库各项指标异常,导致整个环境崩溃。在生产环境中出现这种问题,那是相当致命的,当发现数据库指标异常时因快速处理!

如何发现死锁

1.查询数据库进程

主要看State字段,如果出现大量 waiting for ..lock 即可判定死锁:

SHOW FULL PROCESSLIST;

注意:需要拥有root组权限(supper),否则只能看到当前用户的进程,无法查询所有

2.查看当前的事务

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

INNODB_TRX 表包含信息关于每个事务(排除只读事务)当前执行的在InnoDB,包含是否事务是等待一个锁, 当事务启动后, SQL语句事务是正在执行

INNODB_TRX Columns 相关列信息:

a) trx_id:innodb存储引擎内部事务唯一的事务id。

b) trx_state:当前事务的状态。

c) trx_started:事务开始的时间。

d) trx_requested_lock_id:等待事务的锁id,如trx_state的状态为LOCK WAIT,那么该值代表当前事务之前占用锁资源的id,如果trx_state不是LOCK WAIT的话,这个值为null。

e) trx_wait_started:事务等待开始的时间。

f) trx_weight:事务的权重,反映了一个事务修改和锁住的行数。在innodb的存储引擎中,当发生死锁需要回滚时,innodb存储引擎会选择该值最小的事务进行回滚。

g) trx_mysql_thread_id:正在运行的mysql中的线程id,show full processlist显示的记录中的thread_id。

h) trx_query:事务运行的sql语句,在实际中发现,有时会显示为null值,当为null的时候,就是t2事务中等待锁超时直接报错(ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction)后,trx_query就显示为null值

比如事务t2正在运行trx_query: update test.t1 set b='t2' where a=1的sql语句,t1先执行,所以是trx_state: RUNNING先申请的资源一直在运行,而t2后run的所以是trx_state: LOCK WAIT一直在等待t1执行完后释放资源。 但是并不能仔细判断锁的一些详细情况,我们需要再去看当前锁定的事务表数据。

3.查看当前锁定的事务

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

INNODB_LOCKS 表包含信息关于每个锁一个InnoDB 事务已经请求,但是没有获得锁,每个lock一个事务持有是堵塞另外一个事务

INNODB_LOCKS Columns 相关列信息:

a) lock_id:锁的id以及被锁住的空间id编号、页数量、行数量

b) lock_trx_id:锁的事务id。

c) lock_mode:锁的模式。

d) lock_type:锁的类型,表锁还是行锁

e) lock_table:要加锁的表。

f) lock_index:锁的索引。

g) lock_space:innodb存储引擎表空间的id号码

h) lock_page:被锁住的页的数量,如果是表锁,则为null值。

i) lock_rec:被锁住的行的数量,如果表锁,则为null值。

j) lock_data:被锁住的行的主键值,如果表锁,则为null值。

如以下查询 :

mysql> select * from INNODB_LOCKSG

1. row **

lock_id: 3015646:797:3:2

lock_trx_id: 3015646

lock_mode: X

lock_type: RECORD

lock_table: test.t1

lock_index: PRIMARY

lock_space: 797

lock_page: 3

lock_rec: 2

lock_data: 1

2. row **

lock_id: 3015645:797:3:2

lock_trx_id: 3015645

lock_mode: X

lock_type: RECORD

lock_table: test.t1

lock_index: PRIMARY

lock_space: 797

lock_page: 3

lock_rec: 2

lock_data: 1

2 rows in set (0.00 sec)

这里我们可以看到当前的锁信息了,2个事务都锁定了,看相同的数据lock_space: 797、lock_page: 3、lock_rec: 2可以得出事务t1和事务t2访问了相同的innodb数据块,再通过lock_data字段信息lock_data: 1,看到锁定的数据行都是主键为1的数据记录,可见2个事务t1和t2都申请了相同的资源,因此会被锁住,事务在等待。

通过lock_mode: X值也可以看出事务t1和t2申请的都是排它锁。

PS:当执行范围查询更新的时候,这个lock_data的值并非是完全准确。当我们运行一个范围更新时,lock_data只返回最先找到的第一行的主键值id;另外如果当前资源被锁住了,与此同时由于锁住的页因为InnoDB存储引擎缓冲池的容量,而导致替换缓冲池页面,再去查看INNODB_LOCKS表时,这个lock_data会显示未NULL值,意味着InnoDB存储引擎不会从磁盘进行再一次查找。

4.查看当前等锁的事务

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

INNODB_LOCK_WAITS 表包含了blocked的事务的锁等待的状态。当事务量比较少,我们可以直观的查看,当事务量非常大,锁等待也时常发生的情况下,这个时候可以通过INNODB_LOCK_WAITS表来更加直观的反映出当前的锁等待情况:

INNODB_LOCK_WAITSColumns 相关列信息:

a) requesting_trx_id:申请锁资源的事务id。

b) requested_lock_id:申请的锁的id。

c) blocking_trx_id:阻塞的事务id。

d) blocking_lock_id:阻塞的锁的id。

如以下查询:
mysql> select * from INNODB_LOCK_WAITSG

1. row **

requesting_trx_id: 3015646

requested_lock_id: 3015646:797:3:2

blocking_trx_id: 3015645

blocking_lock_id: 3015645:797:3:2

1 row in set (0.00 sec)

mysql>

这里我们可以看到事务t1(3015646)申请了锁资源,而事务t2(3015645)则阻塞了事务t1的申请。

如何处理死锁

杀死进程

通过以上方法一可以查询对应死锁的数据库进程,可以直接杀掉

kill 进程ID

如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

虽然不能完全避免死锁,但可以使死锁的数量减至最少。将死锁减至最少可以增加事务的吞吐量并减少系统开销,因为只有很少的事务回滚,而回滚会取消事务执行的所有工作。由于死锁时回滚而由应用程序重新提交。

下列方法有助于最大限度地降低死锁:

(1)按同一顺序访问对象。
(2)避免事务中的用户交互。
(3)保持事务简短并在一个批处理中。
(4)使用低隔离级别。
(5)使用绑定连接。

转载于:https://www.cnblogs.com/daijiabao/p/11286864.html

mysql -- 死锁相关推荐

  1. java mysql死锁_记一次线上mysql死锁分析(一)

    记录一次比较诡异的mysql死锁日志.系统运行几个月来,就在前几天发生了一次死锁,而且就只发生了一次死锁,整个排查过程耗时将近一天,最后感谢我们的DBA大神和老大一起分析找到原因. 诊断死锁 借助于我 ...

  2. mysql查询死锁的次数_一次神奇的MySQL死锁排查记录

    一次神奇的MySQL死锁排查记录 发布时间:2020-08-29 00:50:26 来源:脚本之家 阅读:135 作者:咖啡拿铁 背景 说起Mysql死锁,之前写过一次有关Mysql加锁的基本介绍,对 ...

  3. MySQL死锁如何处理

    转载自  MySQL死锁如何处理 前提 笔者负责的一个系统最近有新功能上线后突然在预警模块不定时报出MySQL死锁导致事务回滚.幸亏,上游系统采用了异步推送和同步查询结合的方式,感知到推送失败及时进行 ...

  4. mysql 死锁监视器_并发基础知识:死锁和对象监视器

    mysql 死锁监视器 本文是我们名为Java Concurrency Essentials的学院课程的一部分. 在本课程中,您将深入探讨并发的魔力. 将向您介绍并发和并发代码的基础知识,并学习诸如原 ...

  5. mysql死锁的排查方法_MySQL死锁系列-线上死锁问题排查思路

    前言 MySQL 死锁异常是我们经常会遇到的线上异常类别,一旦线上业务日间复杂,各种业务操作之间往往会产生锁冲突,有些会导致死锁异常.这种死锁异常一般要在特定时间特定数据和特定业务操作才会复现,并且分 ...

  6. go语言 mysql卡死_一次mysql死锁的排查过程-Go语言中文社区

    一次mysql死锁的排查过程一.背景17号晚上要吃饭了,看旁边的妹子和佐哥还在调代码,就问了下什么问题啊,还在弄,妹子说,在测试环境测试给用户并发发送卡券时,出现了死锁,但看代码没有死锁,问题如下图 ...

  7. zabbix监控mysql死锁

    percona MySQL Server Template算是比较常用的zabbix监控mysql的模板了,监控项也比较齐全,但是没有监控mysql死锁的监控项,如果有需求,就需要另外创建模板或者监控 ...

  8. 一次MySQL死锁问题解决

    一次MySQL死锁问题解决 一.环境 CentOS, MySQL 5.6.21-70, JPA 问题场景:系统有定时批量更新数据状态操作,每次更新上千条记录,表中总记录数约为500W左右. 二.错误日 ...

  9. mysql死锁语句_记一次神奇的Mysql死锁排查

    背景 说起Mysql死锁,之前写过一次有关Mysql加锁的基本介绍,对于一些基本的Mysql锁或者死锁都有一个简单的认识,可以看下这篇文章为什么开发人员需要了解数据库锁.有了上面的经验之后,本以为对于 ...

  10. mysql排插问题_手把手教你分析 MySQL 死锁问题

    原标题:手把手教你分析 MySQL 死锁问题 前言 前几天跟一位朋友分析了一个死锁问题,所以有了这篇图文详细的博文,哈哈~ 发生死锁了,如何排查和解决呢?本文将跟你一起探讨这个问题 准备好数据环境 模 ...

最新文章

  1. ios8 Xcode6 设置Launch Image 启动图片
  2. Free Download Manager (FDM) 中文版 - 替代迅雷最佳免费开源下载工具软件
  3. rust和gta5哪个吃配置_选指数基金,像“今晚吃什么”一样容易
  4. 虚拟机当作设置服务器,虚拟机当作设置服务器
  5. java多线程编程一之java线程的原理
  6. echars 在vue v-if 切换会 显示不出来或者显示出来但是不是百分百显示
  7. DOxygen for C++使用说明——注释代码二
  8. linux 执行sh_linux下执行脚本 sh -x XXX.sh 调试中存在大量/r 的问题
  9. Linux工作笔记-使用find和grep检索文件或子文件中是否包含指定字符串
  10. 第十一章 图形视图、动画、状态机框架
  11. Log4--Java日志记录器
  12. C++新特性探究(13.5):右值引用
  13. 已知高维高斯联合概率分布求边缘概率分布以及条件概率分布
  14. 使用51单片机驱动航模无刷电机
  15. css 魔方,css 3d旋转魔方
  16. 数据结构 队列学习总结
  17. 第十届蓝桥杯单片机组(省赛代码)
  18. UE4 C++ 事件
  19. PowerManagerService分析-updatePowerStateLocked方法
  20. screen:There is no screen to be resumed matching XXX 解决办法

热门文章

  1. 华为路由器hilink怎么用_华为无线充电怎么用?MatePadPro无线充电使用方法
  2. python重写和装饰器_python装饰器
  3. Nginx反向代理的使用
  4. LeetCode(#26)————删除排序数组中的重复项
  5. Java 集合Collection常见知识点汇总~
  6. host 端口_如何让多端口网站用一个nginx进行反向代理实际场景分析
  7. java生成大素数_用BigInteger实现大素数生成算法
  8. Linux APT VIM 的一些指令
  9. PHP 继承新增,php类的扩展和继承用法实例
  10. Oracle 数据怎么实时同步到 MySQL | 亲测干货分享建议收藏