1. 程式人生 > >pt-osc測試

pt-osc測試

pt-osc測試

1、原表必須存在主鍵 PRIMARY KEY 或者 UNIQUE KEY

The new table `darren`.`_t_user_new` does not have a PRIMARY KEY or a unique index which is required for the DELETE trigger.
Please check you have at least one UNIQUE and NOT NULLABLE index.

2、支援有外來鍵約束的表,需要加上--alter-foreign-keys-method=rebuild_constraints引數

3、預設原表不能存在觸發器。但是需要--preserve-triggers變數,不建議這麼做,可能存在風險

The table `test`.`foo` has triggers but --preserve-triggers was not specified.

4、在pt-osc的執行過程中,如果有對主鍵的更新操作則會出現重複的資料,在3.02版本中已經修復

3.02之前:
  更新觸發器對應的sql語句:REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals);
3.02之後:
  DELETE IGNORE FROM $new_tbl->{name} WHERE !($upd_index_cols) AND $del_index_cols;
  REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals);

5、innodb_autoinc_lock_mode=1測試

當innodb_autoinc_lock_mode =1:
對於 bulk inserts,使用傳統表鎖的 AUTO-INC Locking 方式。

------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-10-24 16:44:13 0x7f93585e3700
*** (1) TRANSACTION:
TRANSACTION 275263782, ACTIVE 0 sec setting auto-inc lock
mysql tables in use 2, locked 2
LOCK WAIT 4 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 2
MySQL thread id 190, OS thread handle 140269612435200, query id 20289531 10.126.126.164 darren update
REPLACE INTO `sbtest`.`_sbtest1_new` (`id`, `c4`, `k`, `c`, `pad`, `c3`, `c5`, `c6`, `c7`, `c14`, `c9`, `c10`) VALUES (NEW.`id`, NEW.`c4`, NEW.`k`, NEW.`c`, NEW.`pa
d`, NEW.`c3`, NEW.`c5`, NEW.`c6`, NEW.`c7`, NEW.`c14`, NEW.`c9`, NEW.`c10`)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
TABLE LOCK table `sbtest`.`_sbtest1_new` trx id 275263782 lock mode AUTO-INC waiting
*** (2) TRANSACTION:
TRANSACTION 275263754, ACTIVE 0 sec fetching rows, thread declared inside InnoDB 4212
mysql tables in use 2, locked 2
258 lock struct(s), heap size 41168, 17913 row lock(s), undo log entries 17886
MySQL thread id 204, OS thread handle 140270819489536, query id 20289201 10.126.126.164 darren Sending data
INSERT LOW_PRIORITY IGNORE INTO `sbtest`.`_sbtest1_new` (`id`, `c4`, `k`, `c`, `pad`, `c3`, `c5`, `c6`, `c7`, `c14`, `c9`, `c10`) SELECT `id`, `c4`, `k`, `c`, `pad`
, `c3`, `c5`, `c6`, `c7`, `c14`, `c9`, `c10` FROM `sbtest`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1481317')) AND ((`id` <= '1506548')) LOCK IN SHARE MODE
 /*pt-online-schema-change 69839 copy nibble*/
*** (2) HOLDS THE LOCK(S):
TABLE LOCK table `sbtest`.`_sbtest1_new` trx id 275263754 lock mode AUTO-INC
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 15248 page no 25707 n bits 152 index PRIMARY of table `sbtest`.`sbtest1` trx id 275263754 lock mode S locks rec but not gap waiting
Record lock, heap no 40 PHYSICAL RECORD: n_fields 15; compact format; info bits 0
 0: len 8; hex 000000000016e050; asc        P;;
 1: len 6; hex 000010683126; asc    h1&;;
 2: len 7; hex 01000007722b37; asc     r+7;;
 3: len 1; hex 30; asc 0;;
 4: len 4; hex 00385728; asc  8W(;;
 5: len 30; hex 34313331333339383035342d30323832343038383036372d383038353233; asc 41313398054-02824088067-808523; (total 119 bytes);
 6: len 30; hex 34393730393732313932382d31333738353836373533322d393836313330; asc 49709721928-13785867532-986130; (total 59 bytes);
 7: len 4; hex 80000000; asc     ;;
 8: len 1; hex 30; asc 0;;
 9: len 1; hex 30; asc 0;;
 10: len 1; hex 30; asc 0;;
 11: len 1; hex 30; asc 0;;
 12: len 4; hex 80000000; asc     ;;
 13: len 4; hex 80000000; asc     ;;
 14: len 4; hex 80000000; asc     ;;

*** WE ROLL BACK TRANSACTION (1)

【分析】

根據死鎖資訊可以得到 2個資訊:
    
(1)事務1在等待"_sbtest1_new"表的AUTO-INC表鎖;
 
(2)事務2持有"_sbtest1_new"的AUTO-INC表鎖,等待"sbtest1"的記錄鎖。

事務1的replace into語句,明顯是跑pt-osc建立的觸發器產生的,當原表產生記錄更新時,
觸發器並將記錄以replace方式同步到新表。

事務1:
(1)根據條件更新,對sbtest1持有排他的RECORD LOCKS;
(2)更新後觸發器被觸發,再以replace的方式插入_sbtest1_new表,需要對_sbtest1_new持有一個隱式的自增鎖。

事務2:
(1)insert into select from,首先對_sbtest1_new加上了表級的自增鎖;
(2)對新表加上表鎖後,再根據條件中主鍵id的範圍區間去申請原表sbtest1的記錄鎖。

由上,由於事務1先更新原表sbtest1,對更新的記錄加上排它鎖,觸發器還沒觸發時,
事務2開始執行,這個時候事務2現對新表加表鎖,當它再去申請對原表加記錄級別的共享鎖時,
發現部分記錄被加上了排他鎖,所以需要等待。這時事務1觸發器觸發了,需要對新表獲取一個自增鎖,造成了迴環,產生死鎖。