MySQL|MySQL数据库事务锁等待(Lock wait timeout exceeded; try restarting transaction)

当在操作mysql数据库的表数据时,发现更新某表的xx字段时,系统老是提示“Lock wait timeout exceeded; try restarting transaction”错误。一般情况下,出现这个情况的原因可能是当一个sql执行完之后,但是该事务处于未commit的状态,后面的sql语句如果也对该字段进行操作,就会出现锁等待的情况,操作超时结束。这个时候我们就需要对数据库的进程进行排查,发现导致锁等待的进程,将其kill。

【MySQL|MySQL数据库事务锁等待(Lock wait timeout exceeded; try restarting transaction)】查看数据库的进程“show full processlist; ”的方法有两种:
1、借助sql可视化工具,如Navicat For MySQL和SQLyog等。
在Navicat For MySQL可以选择“工具”中的“服务器监控”查看所有进程状态;
在SQLyog中可以选择“工具”下的服务器过程列表(不过没有前者详细);
2、通过命令行连接服务器数据库进行操作:
首先连接服务器数据库(可参考MySQL连接远程服务器上的数据库),输入命令”show full processlist; ”查看当前服务器下的数据库进程状态:
MySQL|MySQL数据库事务锁等待(Lock wait timeout exceeded; try restarting transaction)
文章图片

查看显示的进程列表,看是否能够找到正在执行的导致锁等待的进程,如果发现kill掉,就会解决该问题。如果没有发现慢进程的记录,所有进程都是“sleep”状态,就再去查看下innodb的事务表
INNODB_TRX,查看是否有正在锁定的线程事务,看里面的ID是否存在show full processlist里面的sleep线程中,如果是,就证明这个sleep的线程事务一直没有commit或者rollback而是卡住了,我们需要手动kill掉。
执行“SELECT * FROM information_schema.INNODB_TRX\G; ”命令:
mysql> SELECT * FROM information_schema.INNODB_TRX\G;
***************** 1. row *****************
trx_id: 20866 /请记住该trx_id/
trx_state: LOCK WAIT /当前状态-状态为锁等待 “trx_state: RUNNING ”/
trx_started: 2014-07-31 10:42:35
trx_requested_lock_id: 20866:617:3:3
trx_wait_started: 2014-07-30 10:42:35
trx_weight: 2
trx_mysql_thread_id: 11120 /在process 里面的id值/
trx_query: delete from test where id=111 //锁等待的语句//
trx_operation_state: starting index read
trx_tables_in_use: 1
trx_tables_locked: 1
trx_lock_structs: 2
trx_lock_memory_bytes: 376
trx_rows_locked: 1
trx_rows_modified: 0
trx_concurrency_tickets: 0
trx_isolation_level: READ COMMITTED
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_adaptive_hash_latched: 0
trx_adaptive_hash_timeout: 10000
trx_is_read_only: 0
trx_autocommit_non_locking: 0
发现导致锁等待的进程,执行”kill 11120”将该进程的ID kill掉,
再重新查询INNODB_TRX表的时候就会出现下面的结果(阻塞的事务Sleep进程就不存在了):
MySQL|MySQL数据库事务锁等待(Lock wait timeout exceeded; try restarting transaction)
文章图片

(注意:MySQL中,在information_schema下面有三张表:INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS,通过这三张表,可以更简单地监控当前的事务并分析可能存在的问题。
比较常用的列:
  • trx_id:InnoDB存储引擎内部唯一的事物ID
  • trx_status:当前事务的状态
  • trx_started:事务的开始时间
  • trx_requested_lock_id:等待事务的锁ID
  • trx_wait_started:事务等待的开始时间
  • trx_weight:事务的权重,反应一个事务修改和锁定的行数,当发现死锁需要回滚时,权重越小的值被回滚
  • trx_mysql_thread_id:MySQL中的进程ID,与show processlist中的ID值相对应
  • trx_query:事务运行的SQL语句
最后,回头对要操作的字段进行处理,就不会出现锁等待的问题了。

    推荐阅读