摘要:
死鎖:是指兩個或則多個事務在同一個資源上互相占用,并請求鎖定對方占用的資源,而導緻惡性循環的現象;當産生死鎖的時候,MySQL會復原一個小事務的SQL,確定另一個完成。上面是死鎖的概念,而在MySQL中 innodb 會出現死鎖的情況,但是檢視死鎖卻很不“智能”。隻能通過 show engine innodb status 檢視,但隻保留最後一個死鎖的資訊,之前産生的死鎖都被刷掉了。下面介紹的工具卻很容易做到記錄。
前提:
下載下傳位址: wget www.percona.com/downloads/percona-toolkit/2.2.2/percona-toolkit-2.2.2.tar.gz
安裝方法:perl Makefile.PL;make;make install
使用方法:
pt-deadlock-logger [OPTIONS] DSN
pt-deadlock-logger : 顯示指定的DSN的死鎖日志資訊,他能夠标準輸出到螢幕也可以把資訊寫日志檔案中(--log參數)甚至可以保留到指定的表中(--dest參數),該工具預設是永久執行,除非指定 --run-time 或 --iterations 。
用法:
pt-deadlock-logger --ask-pass --run-time=10 --interval=3 --create-dest-table --dest D=test,t=deadlocks u=root,P=3306,h=192.168.200.25Enter MySQL password:
參數:
--create-dest-table :建立指定的表。
--dest :建立存儲死鎖資訊的表。
--database :-D,指定連結的資料庫。
--table :-t,指定存儲的表名。
--log :指定死鎖日志資訊寫入到檔案。
--run-time :運作次數,預設永久
--interval :運作間隔時間,預設30s。
u,p,h,P :連結資料庫的資訊。
以上的參數,已經夠用,更多的參數資訊見官網說明。
測試:
運作 pt-deadlock-logger ,操作資料庫:
session1:
root@localhost : test 04:46:11>select * from dead_tab;+----+------+------+---------+| id | name | age | address |+----+------+------+---------+| 1 | a | 33 | NULL || 2 | bbb | 34 | NULL || 3 | bbb | 35 | NULL |+----+------+------+---------+3 rows in set (0.00 sec)
root@localhost : test 04:46:24>start transaction;Query OK, 0 rows affected (0.00 sec)
root@localhost : test 04:46:31>update dead_tab set name ='A' where id >2;Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
section2:
root@localhost : test 04:46:13>start transaction;Query OK, 0 rows affected (0.01 sec)
root@localhost : test 04:46:48>update dead_tab set name='AA' where id >1;…………
…………
一直在等待着...
回到session1:
root@localhost : test 04:46:44>update dead_tab set name ='AA' where id >1;ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction死鎖出現了!
看pt-deadlock-logger的運作情況:
zhoujy@zhoujy:~$ pt-deadlock-logger --ask-pass --create-dest-table --dest D=test,t=deadlocks u=root,P=3306,h=192.168.200.25Enter MySQL password:
server ts thread txn_id txn_time user hostname ip db tbl idx lock_type lock_mode wait_hold victim query192.168.200.25 2013-10-28T16:47:00 99 0 8 root localhost test dead_tab PRIMARY RECORD X w 0 update dead_tab set name='AA' where id >1192.168.200.25 2013-10-28T16:47:00 100 0 16 root localhost test dead_tab PRIMARY RECORD X w 1 update dead_tab set name ='AA' where id >1
死鎖被列印出來,看看 是否寫到表裡 :
root@localhost : test 04:32:45>select * from deadlocks\G;*************************** 1. row ***************************
server: 192.168.200.25
ts: 2013-10-28 16:47:00
thread: 99
txn_id: 0
txn_time: 8
user: root
hostname: localhost
ip:
db: test
tbl: dead_tab
idx: PRIMARYlock_type: RECORD
lock_mode: X
wait_hold: w
victim: 0
query: update dead_tab set name='AA' where id >1*************************** 2. row ***************************
server: 192.168.200.25
ts: 2013-10-28 16:47:00
thread: 100
txn_id: 0
txn_time: 16
user: root
hostname: localhost
ip:
db: test
tbl: dead_tab
idx: PRIMARYlock_type: RECORD
lock_mode: X
wait_hold: w
victim: 1
query: update dead_tab set name ='AA' where id >12 rows in set (0.00 sec)
結果表明死鎖資訊已經寫入到了表中,記錄的内容是2條産生的sql。繼續同樣的步驟再執行2次出現死鎖的SQL來驗證是之前的死鎖資訊否被刷寫掉:
root@localhost : test 04:53:29>select count(*) from deadlocks;+----------+| count(*) |+----------+| 6 |+----------+1 row in set (0.02 sec)
繼續被寫入到表中。 可以看到多個産生死鎖的sql,而不僅僅是最後一條産生死鎖的sql 。