本文主要是介绍mysql kill进程后出现killed死锁问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
经常会出现这样的场景:有一张3亿的表,现在要对这张表进行删除1亿行,于是有人开始运行delete from table limit 100000000;
毫无疑问这是一个愚蠢的删除方式,于是有人开始变更删除方式:delete from table where id<100000000;
然而运行一段时间后,又发现批量删除的效率可能会更高,所以kill掉了上一条运行了一段时间的sql,开始批量删除, 由于是大sql,晚上点击运行想第二天早上来看结果的DBA就会遗憾的发现新执行的sql被锁给挡了回来,并没有运行,导致浪费了一晚上的时间。
但是盲目的等待锁释放心里没底,所以我们可以通过下面的方式计算出这个锁什么时候能够释放,我们就可以使用表了。
场景:
一个巨大的delete语句 执行一小时后kill ,
show processlist出现killed进程 ,
不要盲目重启! 重启MySQL后进程消失但锁依然存在!
重启MySQL后进程消失但锁依然存在,因为回滚还要继续,这是mysql对数据的保护机制
通过下列语句查询事务情况:
SELECT * FROM information_schema.INNODB_TRX\G*************************** 1. row ***************************trx_id: 715674773trx_state: ROLLING BACKtrx_started: 2018-09-24 23:17:30trx_requested_lock_id: NULLtrx_wait_started: NULLtrx_weight: 540574trx_mysql_thread_id: 0trx_query: NULLtrx_operation_state: NULLtrx_tables_in_use: 0trx_tables_locked: 1trx_lock_structs: 3trx_lock_memory_bytes: 1136trx_rows_locked: 2trx_rows_modified: 540571 #代表锁影响的行数,当数值为0时,锁将会释放trx_concurrency_tickets: 0trx_isolation_level: REPEATABLE READtrx_unique_checks: 1trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULLtrx_adaptive_hash_latched: 0trx_is_read_only: 0
trx_autocommit_non_locking: 0
1 row in set (0.00 sec)
trx_rows_modified: 代表锁影响的行数,当数值为0时,锁将会释放
查看表锁信息
SELECT * FROM information_schema.INNODB_LOCKS
SELECT * FROM information_schema.INNODB_LOCK_waits
desc innodb_locks;
+————-+———————+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+————-+———————+——+—–+———+——-+
| lock_id | varchar(81) | NO | | | |#锁ID
| lock_trx_id | varchar(18) | NO | | | |#拥有锁的事务ID
| lock_mode | varchar(32) | NO | | | |#锁模式
| lock_type | varchar(32) | NO | | | |#锁类型
| lock_table | varchar(1024) | NO | | | |#被锁的表
| lock_index | varchar(1024) | YES | | NULL | |#被锁的索引
| lock_space | bigint(21) unsigned | YES | | NULL | |#被锁的表空间号
| lock_page | bigint(21) unsigned | YES | | NULL | |#被锁的页号
| lock_rec | bigint(21) unsigned | YES | | NULL | |#被锁的记录号
| lock_data | varchar(8192) | YES | | NULL | |#被锁的数据
+————-+———————+——+—–+———+——-+
10 rows in set (0.00 sec)desc innodb_lock_waits;
+——————-+————-+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+——————-+————-+——+—–+———+——-+
| requesting_trx_id | varchar(18) | NO | | | |#请求锁的事务ID
| requested_lock_id | varchar(81) | NO | | | |#请求锁的锁ID
| blocking_trx_id | varchar(18) | NO | | | |#当前拥有锁的事务ID
| blocking_lock_id | varchar(81) | NO | | | |#当前拥有锁的锁ID
+——————-+————-+——+—–+———+——-+
4 rows in set (0.00 sec)desc innodb_trx ;
+—————————-+———————+——+—–+———————+——-+
| Field | Type | Null | Key | Default | Extra |
+—————————-+———————+——+—–+———————+——-+
| trx_id | varchar(18) | NO | | | |#事务ID
| trx_state | varchar(13) | NO | | | |#事务状态:
| trx_started | datetime | NO | | 0000-00-00 00:00:00 | |#事务开始时间;
| trx_requested_lock_id | varchar(81) | YES | | NULL | |#innodb_locks.lock_id
| trx_wait_started | datetime | YES | | NULL | |#事务开始等待的时间
| trx_weight | bigint(21) unsigned | NO | | 0 | |#
| trx_mysql_thread_id | bigint(21) unsigned | NO | | 0 | |#事务线程ID
| trx_query | varchar(1024) | YES | | NULL | |#具体SQL语句
| trx_operation_state | varchar(64) | YES | | NULL | |#事务当前操作状态
| trx_tables_in_use | bigint(21) unsigned | NO | | 0 | |#事务中有多少个表被使用
| trx_tables_locked | bigint(21) unsigned | NO | | 0 | |#事务拥有多少个锁
| trx_lock_structs | bigint(21) unsigned | NO | | 0 | |#
| trx_lock_memory_bytes | bigint(21) unsigned | NO | | 0 | |#事务锁住的内存大小(B)
| trx_rows_locked | bigint(21) unsigned | NO | | 0 | |#事务锁住的行数
| trx_rows_modified | bigint(21) unsigned | NO | | 0 | |#事务更改的行数
| trx_concurrency_tickets | bigint(21) unsigned | NO | | 0 | |#事务并发票数
| trx_isolation_level | varchar(16) | NO | | | |#事务隔离级别
| trx_unique_checks | int(1) | NO | | 0 | |#是否唯一性检查
| trx_foreign_key_checks | int(1) | NO | | 0 | |#是否外键检查
| trx_last_foreign_key_error | varchar(256) | YES | | NULL | |#最后的外键错误
| trx_adaptive_hash_latched | int(1) | NO | | 0 | |#
| trx_adaptive_hash_timeout | bigint(21) unsigned | NO | | 0 | |#
+—————————-+———————+——+—–+———————+——-+
22 rows in set (0.01 sec)
结论:时间过长的update、delete等语句在kill之后会进行回滚操作,会锁表,经常有人更换不同方式对大数据进行修改删除,然而盲目的杀死正在长时间运行的进程后并不能马上对表进行新的操作,后果只能是等待之前的操作回滚结束,本想用更快的方式操作表结果得不偿失,所以还是建议选择好对表修改操作方式然后一次运行,不再修改。
后续测试了innodb_force_recovery参数的修改:
结论:非紧急情况不允许把innodb_force_recovery修改成非0值!
---------------------
作者:DBA界的小学生
来源:CSDN
原文:https://blog.csdn.net/m0_37827567/article/details/82979767
版权声明:本文为博主原创文章,转载请附上博文链接!
这篇关于mysql kill进程后出现killed死锁问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!