資料庫偶然出現死鎖 等待鎖超時 的情況處理

2021-08-11 02:02:57 字數 4723 閱讀 3271

前言:朋友諮詢我說執行簡單的update語句失效,症狀如下:

mysql> update order_info  set province_id=15  ,city_id= 1667  where order_from=10 and order_out_sn='1407261241***x';

error 1205 (hy000): lock wait timeout exceeded; try restarting transaction

mysql> 

qq遠端過去,開始check

1,檢視資料庫的隔離級別:

mysql> select @@tx_isolation;

+-----------------+

| @@tx_isolation  |

+-----------------+

| repeatable-read |

+-----------------+

1 row in set (0.00 sec)

mysql> 

2,去檢視先當前庫的執行緒情況:

mysql> show full processlist;

| id       | user            | host              | db              | command     | time    | state                   | info                  |

|        1 | event_scheduler | localhost         | null            | daemon      | 9635385 | waiting on empty queue  | null                  |

|9930577| business_web    | 192.168.1.21:45503 | business_db     | sleep       |     153 |                         | null                  |

|  9945825 | business_web    | 192.168.1.25:49518 | business_db     | sleep       |      43 |                         | null                  |

|  9946322 | business_web    | 192.168.1.23:44721 | business_db     | sleep       |     153 |                         | null                  |

|  9960167 | business_web    | 192.168.3.28:2409  | business_db     | sleep       |      93 |                         | null                  |

|  9964484 | business_web    | 192.168.1.21:24280 | business_db     | sleep       |       7 |                         | null                  |

|  9972499 | business_web    | 192.168.3.28:35752 | business_db     | sleep       |      13 |                         | null                  |

| 10000117 | business_web    | 192.168.3.28:9149  | business_db     | sleep       |       6 |                         | null                  |

| 10002523 | business_web    | 192.168.3.29:42872 | business_db     | sleep       |       6 |                         | null                  |

| 10007545 | business_web    | 192.168.1.21:51379 | business_db     | sleep       |     155 |                         | null                  |

......

沒有看到正在執行的慢sql記錄執行緒,再去檢視innodb的事務表innodb_trx,看下裡面是否有正在鎖定的事務執行緒,看看id是否在show full processlist裡面的sleep執行緒中,如果是,就證明這個sleep的執行緒事務一直沒有commit或者rollback而是卡住了,我們需要手動kill掉。

mysql> select * from information_schema.innodb_trx;

潮又落ps: 如果用該命令沒有看到狀態為lock wait的執行緒(我就遇到過),可以嘗試把trx_started字段時間不太正常的程序殺掉就好了。

*************************** 1. row ***************************

trx_id: 20866

trx_state: lock wait

trx_started: 2014-07-31 10:42:35

trx_requested_lock_id: 20866:617:3:3

trx_wait_started: 2014-07-30 10:42:35

trx_weight: 2

trx_mysql_thread_id:9930577

trx_query: delete from dltask where id=1

trx_operation_state: starting index read

trx_tables_in_use: 1

trx_tables_locked: 1

trx_lock_structs: 2

trx_lock_memory_bytes: 376

trx_rows_locked: 1

trx_rows_modified: 0

trx_concurrency_tickets: 0

trx_isolation_level: read committed

trx_unique_checks: 1

trx_foreign_key_checks: 1

trx_last_foreign_key_error: null

trx_adaptive_hash_latched: 0

trx_adaptive_hash_timeout: 10000

trx_is_read_only: 0

trx_autocommit_non_locking: 0

3,看到有這條9930577的sql,kill掉,執行kill 9930577;

mysql> kill 9930577;

query ok, 0 rows affected (0.00 sec)

mysql>

然後再去查詢

innodb_trx

表,就沒有阻塞的事務

sleep

執行緒存在了,如下所示:

mysql> select * from innodb_trx;

empty set (0.00 sec)

error:

no query specified

mysql>

再去執行

update

語句,就能正常執行了,如下所示:

mysql> update order_info  set province_id=15  ,city_id= 1667  where order_from=10 and order_out_sn='1407261241***x';

query ok, 1 row affected (0.00 sec)

rows matched: 1  changed: 1  warnings: 0

mysql>

4,總結分析

表資料量也不大,按照普通的情況來說,簡單的update應該不會造成阻塞的,mysql都是autocommit,不會出現update卡住的情況,去檢視下autocommit的值。

mysql> select @@autocommit;

+--------------+

| @@autocommit |

+--------------+

|0|

+--------------+

1 row in set (0.00 sec)

mysql>

看到亮閃閃的0,這個設定導致原來的update語句如果沒有commit的話,你再重新執行update語句,就會等待鎖定,當等待時間過長的時候,就會報error 1205 (hy000): lock wait timeout exceeded; try restarting transaction的錯誤。

所以趕緊commit剛才執行的update語句,之後 set global autocommit=1;

來自:

一次資料庫鎖等待超時疑似死鎖排查過程

1 起因 測試妹紙找過來說定時任務日誌裡有超時日誌,我看了下估摸是依賴的服務a在重啟之類的原因,問題不大觀望下過一分鐘應該沒有了 過幾分鐘在看日誌,居然還在不停的報錯,於是就去依賴的服務a看了下日誌 哎呀,居然鎖等待超時,莫不是死鎖了?2 排查原因 在mysql控制端執行命令看有沒有開啟死鎖日誌開關...

資料庫索引 鎖 死鎖

平衡多路查詢樹 樹的左右兩邊的層級數相差不會大於1 非葉子節值大於左邊子節點 小於右邊子節點!mysql索引存在硬碟上 b 樹子節點才存資料 非葉結點僅具有索引作用 且是有序的 範圍查詢 層級也不高,減少io b樹不管葉子節點還是非葉子節點,都會儲存資料,這樣導致在非葉子節點中能儲存的指標數量變少 ...

解決資料庫死鎖 取鎖超時的一些經歷

背景 剛從別人手裡交接了乙個服務,裡面有個複雜的業務 命名為介面a 最近我們公司需要修復資料,開了80臺機器去呼叫介面a,日誌就各種 lock wait timeout exceeded try restarting transaction 備註 1.介面a有事務 2.統計錯誤日誌,有很多個地方都會...