Mysql 操作死锁解决方案

起因:用Navicat批量删除表时,卡死;中止后,再次执行删除数据或表仍是卡死;

分析:应该是触发死锁。

使用 show processlist; 发现Waiting for table metadata lock 问题;

mysql> show processlist;

+-------+-----------------+-----------+------+---------+--------+---------------------------------+-----------------------------------------------------------------------+
| ID    | USER            | HOST      | DB   | COMMAND | TIME   | STATE                           | INFO                                                                  |
+-------+-----------------+-----------+------+---------+--------+---------------------------------+-----------------------------------------------------------------------+
|     1 | event_scheduler | localhost | NULL | Daemon  | 365869 | Waiting on empty queue          | NULL                                                                  |
| 13006 | root            | localhost | NULL | Query   |     35 | Waiting for table metadata lock | alter table test.t add column s int                                   |
| 13040 | root            | localhost | NULL | Query   |      0 | executing                       | select * from information_schema.processlist where command != 'sleep' |
| 13044 | root            | localhost | NULL | Query   |      4 | Waiting for table metadata lock | update test.t set b = 10 where a = 3                                  |
| 13043 | root            | localhost | NULL | Query   |     21 | Waiting for table metadata lock | select * from test.t                                                  |
+-------+-----------------+-----------+------+---------+--------+---------------------------------+-----------------------------------------------------------------------+

尝试1:kill mysql 进程,重新执行删除表等DDL操作仍出现死锁,报Waiting for table metadata lock;

mysql> kill 13006;

尝试2:重启Mysql服务,仍会死锁;

尝试3: 设置kill_idle_transation ,失败;

mysql>  set global kill_idle_transaction=5;
1193 - Unknown system variable 'kill_idle_transaction'

尝试4:修改lock_wait_timeout配置,缩短超时时间,无效;

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';
mysql> SET GLOBAL innodb_lock_wait_timeout=500;
mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';

尝试5:查看事务信息表 SELECT * FROM information_schema.INNODB_TRX;发现有2个死锁。但trx_mysql_thread_id=0; 无法直接kill相关进程;

mysql> SELECT * FROM information_schema.INNODB_TRX;
+------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+---------------------+
| trx_id     | trx_state | trx_started         | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_adaptive_hash_latched | trx_adaptive_hash_timeout | trx_is_read_only | trx_autocommit_non_locking | trx_schedule_weight |
+------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+---------------------+
| 2544640445 | RUNNING   | 2022-09-26 15:26:38 | NULL                  | NULL             |          5 |                   0 | NULL      | NULL                |                 0 |                 2 |                3 |                  1136 |               1 |                 2 |                       0 | REPEATABLE READ     |                 1 |                      1 | NULL                       |                         0 |                         0 |                0 |                          0 | NULL                |
| 2451894785 | RUNNING   | 2022-09-26 15:26:38 | NULL                  | NULL             |          0 |                   0 | NULL      | NULL                |                 0 |                 0 |                0 |                  1136 |               0 |                 0 |                       0 | REPEATABLE READ     |                 1 |                      1 | NULL                       |                         0 |                         0 |                0 |                          0 | NULL                |
+------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+---------------------+

本案例正确处理:trx_mysql_thread_id=0的事务为XA事务,需对XA事务回滚;

步骤一:需使用xa recover获取XA事务信息。

mysql> xa recover;
+----------+--------------+--------------+-------------------------------------------+
| formatID | gtrid_length | bqual_length | data                                      |
+----------+--------------+--------------+-------------------------------------------+
|        1 |           39 |            2 | 297d0fba-8a0c-4945-adab-bf1eafedf1d6:3734 |
|        1 |           39 |            2 | 418ffc3a-7d9c-4687-87fb-7ca6814a2dbc:5050 |
+----------+--------------+--------------+-------------------------------------------+

步骤二:XA事务回滚,根据上一步获取到的XA事务信息,根据gtrid_length,bqual_length分割data值,代入下面的格式:

# xa rollback 'left(data,gtrid_length)','substr(data,gtrid_length+1,bqual_length)', formatID;

本案例回滚SQL:

mysql> xa rollback '297d0fba-8a0c-4945-adab-bf1eafedf1d6:37','34', 1;
Query OK, 0 rows affected

mysql> xa rollback '418ffc3a-7d9c-4687-87fb-7ca6814a2dbc:50','50', 1;
Query OK, 0 rows affected

再次删除表,可正常删除。完成!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值