mysql_阻塞和死鎖
阿新 • • 發佈:2022-03-26
什麼是阻塞
由於不同鎖之間的相容關係,造成一個事務需要等待另一個事務釋放其所佔用的資源的現象 稱為 阻塞
如何發現阻塞
mysql_8.0
SELECT waiting_pid as '被阻塞的執行緒', waiting_query as '被阻塞的SQL', blocking_pid as '阻塞執行緒', blocking_query as '阻塞SQL', waiting_age as '阻塞時間', sql_kill_blocking_query as '建議操作' FROM sys.innodb_lock_waits WHERE ( UNIX_TIMESTAMP() - UNIX_TIMESTAMPP(wait_started) ) > 30;
這裡的 30 是三十秒的意思
如何處理阻塞
- 終止佔用資源的事務(治標不治本)
- 優化佔用資源事務的SQL,使其儘快釋放資源
什麼是死鎖
並行執行的多個事務相互之間佔有了對方所需要的資源
比如:
事務一
BEGIN;
Update course set score = 9.7 where course_id = 35;
update user set score = score - 10 where user_id = 10;
事務二
BEGIN; update user set score = score + 10 where user_id = 10; Update course set score = 9.8 where course_id = 35;
由於事務一和事務二 where條件一致,在一定的條件下會導致死鎖,比如事務一在執行第一條sql時對該資源加排他鎖,同時事務二對另一資源加上了排他鎖,當兩個事務在執行它們的第二條SQL時,會分別等待對方的排他鎖釋放,導致死鎖發生
如何發現死鎖
將死鎖記錄到錯誤日誌中
set global innodb_print_all_deadlocks = on;
死鎖日誌例子(整理後):
TRANSACTION 1704, ACTIVE 119 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 4 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1 MYSQL thread id 12, OS thread handle 14025222817xxxxx, query id 170 localhost root update update imc_user set score = score + 10 where user_id = 10
這裡記錄的可能不是導致產生死鎖的那個SQL, 而是事務中發生死鎖時正在執行的那個SQL,所以還是根據這個線索去程式中尋找問題的癥結所在