您好,登錄后才能下訂單哦!
在講解pt-osc內(nèi)部處理流程前,我們先通過下面的例子,看看rename交換表后,子表的信息。
--?創(chuàng)建一個(gè)父表 CREATE?TABLE?parent?( id?int(11)?NOT?NULL?auto_increment, parent_id?int, PRIMARY?KEY??(id), KEY?IX_parent_id?(parent_id) )?ENGINE=InnoDB; --?創(chuàng)建一個(gè)子表,外鍵是child_id,和父表parent_id做關(guān)聯(lián) 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; --?把父表改個(gè)名 rename?table?parent?to?parent_1;
此時(shí)子表會(huì)自動(dòng)執(zhí)向新的父表表名,如下面所示:
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
現(xiàn)在我們要向父表添加一個(gè)字段name varchar(200)
用pt-osc工具執(zhí)行,通常內(nèi)部的執(zhí)行過程是:
1)創(chuàng)建一個(gè)臨時(shí)表_parent_new
2)在臨時(shí)表_parent_new中添加name字段
3)在原表parent上定義觸發(fā)器,以便對(duì)原始表上的數(shù)據(jù)所做的更改也將應(yīng)用于臨時(shí)表_parent_new中
4)將數(shù)據(jù)從原表parent復(fù)制到_parent_new。
5)交換名字rename table parent to _parent_old, _parent_new to parent?
6)刪除原表 drop table _parent_old
7)刪除增刪改三個(gè)觸發(fā)器
那么最危險(xiǎn)的是rename交換名字后,子表的外鍵會(huì)執(zhí)向_parent_old,并不會(huì)變成parent,這將帶來數(shù)據(jù)不一致的后果。
固,pt-osc增加了--alter-foreign-keys-method參數(shù),默認(rèn)是drop_swap,它的執(zhí)行過程跟剛才就有些區(qū)別了。
前4步還是一樣,第5步開始,變成
5)set FOREIGN_KEY_CHECKS=OFF; #關(guān)閉外鍵檢查
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)刪除增刪改三個(gè)觸發(fā)器
10)set FOREIGN_KEY_CHECKS=ON;
第7步如果表大,刪除的速度較慢的話(第8步不會(huì)執(zhí)行),業(yè)務(wù)會(huì)受影響,這也是比較危險(xiǎn)的。
如果修改為rebuild_constraints,它的執(zhí)行過程是:
交換名字
rename?table?parent?to?_parent_old,?_parent_new?to?parent
(這一步保持和原先一樣)
1)將子表外鍵刪除,重新關(guān)聯(lián)父表parent
ALTER?TABLE?child?DROP?FOREIGN?KEY?child_id,?ADD?CONSTRAINT?child_ibfk_1?FOREIGN?KEY??(child_id)?REFERENCES?parent?(parent_id)
注:這一步會(huì)采用ALGORITHM=INPLACE算法,不會(huì)鎖表,支持并發(fā)DML。
2)刪除原表 drop table _parent_old
3)刪除增刪改三個(gè)觸發(fā)器
設(shè)置為auto,如果子表中的行數(shù)很少,則使用rebuild_constraints; 否則轉(zhuǎn)換為drop_swap。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。