在講解pt-osc內部處理流程前,咱們先經過下面的例子,看看rename交換表後,子表的信息。算法
-- 建立一個父表 CREATE TABLE parent ( id int(11) NOT NULL auto_increment, parent_id int, PRIMARY KEY (id), KEY IX_parent_id (parent_id) ) ENGINE=InnoDB; -- 建立一個子表,外鍵是child_id,和父表parent_id作關聯 CREATE TABLE child ( id int(11) NOT NULL auto_increment, child_id int(11) default NULL, PRIMARY KEY (id), KEY IX_child_id (child_id), FOREIGN KEY (child_id) REFERENCES parent (parent_id) ) ENGINE=InnoDB; -- 把附表改個名 rename table parent to parent_1;
此時子表會自動執向新的父表表名,以下面所示:bash
show create table child\G CREATE TABLE child ( id int(11) NOT NULL AUTO_INCREMENT, child_id int(11) DEFAULT NULL, PRIMARY KEY (id), KEYI IX_child_id (child_id), CONSTRAINT child_ibfk_1 FOREIGN KEY (child_id) REFERENCES parent_1 (parent_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
好比咱們要向父表添加一個字段name varchar(200)併發
用pt-osc工具執行,一般內部的執行過程是:ide
1)建立一個臨時表_parent_new
2)在臨時表_parent_new中添加name字段
3)在原表parent上定義觸發器,以便對原始表上的數據所作的更改也將應用於臨時表_parent_new中
4)將數據從原表parent複製到_parent_new。
5)交換名字rename table parent to _parent_old, _parent_new to parent
工具
6)刪除原表 drop table _parent_oldui
7)刪除增刪改三個觸發器
rem
那麼最危險的是rename交換名字後,子表的外鍵會執向_parent_old,並不會變成parent,這將帶來數據不一致的後果。it
固,pt-osc增長了--alter-foreign-keys-method參數,默認是drop_swap,它的執行過程跟剛纔就有些區別了。table
前4步仍是同樣,第5步開始,變成class
5)set FOREIGN_KEY_CHECKS=OFF; #關閉外鍵檢查
6)交換名字rename table parent to _parent_old
7)drop table _parent_old
8)交換名字 rename table _parent_new to _parent_old, _parent_old to parent;
9)刪除增刪改三個觸發器
第7步若是表大,刪除的速度較慢的話(第8步不會執行),業務會受影響,這也是比較危險的。
若是修改成rebuild_constraints,它的執行過程是:
交換名字
rename table parent to _parent_old, _parent_new to parent
(這一步保持和原先同樣)
1)將子表外鍵刪除,從新關聯父表parent
ALTER TABLE child DROP FOREIGN KEY child_id, ADD CONSTRAINT child_ibfk_1 FOREIGN KEY (child_id) REFERENCES parent (parent_id)
注:這一步會採用ALGORITHM=INPLACE算法,不會鎖表,支持併發DML。
2)刪除原表 drop table _parent_old
3)刪除增刪改三個觸發器
若是設置爲auto,若是子表中的行數不多,則使用rebuild_constraints; 不然轉換爲drop_swap。