kill process解决kundb死锁问题

  SQL报错
内容纲要

概要描述


KunDB 中,当两个或多个事务永久阻塞并等待对方释放锁时,会发生死锁。此时可以选择终止其中一个事务来解除死锁。

本文介绍一种根据表名查找事务,并通过 kill process 解决死锁问题的一种方法

详细介绍


1、构造场景

创建一张有主键的表

CREATE TABLE testdum (
  id int NOT NULL,
  name varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;
session1 session2
1 begin;
2 insert into testdum (id ,name ) values (1,’aaaaaa’) on duplicate key update id=values(id),name=values(name);
3 begin
4 insert into testdum (id ,name ) values (1,’bbbbb’) on duplicate key update id=values(id),name=values(name);

此时,session2中的这条insert执行卡住,等待一个innodb_lock_wait_timeout时长之后会报错:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction (errno 1205) (sqlstate HY000) during query: insert into testdum (id ,name ) values (1,’bbbbb’) on duplicate key update id=values(id),name=values(name)

2、解决方案

最简便的解决方案(推荐):

select * from sys.innodb_lock_waits where locked_table_schema='db1' and locked_table_name='testdum';

file

直接拷贝 sql_kill_blocking_connection 的内容进行 kill即可。

注意! 高可用kundb可以在外层直接kill; 分布式kundb需连接到底层shard master 执行kill (先执行前面的select查询,确认在该shard 才需要执行。)


或者可以考虑 参考如下sql语句,获取thread_id

注意,可以根据a.OBJECT_SCHEMA = 'db1' and a.OBJECT_NAME = 'testdum'过滤表名

SELECT
    NOW( 6 ) curr_dt,
    a.thread_id,
    b.PROCESSLIST_ID PROCESSLIST_ID,
    ENGINE_TRANSACTION_ID trx_id,
    object_name,
    INDEX_NAME,
    lock_type,
    lock_mode,
    lock_status,
    LOCK_DATA,
    c.BLOCKING_ENGINE_TRANSACTION_ID blk_trx_id,
    c.BLOCKING_THREAD_ID blk_thd_id 
FROM
    PERFORMANCE_SCHEMA.data_locks a
    LEFT JOIN PERFORMANCE_SCHEMA.threads b ON a.thread_id = b.thread_id
    LEFT JOIN PERFORMANCE_SCHEMA.data_lock_waits c ON a.ENGINE_TRANSACTION_ID = c.REQUESTING_ENGINE_TRANSACTION_ID 
    AND a.thread_id = c.REQUESTING_THREAD_ID 
WHERE
    a.thread_id = b.thread_id 
    AND a.OBJECT_SCHEMA = 'db1'
    AND a.OBJECT_NAME = 'testdum' 
ORDER BY
    thread_id,
    trx_id;

file

可以看到WAITING状态的这条sql,被BLOCKING_THREAD_ID为2704的线程阻塞,而2704的PROCESSLIST_ID为2646,

此时,可以执行kill命令终止该进程。

kill 2646;

此时session1已处于杀死状态,无法再执行sql,再执行会报错 :
ERROR 2013 (HY000): EOF (errno 2013) (sqlstate HY000) during query: show tables kunErr(kungate: http://XXX:25001/)

session2再次执行可以运行成功。

FAQ

sys.innodb_lock_waits 视图的列及其含义如下:

sys.innodb_lock_waits:在MySQL 5.7中,这个视图简化了information_schema.innodb_lock_waits的使用,通过连接其他几个表来提供更直观的锁等待信息。在MySQL 8.0中,它进一步简化了视图定义,并且使用了performance_schema中的表来提供更详细的锁等待信息。

wait_started: 锁等待开始的时间。
wait_age: 锁等待的持续时间(以秒为单位)。
object_schema: 涉及的数据库名。
object_name: 涉及的表名。
index_name: 涉及的索引名。
lock_type: 锁类型(如 RECORD、TABLE 等)。
lock_mode: 锁模式(如 S、X、IS、IX 等)。
lock_status: 锁状态(如 GRANTED、WAITING)。
waiting_trx_id: 请求锁的事务 ID。
waiting_query: 请求锁的 SQL 查询。
waiting_pid: 请求锁的进程 ID。
waiting_lock_id: 请求的锁 ID。
waiting_lock_type: 请求的锁类型。
waiting_lock_mode: 请求的锁模式。
blocking_trx_id: 持有锁的事务 ID。
blocking_query: 持有锁的 SQL 查询。
blocking_pid: 持有锁的进程 ID。
blocking_lock_id: 被请求的锁 ID。
blocking_lock_type: 持有的锁类型。
blocking_lock_mode: 持有的锁模式。
sql_kill_blocking_query: 可以用来终止持有锁的查询的 SQL 命令。
sql_kill_blocking_connection: 可以用来终止持有锁的连接的 SQL 命令。

这篇文章对您有帮助吗?

平均评分 0 / 5. 次数: 0

尚无评价,您可以第一个评哦!

非常抱歉,这篇文章对您没有帮助.

烦请您告诉我们您的建议与意见,以便我们改进,谢谢您。