天天看點

percona-toolkit

摘要:

      死鎖:是指兩個或則多個事務在同一個資源上互相占用,并請求鎖定對方占用的資源,而導緻惡性循環的現象;當産生死鎖的時候,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 。