Mysql

ALTER TABLE 在具有索引列的大表上

  • March 1, 2018

我有一個帶有 VARCHAR(20) 列的大表,我需要將其修改為 VARCHAR(50) 列。通常,在此特定表上執行 ALTER TABLE(添加 TINYINT)大約需要 90-120 分鐘才能完成,因此我只能在周六或週日晚上執行此操作,以免影響數據庫使用者。如果可能的話,我想在那之前做這個修改。

該列也被索引,我認為這會使 ALTER TABLE 變慢,因為它必須在修改列長度後重建索引。

Web 應用程序設置在 MySQL 複製環境(26 個從屬和一個主控)中。我記得有一次在某處讀到一種方法是首先在每個從屬伺服器上執行 ALTER TABLE(最大限度地減少對使用者的影響),然後在主伺服器上執行此操作,但那不會嘗試將 ALTER TABLE 命令複製到從屬伺服器嗎?

所以我的問題是:對我來說,在對使用者造成最小干擾的情況下修改此表的最佳方法是什麼?

編輯:該表是 InnoDB。

如果您有點冒險精神,您可以通過在您可以看到的階段執行 ALTER TABLE 來處理事情。假設您要更改的表稱為 WorkingTable。您可以像這樣分階段執行更改:

#
#  Script 1
#  Alter table structure of a single column of a large table
#
CREATE TABLE WorkingTableNew LIKE WorkingTable;
ALTER TABLE WorkingTableNew MODIFY BigColumn VARCHAR(50);
INSERT INTO WorkingTableNew SELECT * FROM WorkingTable;
ALTER TABLE WorkingTable RENAME WorkingTableOld;
ALTER TABLE WorkingTableNew RENAME WorkingTable;
DROP TABLE WorkingTableOld;

您可以在所有從站上執行此操作。主人呢???你如何防止這種情況復製到從屬伺服器。簡單:不要將 SQL 發送到 master 的二進制日誌中。只需在執行 ALTER TABLE 之前關閉會話中的二進制日誌記錄:

#
#  Script 2
#  Alter table structure of a single column of a large table
#  while preventing it from replicating to slaves
#
SET SQL_LOG_BIN = 0;
CREATE TABLE WorkingTableNew LIKE WorkingTable;
ALTER TABLE WorkingTableNew MODIFY BigColumn VARCHAR(50);
INSERT INTO WorkingTableNew SELECT SQL_NO_CACHE * FROM WorkingTable;
ALTER TABLE WorkingTable RENAME WorkingTableOld;
ALTER TABLE WorkingTableNew RENAME WorkingTable;
DROP TABLE WorkingTableOld;

可是等等 !!!處理這些命令時出現的任何新數據呢???在操作開始時重命名表應該可以解決問題。讓我們稍微修改一下這段程式碼,以防止在這方面輸入新數據:

#
#  Script 3
#  Alter table structure of a single column of a large table
#  while preventing it from replicating to slaves
#  and preventing new data from entering into the old table
#
SET SQL_LOG_BIN = 0;
ALTER TABLE WorkingTable RENAME WorkingTableOld;
CREATE TABLE WorkingTableNew LIKE WorkingTableOld;
ALTER TABLE WorkingTableNew MODIFY BigColumn VARCHAR(50);
INSERT INTO WorkingTableNew SELECT SQL_NO_CACHE * FROM WorkingTableOld;
ALTER TABLE WorkingTableNew RENAME WorkingTable;
DROP TABLE WorkingTableOld;
  • 腳本 1 可以在任何未啟用二進制日誌的從站上執行
  • 腳本 2 可以在啟用了二進制日誌的任何從站上執行
  • 腳本 3 可以在 master 或其他任何地方執行

試一試 !!!

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