參考文章: http://seanlook.com/2016/05/27/mysql-pt-online-schema-change/mysql
上面的文章寫的很詳細,在這篇文章中,想要再補充一些本身的理解。sql
1、在原表建立的三個觸發器,在copy數據時,如何保證數據的一致?
- insert:在原表發生insert時,同時也會將數據插入新表;
- update:使用於replace……into的方式,若新表中沒有該數據,則觸發插入數據,若新表中已有該數據,則將舊數據刪除,插入更新的數據。可是replace……into只能應用於表中有主鍵或惟一鍵時使用,不然replace……into會和insert同樣,沒法實現更新的功能。
- delete:在新表中無相關數據,就刪完原表數據,觸發器會忽略在觸發器內部定義的delete語句,若新表中早已複製了數據,則就出發刪除該數據。具體解釋:
- create trigger db_tb_del after delete on db.tb for each row delete ignore from db._tb_new where db._tb_new.id <=> OLD.id;刪除觸發器操是使用after delete,即先執行刪除,再觸發刪除觸發器,執行觸發器中定義的SQL(該SQL的含義爲:在where條件中,若新表的id 等於 上步delete操做原表的id,則執行該delete語句,若不符合條件,則忽略刪除這條語句);
2、在線DDL的幾種選擇
在MySQL5.6中,在線DDL的效率很低,有時會嚴重鎖表,percona中的pt-osc能夠較高效率的作在線DDL,可是注意pt-osc的使用限制。工具
- 在一個表中符合如下任意條件的狀況,都沒法使用pt-osc:
- 表中沒有主鍵或惟一鍵;
- 表中已存在觸發器;
- 表中有外鍵
- 判斷是否可使用MySQL5.6 原生的在線DDL:
- 建立一個和原表相同結構的表,導入少許數據,執行想要操做的DDL,檢查「rows affected」是否爲0,若爲0,則可使用,若非零,則意味着該操做會重建整個表,不可以使用。
- 在沒法使用pt-osc工具,並且原生的在線DDL也嚴重影響業務時,還有一種辦法:
- 在從庫上執行DDL,而後將從庫升級爲主庫,再在舊主庫上DDL。