MySQL的ERROR 1205錯誤分析


 

一、錯誤發生及原因猜測

1、錯誤發生

在刪除 t_user 表的一條數據時,Navicat 發生長時間的無響應,然后彈出一個對話框,提示:ERROR 1205: Lock wait timeout exceeded; try restarting transaction

 

關閉對話框之后,數據並沒有被刪除。

 

 

2、原因猜測

 

根據錯誤信息可以知道,是因為鎖等待超時導致的錯誤。那么具體到底是什么原因。

 

我們知道,InnoDB 引擎是支持事務的。

在使用 begin 或 start transaction 開啟事務,進行更新、刪除時,會對被操作的行加行級鎖。

如果這個事務沒有提交,而其他的事務對同一行也進行了更新、刪除操作,那么這個事務是不能成功的,至於會不會出現上面的錯誤,還不確定。

 

 

二、錯誤重現

 1、演示環境

 

操作系統

Windows 7 x64

MySQL版本

MySQL Community Server (GPL) 5.5.56

執行未提交事務的用戶

system

查看會話、執行刪除操作的用戶

root

數據庫

test

t_user

 

 

 

 

 

 

 

 

 

 1 mysql> select * from t_user;
 2 +----+----------+
 3 | id | username |
 4 +----+----------+
 5 |  1 | a1       |
 6 |  2 | a2       |
 7 |  3 | a3       |
 8 |  4 | a4       |
 9 |  5 | a5       |
10 |  6 | a6       |
11 +----+----------+

 

 

2、錯誤重現

 

使用 A窗口 更新 id = 2 的數據

 

1 mysql> begin;
2 Query OK, 0 rows affected (0.00 sec)
3 
4 mysql> update t_user set username = 'b1' where id = 2;
5 Query OK, 1 row affected (0.00 sec)
6 Rows matched: 1  Changed: 1  Warnings: 0

 

在沒有提交的情況下,使用 C窗口 查看當前事務,我們可以看到事務的 狀態(trx_state)、行鎖數(trx_rows_locked)、修改數據行數(trx_rows_modified) 等信息

 

 1 mysql> select * from innodb_trx\G;
 2 *************************** 1. row ***************************
 3                     trx_id: A023
 4                  trx_state: RUNNING
 5                trx_started: 2018-03-11 15:30:19
 6      trx_requested_lock_id: NULL
 7           trx_wait_started: NULL
 8                 trx_weight: 3
 9        trx_mysql_thread_id: 5
10                  trx_query: NULL
11        trx_operation_state: NULL
12          trx_tables_in_use: 0
13          trx_tables_locked: 0
14           trx_lock_structs: 2
15      trx_lock_memory_bytes: 376
16            trx_rows_locked: 1
17          trx_rows_modified: 1
18    trx_concurrency_tickets: 0
19        trx_isolation_level: REPEATABLE READ
20          trx_unique_checks: 1
21     trx_foreign_key_checks: 1
22 trx_last_foreign_key_error: NULL
23  trx_adaptive_hash_latched: 0
24  trx_adaptive_hash_timeout: 10000

 

此時再使用 B窗口 刪除t_user表的數據,在刪除 id = 2 的數據時,發現事務被阻塞。我們在 C窗口 查看 processlist、事務以及鎖等待 情況

 

1 mysql> show full processlist;

 

 

1 mysql> select * from innodb_trx\G;

 

 

1 mysql> select * from INNODB_LOCK_WAITS\G;

 

當事務超時后出現1205的錯誤

 

此時,我們再查看一下 processlist、事務以及鎖等待 情況,發現剛才處於 等待狀態 的事務、process和鎖等待已經沒有了

1 mysql> show full processlist;
2 mysql> select * from INNODB_LOCK_WAITS\G;
3 mysql> select * from innodb_trx\G;

 

此時把 A窗口rollback 回來

mysql> rollback;

 

再查看一下processlist、事務以及鎖等待情況

 

 

由此可以確定:1205 的錯誤是因為未提交事務對數據加了行級鎖,當前事務獲取同一數據行級鎖超時導致的

 

三、解決方案

我們可以使用 show full processlist 查看未提交事務的連接的 id

 

可以看到這個連接的id是5

 

如果可以確定不是很重要的事務,我們可以使用kill命令斷開這個連接。

 

mysql> kill 5;

 

 

 如果不確定的話,還是需要溝通一下如何安全處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM