mysql 表鎖 mysql鎖表解決方案

2021-10-25 14:03:50 字數 2927 閱讀 2865

1.為何會鎖表

首先我們了解一下資料庫查詢機制,首先我們用工具進行連線查詢時,會建立乙個connection,此時資料庫會將查詢語句解析成一棵「樹」,各個引擎底層的結構不一樣,mysql的話在innodb用的是b-tree,俗稱b+樹,那麼再到執行器進行處理,最後返回給客戶端。

鎖表的原因:

當多個連線(資料庫連線)同時對乙個表的資料進行更新操作,那麼速度將會越來越慢,持續一段時間後將出現資料表被鎖的現象,從而影響到其它的查詢及更新。尤其當我們使用迴圈的時候更加容易出現鎖表這種情況,導致其他連線無法讀寫此表。

鎖表的發現:

當我們發現一條語句查詢很久都遲遲沒有答案,可以首先考慮是否鎖表了,如何檢視呢?

方法一show processlist

image.png

但是此命令只能顯示前100條資料,要想看全部的資料,請輸入

show full processlist

這個命令中最關鍵的就是state列,mysql列出的狀態主要有以下幾種:

checking table

正在檢查資料表(這是自動的)。

closing tables

正在將表中修改的資料重新整理到磁碟中,同時正在關閉已經用完的表。這是乙個很快的操作,如果不是這樣的話,就應該確認磁碟空間是否已經滿了或者磁碟是否正處於重負中。

connect out

複製從伺服器正在連線主伺服器。

copying to tmp table on disk

由於臨時結果集大於tmp_table_size,正在將臨時表從記憶體儲存轉為磁碟儲存以此節省記憶體。

creating tmp table

正在建立臨時表以存放部分查詢結果。

deleting from main table

伺服器正在執行多表刪除中的第一部分,剛刪除第乙個表。

deleting from reference tables

伺服器正在執行多表刪除中的第二部分,正在刪除其他表的記錄。

flushing tables

正在執行flush tables,等待其他執行緒關閉資料表。

killed

傳送了乙個kill請求給某執行緒,那麼這個執行緒將會檢查kill標誌位,同時會放棄下乙個kill請求。mysql會在每次的主迴圈中檢查kill標誌位,不過有些情況下該執行緒可能會過一小段才能死掉。如果該線程程被其他執行緒鎖住了,那麼kill請求會在鎖釋放時馬上生效。

locked

被其他查詢鎖住了。

sending data

正在處理select查詢的記錄,同時正在把結果傳送給客戶端。

sorting for group

正在為group by做排序。

sorting for order

正在為order by做排序。

opening tables

這個過程應該會很快,除非受到其他因素的干擾。例如,在執alter table或lock table語句行完以前,資料表無法被其他執行緒開啟。正嘗試開啟乙個表。

removing duplicates

正在執行乙個select distinct方式的查詢,但是mysql無法在前乙個階段優化掉那些重複的記錄。因此,mysql需要再次去掉重複的記錄,然後再把結果傳送給客戶端。

reopen table

獲得了對乙個表的鎖,但是必須在表結構修改之後才能獲得這個鎖。已經釋放鎖,關閉資料表,正嘗試重新開啟資料表。

repair by sorting

修復指令正在排序以建立索引。

repair with keycache

修復指令正在利用索引快取乙個乙個地建立新索引。它會比repair by sorting慢些。

searching rows for update

正在講符合條件的記錄找出來以備更新。它必須在update要修改相關的記錄之前就完成了。

sleeping

正在等待客戶端傳送新請求.

system lock

正在等待取得乙個外部的系統鎖。如果當前沒有執行多個mysqld伺服器同時請求同乙個表,那麼可以通過增加--skip-external-locking引數來禁止外部系統鎖。

upgrading lock

insert delayed正在嘗試取得乙個鎖表以插入新記錄。

updating

正在搜尋匹配的記錄,並且修改它們。

user lock

正在等待get_lock()。

waiting for tables

該執行緒得到通知,資料表結構已經被修改了,需要重新開啟資料表以取得新的結構。然後,為了能的重新開啟資料表,必須等到所有其他執行緒關閉這個表。以下幾種情況下會產生這個通知:flush tables tbl_name, alter table, rename table, repair table, analyze table,或optimize table。

waiting for handler insert

insert delayed已經處理完了所有待處理的插入操作,正在等待新的請求。

大部分狀態對應很快的操作,只要有乙個執行緒保持同乙個狀態好幾秒鐘,那麼可能是有問題發生了,需要檢查一下。

還有其他的狀態沒在上面中列出來,不過它們大部分只是在檢視伺服器是否有存在錯誤是才用得著。

假如發現鎖表程序,請輸入kill指令將他剔除

kill "id"

方法2可以檢視此表

select * from information_schema.innodb_trx

image.png

主要看箭頭指向的這幾個字段,如果有阻塞資料(不為0的就是阻塞的),找到後在根據下圖這個字段:try_mysql_thread_id 作為這條資料的主鍵id執行這個sql進行刪除: kill id ;(殺死對應id的程序).假設這裡try_mysql_thread_id=14的這條資料是鎖了。我們執行 kill 14刪除就不在鎖表了。

以上兩種方法都可以用哦,尤其是做運維的。

mysql鎖表 解鎖

檢視mysql鎖表的情況 select from information schema.innodb trx show processlist殺掉查詢結果中鎖表的trx mysql thread id,其中trx mysql thread id對應 show processlist 的id kill...

mysql鎖解決方法 mysql鎖表解決方法

如果有 super 許可權,則可以看到全部的執行緒,否則,只能看到自己發起的執行緒 id列 乙個標識,你要kill 乙個語句的時候很有用。user列 顯示當前使用者,如果不是root,這個命令就只顯示你許可權範圍內的sql語句。host列 顯示這個語句是從哪個ip 的哪個埠上發出的。可用來追蹤出問題...

mysql事物鎖鎖表 mysql 事務 行鎖 表鎖

一 準備 select from information schema.innodb trx 查詢事務 select from information schema.innodb locks 查詢鎖 select from information schema.innodb lock waits 暫...