Mysql

在不停機的情況下更改大表

  • August 13, 2017

我有一個非常大的表,讓我們呼叫它example,然後我嘗試在該表上執行一些更改命令:

ALTER TABLE `example` ADD `example_column` TINYINT(1) NOT NULL DEFAULT 0;

檢查 alter 命令的進度:

mysql -e 'show engine innodb status \G' | grep 'undo \| log \| entries'

給我很好的資訊,關於時間 - 或多或少需要 17 天才能完成……

更改阻塞表,因此阻塞生產表 17 天不是一個好的選擇。;)

我嘗試在網上調查一些很棒的工具,例如:

  1. Pt-online-schema-change - Percona
  2. gh-ost - GitHub 的 MySQL 線上模式遷移

我還閱讀了文件,以及上述工具的限制部分:

幽靈限制

  • 根本不支持觸發器
  • 根本不支持外鍵

pt-online-schema-change 限制

  • 觸發器的使用意味著如果表上已經定義了任何觸發器,則該工具將無法工作。
  • 不提供任何更改包含外鍵的表的好方法

我的範例表有觸發器和外鍵……

你能給我一些建議,如何處理這個改變?

我有 MySQL 5.6。我使用 GTID(基於行)複製。

我將非常感謝您的建議!

你最好像這樣執行 ALTER TABLE

ALTER TABLE `example` ADD `example_column` TINYINT(1) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;

有什麼好處?定義預設值為 is 的列NULL不會嘗試增加行的大小。對於VARCHAR. 老實說,我不確定這是否適用於數字。(INT、TINYINT 等)。您需要對此進行測試(我在 2 年前提到過對此進行測試(InnoDB 是否允許將列添加到具有並發 READ/WRITE 行的表中?))。因此,不應該有停機時間。

這樣做的缺點是更改您的軟體以處理NULL數字列。

如果您擔心外鍵,請事先在會話中將其關閉

SET foreign_key_checks = 0;
ALTER TABLE `example` ADD `example_column` TINYINT(1) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;

如果您有觸發器並且可以在載入期間沒有它,請放下觸發器,執行ALTER TABLE並重新創建觸發器。

警告:確保您使用的是最新版本的 MySQL 5.6(至少 5.6.23)以避免ALTER TABLE.

請注意,我沒有提到使用第三方工具。這只是直接的 MySQL。

試一試 !!!

零停機時間、觸發器或 FK 或複制等沒有問題怎麼樣?

好的,有一個問題。您將創建另一個表來包含 PK 和新列。需要新列的查詢需要進行 JOIN。但是,在某些情況下,這並不是一個嚴重的缺點。

而且,JOIN通常需要LEFT JOIN這樣才能NULL在(還沒有)新列的值時獲得。

使用與原始表相同的 PK 列創建新表,但沒有AUTO_INCREMENT. 在新表中有新列。

引用自:https://dba.stackexchange.com/questions/182330