mysql kill進程后出現(xiàn)killed死鎖問題及解決
mysql kill進程后出現(xiàn)killed死鎖
經(jīng)常會出現(xiàn)這樣的場景
有一張3億的表,現(xiàn)在要對這張表進行刪除1億行,于是有人開始運行
delete from table limit 100000000;
毫無疑問這是一個愚蠢的刪除方式,于是有人開始變更刪除方式:
delete from table where id<100000000;
然而運行一段時間后,又發(fā)現(xiàn)批量刪除的效率可能會更高,所以kill掉了上一條運行了一段時間的sql,開始批量刪除, 由于是大sql,晚上點擊運行想第二天早上來看結(jié)果的DBA就會遺憾的發(fā)現(xiàn)新執(zhí)行的sql被鎖給擋了回來,并沒有運行,導致浪費了一晚上的時間。
但是盲目的等待鎖釋放心里沒底,所以我們可以通過下面的方式計算出這個鎖什么時候能夠釋放,我們就可以使用表了。
場景
一個巨大的delete語句 執(zhí)行一小時后kill ,
show processlist出現(xiàn)killed進程 ,
不要盲目重啟! 重啟MySQL后進程消失但鎖依然存在!
重啟MySQL后進程消失但鎖依然存在,因為回滾還要繼續(xù),這是mysql對數(shù)據(jù)的保護機制
通過下列語句查詢事務(wù)情況
SELECT * FROM information_schema.INNODB_TRX\G
*************************** 1. row ***************************
trx_id: 715674773
trx_state: ROLLING BACK
trx_started: 2018-09-24 23:17:30
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 540574
trx_mysql_thread_id: 0
trx_query: NULL
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 1
trx_lock_structs: 3
trx_lock_memory_bytes: 1136
trx_rows_locked: 2
trx_rows_modified: 540571 #代表鎖影響的行數(shù),當數(shù)值為0時,鎖將會釋放
trx_concurrency_tickets: 0
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_adaptive_hash_latched: 0
trx_is_read_only: 0
trx_autocommit_non_locking: 0
1 row in set (0.00 sec)
trx_rows_modified: 代表鎖影響的行數(shù),當數(shù)值為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 | | | |#擁有鎖的事務(wù)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 | |#被鎖的數(shù)據(jù) +————-+———————+——+—–+———+——-+ 10 rows in set (0.00 sec) desc innodb_lock_waits; +——————-+————-+——+—–+———+——-+ | Field | Type | Null | Key | Default | Extra | +——————-+————-+——+—–+———+——-+ | requesting_trx_id | varchar(18) | NO | | | |#請求鎖的事務(wù)ID | requested_lock_id | varchar(81) | NO | | | |#請求鎖的鎖ID | blocking_trx_id | varchar(18) | NO | | | |#當前擁有鎖的事務(wù)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 | | | |#事務(wù)ID | trx_state | varchar(13) | NO | | | |#事務(wù)狀態(tài): | trx_started | datetime | NO | | 0000-00-00 00:00:00 | |#事務(wù)開始時間; | trx_requested_lock_id | varchar(81) | YES | | NULL | |#innodb_locks.lock_id | trx_wait_started | datetime | YES | | NULL | |#事務(wù)開始等待的時間 | trx_weight | bigint(21) unsigned | NO | | 0 | |# | trx_mysql_thread_id | bigint(21) unsigned | NO | | 0 | |#事務(wù)線程ID | trx_query | varchar(1024) | YES | | NULL | |#具體SQL語句 | trx_operation_state | varchar(64) | YES | | NULL | |#事務(wù)當前操作狀態(tài) | trx_tables_in_use | bigint(21) unsigned | NO | | 0 | |#事務(wù)中有多少個表被使用 | trx_tables_locked | bigint(21) unsigned | NO | | 0 | |#事務(wù)擁有多少個鎖 | trx_lock_structs | bigint(21) unsigned | NO | | 0 | |# | trx_lock_memory_bytes | bigint(21) unsigned | NO | | 0 | |#事務(wù)鎖住的內(nèi)存大?。˙) | trx_rows_locked | bigint(21) unsigned | NO | | 0 | |#事務(wù)鎖住的行數(shù) | trx_rows_modified | bigint(21) unsigned | NO | | 0 | |#事務(wù)更改的行數(shù) | trx_concurrency_tickets | bigint(21) unsigned | NO | | 0 | |#事務(wù)并發(fā)票數(shù) | trx_isolation_level | varchar(16) | NO | | | |#事務(wù)隔離級別 | 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)
結(jié)論:
時間過長的update、delete等語句在kill之后會進行回滾操作,會鎖表,經(jīng)常有人更換不同方式對大數(shù)據(jù)進行修改刪除,然而盲目的殺死正在長時間運行的進程后并不能馬上對表進行新的操作,后果只能是等待之前的操作回滾結(jié)束,本想用更快的方式操作表結(jié)果得不償失,所以還是建議選擇好對表修改操作方式然后一次運行,不再修改。
后續(xù)測試了innodb_force_recovery參數(shù)的修改:
結(jié)論:非緊急情況不允許把innodb_force_recovery修改成非0值!
補充:
今天又遇到一個新的情況:
當我在改一個小表的表結(jié)構(gòu)時發(fā)現(xiàn)本應該瞬間完成的語句一直沒有執(zhí)行成功,連接數(shù)據(jù)庫端查看發(fā)現(xiàn)此語句正在等待鎖釋放;
于是開始尋找加鎖的源頭
show processlist; select * from information_schema.processlist where time>100 and command<>'sleep';
果然查到了一個刪除語句;
但是發(fā)現(xiàn)該語句已經(jīng)被kill 狀態(tài)顯示為killed,并且已經(jīng)執(zhí)行了50000s+ 也就是幾天前了;(之所以沒有監(jiān)控到是因為這個我的過濾條件寫的是where command=‘Query’ 所以這個killed進程就沒有捕捉到)此時我使用上述查詢查找鎖記錄發(fā)現(xiàn)查找結(jié)果是空的
SELECT * FROM information_schema.INNODB_TRX\G
查詢show engine innodb status 也沒有找到rolling back關(guān)鍵字的大回滾事務(wù);
(我中間還測了一下收回賬戶權(quán)限這個查詢會不會消失 ,然而和我推測的一樣,并沒有什么錘子用)
于是我決定重啟;既然沒有回滾想必重啟應該不會有什么大問題;
所以我就shutdown了一下,mysql登陸不了了,但是進程很奇怪的還在;我又手動kill -9 了一下;
然后重新啟動,成功啟動;
new結(jié)論:
遇到killed語句先
SELECT * FROM information_schema.INNODB_TRX\G
看看有沒有什么事務(wù)正在回滾或被鎖住
如果有就安心的等它回滾結(jié)束,暫時不要用這個表,如果非要用就新建一個別名表 在從庫把備份拿過來寫進去,讓程序先換個表讀取;
如果查詢沒有結(jié)果,再次確認一下show engine innodb status 有沒有正在回滾的事務(wù) 如果進程太多可以重定向出來:
mysql -u -p -P 3306 -e “show engine innodb status” >/tmp/status.txt
斜杠/查找是否存在關(guān)鍵字 rolling back
如果確定沒有回滾語句,就可以安心的重啟了 ;

