网站建设 300元,网页制作设计作品,武强营销型网站建设费用,微信优惠群怎么做网站死锁#xff08;Deadlock#xff09; 什么是死锁 所谓死锁#xff1a;是指两个或两个以上的进程在执行过程中#xff0c;因争夺资源而造成的一种互相等待的现象#xff0c;若无外力作用#xff0c;它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁#xf… 死锁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_idinnodb存储引擎内部事务唯一的事务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中的线程idshow 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 bt2 where a1的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_spaceinnodb存储引擎表空间的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