MySQL NDB 叢集支援使用 ALTER TABLE ... ALGORITHM=DEFAULT|INPLACE|COPY
進行線上表格綱要變更。NDB 叢集會依據接下來的段落描述處理 COPY
和 INPLACE
。
對於 ALGORITHM=COPY
,mysqld NDB 叢集處理常式會執行以下動作
告知資料節點建立表格的空白複本,並對此複本進行必要的綱要變更。
從原始表格讀取列,並將其寫入複本。
告知資料節點捨棄原始表格,然後重新命名複本。
我們有時將此稱為「複製」或「離線」 ALTER TABLE
。
在執行複製 ALTER TABLE
時,不允許同時執行 DML 操作。
發出複製 ALTER TABLE
陳述式的 mysqld 會取得中繼資料鎖定,但這僅對該 mysqld 有效。其他 NDB
用戶端可以在複製 ALTER TABLE
期間修改列資料,導致不一致。
對於 ALGORITHM=INPLACE
,NDB 叢集處理常式會告知資料節點進行必要的變更,且不會執行任何資料複製。
我們也將此稱為「非複製」或「線上」 ALTER TABLE
。
非複製 ALTER TABLE
允許並行 DML 操作。
NDB 8.4 不支援 ALGORITHM=INSTANT
。
無論使用何種演算法,mysqld 在執行 ALTER TABLE 時都會取得全域綱要鎖定 (GSL);這會阻止在叢集中此或其他 SQL 節點上同時執行任何 (其他) DDL 或備份。這通常不會有問題,除非 ALTER TABLE
花費很長時間。
某些較舊的 NDB 叢集版本使用 NDB
專有的語法,用於線上 ALTER TABLE
操作。該語法已移除。
在 NDB
表格的變寬欄位上新增和捨棄索引的操作會線上進行。線上操作為非複製;也就是說,它們不需要重新建立索引。它們不會鎖定正在變更的表格,使其無法被 NDB 叢集中其他 API 節點存取 (但請參閱本節稍後的NDB 線上操作的限制)。這類操作不需要在具有多個 API 節點的 NDB 叢集中,針對 NDB
表格變更使用單一使用者模式;交易可以在線上 DDL 操作期間不中斷地繼續進行。
ALGORITHM=INPLACE
可用於在 NDB
表格上執行線上 ADD COLUMN
、ADD INDEX
(包括 CREATE INDEX
陳述式) 和 DROP INDEX
操作。也支援線上重新命名 NDB
表格。
無法在線上將磁碟式欄位新增至 NDB
表格。這表示,如果您想要將記憶體中欄位新增至使用表格層級 STORAGE DISK
選項的 NDB
表格,則必須明確宣告新的欄位使用記憶體式儲存。例如,假設您已建立表格空間 ts1
,則假設您按如下方式建立表格 t1
mysql> CREATE TABLE t1 (
> c1 INT NOT NULL PRIMARY KEY,
> c2 VARCHAR(30)
> )
> TABLESPACE ts1 STORAGE DISK
> ENGINE NDB;
Query OK, 0 rows affected (1.73 sec)
Records: 0 Duplicates: 0 Warnings: 0
您可以使用以下方式,將新的記憶體中欄位新增至此表格
mysql> ALTER TABLE t1
> ADD COLUMN c3 INT COLUMN_FORMAT DYNAMIC STORAGE MEMORY,
> ALGORITHM=INPLACE;
Query OK, 0 rows affected (1.25 sec)
Records: 0 Duplicates: 0 Warnings: 0
如果省略 STORAGE MEMORY
選項,則此陳述式會失敗
mysql> ALTER TABLE t1
> ADD COLUMN c4 INT COLUMN_FORMAT DYNAMIC,
> ALGORITHM=INPLACE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason:
Adding column(s) or add/reorganize partition not supported online. Try
ALGORITHM=COPY.
如果您省略 COLUMN_FORMAT DYNAMIC
選項,則會自動採用動態欄位格式,但會發出警告,如下所示
mysql> ALTER ONLINE TABLE t1 ADD COLUMN c4 INT STORAGE MEMORY;
Query OK, 0 rows affected, 1 warning (1.17 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Warning
Code: 1478
Message: DYNAMIC column c4 with STORAGE DISK is not supported, column will
become FIXED
mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`c1` int(11) NOT NULL,
`c2` varchar(30) DEFAULT NULL,
`c3` int(11) /*!50606 STORAGE MEMORY */ /*!50606 COLUMN_FORMAT DYNAMIC */ DEFAULT NULL,
`c4` int(11) /*!50606 STORAGE MEMORY */ DEFAULT NULL,
PRIMARY KEY (`c1`)
) /*!50606 TABLESPACE ts_1 STORAGE DISK */ ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.03 sec)
STORAGE
和 COLUMN_FORMAT
關鍵字僅在 NDB 叢集中支援;在任何其他版本的 MySQL 中,嘗試在 CREATE TABLE
或 ALTER TABLE
陳述式中使用其中一個關鍵字會導致錯誤。
也可以將陳述式 ALTER TABLE ... REORGANIZE PARTITION, ALGORITHM=INPLACE
與沒有
選項一起用於 partition_names
INTO (partition_definitions
)NDB
表格。這可用於在線上新增至叢集的新資料節點之間重新分配 NDB 叢集資料。這不會執行任何解碎片,這需要 OPTIMIZE TABLE
或 Null ALTER TABLE
陳述式。如需更多資訊,請參閱第 25.6.7 節「線上新增 NDB 叢集資料節點」。
NDB 線上操作的限制
不支援線上 DROP COLUMN
操作。
新增欄位或新增或捨棄索引的線上 ALTER TABLE
、CREATE INDEX
或 DROP INDEX
陳述式受以下限制約束
指定的線上
ALTER TABLE
只能使用ADD COLUMN
、ADD INDEX
或DROP INDEX
其中之一。可以在單一陳述式中線上新增一個或多個欄位;在單一陳述式中只能線上建立或捨棄一個索引。除了執行線上
ALTER TABLE
ADD COLUMN
、ADD INDEX
或DROP INDEX
操作 (或CREATE INDEX
或DROP INDEX
陳述式) 的 API 節點之外,正在變更的表格不會針對其他 API 節點鎖定。但是,當線上操作正在執行時,表格會針對源自相同 API 節點的任何其他操作鎖定。要變更的表格必須具有明確的主索引鍵;
NDB
儲存引擎建立的隱藏主索引鍵不足以用於此目的。無法在線上變更表格使用的儲存引擎。
無法在線上變更表格使用的表格空間。明確禁止諸如
ALTER TABLE
之類的陳述式。ndb_table
... ALGORITHM=INPLACE, TABLESPACE=new_tablespace
當與 NDB 叢集磁碟資料表格搭配使用時,無法在線上變更欄位的儲存類型 (
DISK
或MEMORY
)。這表示,當您新增或捨棄索引的方式會使操作線上執行,且您想要變更欄位或數個欄位的儲存類型時,您必須在新增或捨棄索引的陳述式中使用ALGORITHM=COPY
。
線上新增的欄位不能使用 BLOB
或 TEXT
類型,且必須符合以下準則
這些欄位必須是動態的;也就是說,必須可以使用
COLUMN_FORMAT DYNAMIC
來建立它們。如果您省略COLUMN_FORMAT DYNAMIC
選項,則會自動採用動態欄位格式。這些欄位必須允許
NULL
值,且除了NULL
之外,不得有任何明確的預設值。線上新增的欄位會自動建立為DEFAULT NULL
,如下所示mysql> CREATE TABLE t2 ( > c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY > ) ENGINE=NDB; Query OK, 0 rows affected (1.44 sec) mysql> ALTER TABLE t2 > ADD COLUMN c2 INT, > ADD COLUMN c3 INT, > ALGORITHM=INPLACE; Query OK, 0 rows affected, 2 warnings (0.93 sec) mysql> SHOW CREATE TABLE t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t2` ( `c1` int(11) NOT NULL AUTO_INCREMENT, `c2` int(11) DEFAULT NULL, `c3` int(11) DEFAULT NULL, PRIMARY KEY (`c1`) ) ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
新增欄位時,必須接在任何現有欄位之後。如果您嘗試在任何現有欄位之前線上新增欄位,或使用
FIRST
關鍵字,則該陳述式將會失敗並產生錯誤。現有資料表欄位無法線上重新排序。
對於 ALTER TABLE
線上操作於 NDB
資料表時,固定格式欄位會在線上新增時,或線上建立或刪除索引時,轉換為動態格式,如下所示(為了清楚起見,重複顯示剛才的 CREATE TABLE
和 ALTER TABLE
陳述式)
mysql> CREATE TABLE t2 (
> c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY
> ) ENGINE=NDB;
Query OK, 0 rows affected (1.44 sec)
mysql> ALTER TABLE t2
> ADD COLUMN c2 INT,
> ADD COLUMN c3 INT,
> ALGORITHM=INPLACE;
Query OK, 0 rows affected, 2 warnings (0.93 sec)
mysql> SHOW WARNINGS;
*************************** 1. row ***************************
Level: Warning
Code: 1478
Message: Converted FIXED field 'c2' to DYNAMIC to enable online ADD COLUMN
*************************** 2. row ***************************
Level: Warning
Code: 1478
Message: Converted FIXED field 'c3' to DYNAMIC to enable online ADD COLUMN
2 rows in set (0.00 sec)
只有要線上新增的欄位必須是動態的。現有欄位不需要,這包括資料表的主鍵,也可以是 FIXED
,如下所示
mysql> CREATE TABLE t3 (
> c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY COLUMN_FORMAT FIXED
> ) ENGINE=NDB;
Query OK, 0 rows affected (2.10 sec)
mysql> ALTER TABLE t3 ADD COLUMN c2 INT, ALGORITHM=INPLACE;
Query OK, 0 rows affected, 1 warning (0.78 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW WARNINGS;
*************************** 1. row ***************************
Level: Warning
Code: 1478
Message: Converted FIXED field 'c2' to DYNAMIC to enable online ADD COLUMN
1 row in set (0.00 sec)
欄位不會透過重新命名操作,從 FIXED
轉換為 DYNAMIC
欄位格式。有關 COLUMN_FORMAT
的更多資訊,請參閱 第 15.1.20 節,「CREATE TABLE 陳述式」。
在使用 ALGORITHM=INPLACE
的 ALTER TABLE
陳述式中,支援 KEY
、CONSTRAINT
和 IGNORE
關鍵字。
不允許使用線上 ALTER TABLE
陳述式將 MAX_ROWS
設定為 0。您必須使用複製 ALTER TABLE
來執行此操作。(錯誤編號 #21960004)