總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL去重中distinct和group?by的區(qū)別淺析
今天無意中聽到有同事在討論,distinct和group by有什么區(qū)別,下面這篇文章主要給大家介紹了關(guān)于MySQL去重中distinct和group?by區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-11-11
詳解MySQL中DROP,TRUNCATE 和DELETE的區(qū)別實現(xiàn)mysql從零開始
注意:這里說的delete是指不帶where子句的delete語句 相同點: truncate和不帶where子句的delete, 以及drop都會刪除表內(nèi)的數(shù)據(jù)2008-04-04
MySQL使用LOAD_FILE()函數(shù)方法總結(jié)
在本篇文章里小編給大家分享了關(guān)于MySQL使用LOAD_FILE()函數(shù)方法和相關(guān)知識點,需要的朋友們學習下。2019-03-03
計算機管理服務(wù)中找不到mysql的服務(wù)的解決辦法
MySQL是一種流行的開源關(guān)系型數(shù)據(jù)庫管理系統(tǒng),用于存儲和管理大量數(shù)據(jù),在計算機管理中,啟動MySQL服務(wù)是一項重要的任務(wù),因為它可以確保數(shù)據(jù)庫系統(tǒng)的順利運行,這篇文章主要給大家介紹了關(guān)于計算機管理服務(wù)中找不到mysql的服務(wù)的解決辦法,需要的朋友可以參考下2023-05-05

