Mysql数据库锁住问题排查

By | 2023年6月13日

1 检查当前进程

     show processlist;

这条命令会列出当前数据库正在执行的进程,如果有卡住的,删掉即可。

kill id;

2 检查事物

如果进程没有卡住而仍然无法执行表结构修改等操作,则进行事物排查

select * from information_schema.innodb_trx\G;

结果形式如下:

*************************** 1. row ***************************
                    trx_id: 27159530
                 trx_state: RUNNING
               trx_started: 2017-11-13 14:29:34
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 0
       trx_mysql_thread_id: 9561
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 0
          trx_lock_structs: 0
     trx_lock_memory_bytes: 360
           trx_rows_locked: 0
         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
1 row in set (0.00 sec)

这种结果表示有事物未执行完,删掉该事物对应的线程。

-- kill trx_mysql_thread_id;

kill 9561;

3 其他有用命令

-- 查看那些表锁到了
show OPEN TABLES where In_use > 0;

3.1

查看未关闭的事物

SELECT
     a.trx_id,
     a.trx_state,
     a.trx_started,
     a.trx_query,
     b.ID,
     b.USER,
     b.DB,
     b.COMMAND,
     b.TIME,
     b.STATE,
     b.INFO,
     c.PROCESSLIST_USER,
     c.PROCESSLIST_HOST,
     c.PROCESSLIST_DB,
     d.SQL_TEXT
FROM
     information_schema.INNODB_TRX a
LEFT JOIN information_schema.PROCESSLIST b ON a.trx_mysql_thread_id = b.id
AND b.COMMAND = 'Sleep'
LEFT JOIN PERFORMANCE_SCHEMA.threads c ON b.id = c.PROCESSLIST_ID
LEFT JOIN PERFORMANCE_SCHEMA.events_statements_current d ON d.THREAD_ID = c.THREAD_ID;

3.2 查看正在执行的事物

通过thread_id可以对应找到sql语句

select* from performance_schema.events_statements_current\G

3.3 查看已经死掉未提交到进程

通过show processlist看不到TableA上有任何操作,在information_schema.innodb_trx中也没有任何进行中的事务。这很可能是因为在一个显式的事务中,对TableA进行了一个失败的操作(比如查询了一个不存在的字段),这时事务没有开始,但是失败语句获取到的锁依然有效,没有释放。从performance_schema.events_statements_current表中可以查到失败的语句。

可以通过下面的方式进行释放

select processlist_id from performance_schema.threads where thread_id in (select thread_id from performance_schema.events_statements_current where current_schema='pdla' and ( mysql_errno>0 or lock_time>0 )) ;

通过上面的语句能够查询出来pdla数据库中失败的和锁定的进程

然后通过kill命令杀掉即可。