mysql 死锁和死锁检测
1、死锁的定义
当mysql请求发生并发时,不同线程执行的事务操作需要获取相同资源的锁,涉及的线程都在等待别的线程释放锁,几个线程都进入无限等待的状态时,就出现死锁了。
2、锁等待的最大时长
当出现死锁时,事务会一直等待,直到时间达到innodb_lock_wait_timeout设置的值,默认值是50秒。
3、死锁检测
可以设置innodb_deadlock_detect=on 来开启死锁检测。死锁检测在发生死锁的时候,能够快速发现并进行处理,回滚并重新启动。但是死锁检测会比较好资源。当每个新来的被堵住的线程,都要判断会不会由于自己的加入导致了死锁,这是一个时间复杂度是 O(n) 的操作。假设有 1000 个并发线程要同时更新同一行,那么死锁检测操作可能就是 100 万的量级。虽然最终检测的结果可能没有死锁,但是这期间要消耗大量的 CPU 资源。
4、innodb死锁的监控和查看
innodb引擎,可以通过show engine innodb status 命令查看最近产生死锁的情况。
另一种方式是通过InnoDB monitor查看。InnoDB monitor可以记录innodb内部的很多统计信息。InnoDB monitor一共有四种模式。其中innodb_monitor/innodb_lock_monitor两种监视器的输出结果基本类似,后者会有更多关于锁的信息;innodb_table_monitor则会将系统中所有innodb的表的一些结构和内部信息输出,而innodb_tablespace_monitor则输出的是tablespace的信息,注意该monitor输出的只是共享表空间的信息,如果使用innodb_file_per_table为每个表使用独立的表空间,则这些表空间的信息是不会包含在输出中的。
其实,show engine innodb status是其中innodb_monitor模式的直接展现,并且只能交互式开启,无法自动循环捕获信息。
四种模式的开启方式,是通过创建一张特殊的innodb表来开启,开启后会按照固定的时间(20s)间隔循环,输出信息到log-error参数指定的错误日志文件中。
四种monitor开启的方式分别是:
create table innodb_monitor(x int) engine=innodb;
create table innodb_lock_monitor(x int) engine=innodb;
create table innodb_table_monitor(x int) engine=innodb;
create table innodb_tablespace_monitor(x int) engine=innodb;
<、pre>
通过drop对应的表,可以停止monitor。开启monitor后因为是持续周期性的运行的,在不需要的时候一定要记得drop相关表来停止monitor。如果在开启monitor的中间服务器有重启,monitor不会自动重启,并且在下次启动monitor之前,必须先执行停止操作。MySQL5.6.16后推荐使用如下方法开启:
set GLOBAL innodb_status_output=ON;
set GLOBAL innodb_status_output_locks=ON;
<、pre>