Mysql
大型 MySQL 表的線上模式更改策略
我很想听聽人們在 MySQL 中對非常大的表執行更改時使用的策略和方法。大可以是會影響更改的任意數量的行或大小。為了便於討論,假設有 200 萬行以上的任何更改都會影響正常的應用程序性能。
我看到的兩個主要策略是在從屬設備上執行更改,然後在它完成後將其提升為主控設備,或者創建一個表的副本,其中已經完成了預期的更改,然後複製並趕上數據並在刪除舊的之前進行重命名以將它們換掉。
理想情況下,我正在尋找一種方法來實現後者。我在這裡的一個大問題是表上的觸發器被更改,當然要確保兩個表中的數據在交換之前保持同步。我認為可以通過在過程中的關鍵點使用 read_only 變數來在一定程度上減輕錯誤或失去數據的可能性,以確保在擺弄觸發器時以及在您擷取所有數據之後數據不會發生變化。我知道這會對使用數據庫的應用程序產生影響,但這比冒著損壞數據的風險要好。
我一直在研究這樣做的實用程序和策略,並且有幾個。一個值得注意的是這個,Facebook 用它作為他們線上修改的基礎。: openark 工具封包檔。然後在此處詳細說明該過程:線上模式更改的想法和想法
你對這兩種方法有什麼經驗?你遇到了什麼陷阱和陷阱?你更喜歡/建議哪個,為什麼?
Percona/Maatkit 也有自己的:pt-online-schema-change
我已經使用觸發器方法對超過 1 億行的表進行了線上模式更改,並且效果非常好。
- 創建具有所需結構的新表。
- 將觸發器添加到舊表以將插入的數據複製到新表。它看起來像:
DELIMITER | CREATE TRIGGER original_to_new AFTER INSERT ON original_table FOR EACH ROW BEGIN INSERT INTO new_table SET col1 = NEW.col1, col2 = NEW.col2... END; | DELIMITER ;
- 記下使用觸發器移動到新表的第一個自動增量 id。
- 將舊表中的數據複製到新表中,直到步驟 3 中擷取的 ID。
- 交換錶名。
RENAME original_table TO original_table_backup, new_table TO original_table
- 丟棄舊表