1.如何知道系统有没有发生过死锁,如何去查看发生过的锁
show status like ‘innodb_row_lock%'; 从系统启动到现在的数据
Innodb_row_lock_current_waits:当前正在等待锁的数量;
Innodb_row_lock_time :锁定的总时间长度,单位ms;
Innodb_row_lock_time_avg :每次等待所花平均时间;
Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花的时间;
Innodb_row_lock_waits :从系统启动到现在总共等待的次数。
平均时间和锁等待次数比较大的话,说明可能会存在锁争用情况
2. show engine innodb status
展示innodb存储引擎的运行状态
通过这个命令显示的内容比较多,其中有一项lasted detected deadlock 显示最近发生的死锁。
图中红色线条标注的是执行的SQL,以及加了什么锁,可以看出是在这行记录上加了X锁,没有gap锁。
3. 错误日志中查看历史发生过的死锁
set global innodb_print_all_deadlocks=1;
上一个命令,只能看到最近发生的锁,如果我想看历史发生的锁怎么办? 执行这一句,更改innodb 的一个配置,innodb_print_all_deadlocks,打印所有的死锁。会将死锁的信息输出到mysql的错误日志中,默认是不输出,格式和show engine innodb status 是差不多的。
4. information_schema.innodb_locks
information_schema 数据库是mysql自带的,保存着关于MySQL服务器所维护的所有其他数据库的信息。其中innodb_locks表,记录了事务请求但是还没获得的锁,即等待获得的锁。
lock_id:锁的id,由锁住的空间id编号、页编号、行编号组成
lock_trx_id:锁的事务id。
lock_mode:锁的模式。S[,GAP], X[,GAP], IS[,GAP], IX[,GAP]
lock_type:锁的类型,表锁还是行锁
lock_table:要加锁的表。
lock_index:锁住的索引。
lock_space:innodb存储引擎表空间的id号码
lock_page:被锁住的页的数量,如果是表锁,则为null值。
lock_rec:被锁住的行的数量,如果表锁,则为null值。
lock_data:被锁住的行的主键值,如果表锁,则为null值。
5. information_schema.innodb_lock_waits
查看等待中的锁
requesting_trx_id:申请锁资源的事务id。
requested_lock_id:申请的锁的id。
blocking_trx_id:阻塞的事务id,当前拥有锁的事务ID。
blocking_lock_id:阻塞的锁的id,当前拥有锁的锁ID
6. information_schema.innodb_trx
查看已开启的事务
trx_id:innodb存储引擎内部事务唯一的事务id。
trx_state:当前事务的状态。
trx_started:事务开始的时间。
trx_requested_lock_id:等待事务的锁id,如trx_state的状态为LOCK WAIT,那么该值代表当前事务之前占用锁资源的id,如果trx_state不是LOCK WAIT的话,这个值为null。
trx_wait_started:事务等待开始的时间。
trx_weight:事务的权重,反映了一个事务修改和锁住的行数。在innodb的存储引擎中,当发生死锁需要回滚时,innodb存储引擎会选择该值最小的事务进行回滚。
trx_mysql_thread_id:正在运行的mysql中的线程id,show full processlist显示的记录中的thread_id。
trx_query:事务运行的sql语句
写在最后:
出现死锁问题时,可以查看系统设置的隔离级别,RR与RC在加锁粒度上存在很大区别,RR隔离级别因为加锁粒度更大,在并发更新表的场景下容易产生思索,通常是因为UPDATE语句的where条件所带的字段是普通索引,通常变更成唯一索引可以解决死锁问题。也可以评估业务系统是否兼容RC隔离级别,直接切换隔离级别。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。