MySQL NDB Cluster 使用 ALTER TABLE ... ALGORITHM=DEFAULT|INPLACE|COPY
支持在线表模式更改。NDB Cluster 处理 COPY
和 INPLACE
,如接下来的几段所述。
对于 ALGORITHM=COPY
,mysqld NDB Cluster 处理程序执行以下操作
告诉数据节点创建表的空副本,并对该副本进行所需的模式更改。
从原始表中读取行,并将它们写入副本。
告诉数据节点删除原始表,然后重命名副本。
我们有时将其称为 “复制” 或 “脱机” ALTER TABLE
。
DML 操作不允许与复制 ALTER TABLE
同时执行。
发出复制 ALTER TABLE
语句的 mysqld 获取元数据锁,但这仅在该 mysqld 上生效。其他 NDB
客户端可以在复制 ALTER TABLE
期间修改行数据,从而导致不一致。
对于 ALGORITHM=INPLACE
,NDB Cluster 处理程序告诉数据节点进行所需的更改,并且不执行任何数据复制。
我们也将其称为 “非复制” 或 “在线” ALTER TABLE
。
非复制 ALTER TABLE
允许并发 DML 操作。
ALGORITHM=INSTANT
不受 NDB 8.4 支持。
无论使用何种算法,mysqld 在执行 ALTER TABLE 时都会获取全局模式锁 (GSL);这会阻止在集群中的此 SQL 节点或任何其他 SQL 节点上同时执行任何 (其他) DDL 或备份。这通常不会出现问题,除非 ALTER TABLE
耗时很长。
NDB Cluster 的一些较旧版本使用特定于 NDB
的语法进行在线 ALTER TABLE
操作。该语法现已删除。
在 NDB
表的可变宽度列上添加和删除索引的操作在线进行。在线操作是非复制的;也就是说,它们不需要重新创建索引。它们不会锁定正在修改的表,使其无法被 NDB Cluster 中的其他 API 节点访问(但请参阅本节后面的 NDB 在线操作的限制)。此类操作不需要在具有多个 API 节点的 NDB 集群中进行 NDB
表的修改的单用户模式;事务可以在在线 DDL 操作期间继续不间断地进行。
ALGORITHM=INPLACE
可用于在 NDB
表上执行在线 ADD COLUMN
、ADD INDEX
(包括 CREATE INDEX
语句)和 DROP INDEX
操作。还支持在线重命名 NDB
表。
无法在线将基于磁盘的列添加到 NDB
表中。这意味着,如果要将内存中列添加到使用表级 STORAGE DISK
选项的 NDB
表中,则必须显式声明新列使用基于内存的存储。例如,假设您已创建表空间 ts1
,则创建表 t1
如下所示
Press CTRL+C to copymysql> 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
您可以按照此处所示在线将新内存中列添加到该表中
Press CTRL+C to copymysql> 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
选项,则该语句将失败
Press CTRL+C to copymysql> 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
选项,则会自动采用动态列格式,但会发出警告,如下所示
Press CTRL+C to copymysql> 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 Cluster 中受支持;在 MySQL 的任何其他版本中,尝试在 CREATE TABLE
或 ALTER TABLE
语句中使用这两个关键字都会导致错误。
也可以在 NDB
表上使用语句 ALTER TABLE ... REORGANIZE PARTITION, ALGORITHM=INPLACE
,且没有
选项。这可用于将 NDB Cluster 数据重新分配到在线添加到集群中的新数据节点。这不会执行任何碎片整理,碎片整理需要 partition_names
INTO (partition_definitions
)OPTIMIZE TABLE
或空 ALTER TABLE
语句。有关更多信息,请参阅 第 25.6.7 节,“在线添加 NDB Cluster 数据节点”。
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 节点的任何其他操作被锁定。要修改的表必须具有显式主键;
NDB
存储引擎创建的隐藏主键不足以满足此目的。无法在线更改表使用的存储引擎。
无法在线更改表使用的表空间。例如,
ALTER TABLE
这样的语句被明确禁止。ndb_table
... ALGORITHM=INPLACE, TABLESPACE=new_tablespace
当与 NDB Cluster 磁盘数据表一起使用时,无法在线更改列的存储类型 (
DISK
或MEMORY
)。这意味着,当您添加或删除索引时,如果操作将在线执行,并且您希望更改列或列的存储类型,则必须在添加或删除索引的语句中使用ALGORITHM=COPY
。
无法在线添加要在线添加的列,这些列不能使用 BLOB
或 TEXT
类型,并且必须满足以下条件
列必须是动态的;也就是说,必须能够使用
COLUMN_FORMAT DYNAMIC
创建它们。如果省略COLUMN_FORMAT DYNAMIC
选项,则会自动采用动态列格式。列必须允许
NULL
值,并且除了NULL
之外不能有任何显式默认值。在线添加的列会自动创建为DEFAULT NULL
,如下所示Press CTRL+C to copymysql> 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
关键字,则该语句将失败并出现错误。无法在线重新排序现有表列。
对于 NDB
表的在线 ALTER TABLE
操作,当它们在线添加或在线创建或删除索引时,固定格式列将转换为动态列,如下所示(为了清楚起见,重复显示了前面显示的 CREATE TABLE
和 ALTER TABLE
语句)
Press CTRL+C to copymysql> 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
主键,如下所示
Press CTRL+C to copymysql> 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 语句”。
KEY
、CONSTRAINT
和 IGNORE
关键字在使用 ALGORITHM=INPLACE
的 ALTER TABLE
语句中受支持。
使用在线 ALTER TABLE
语句将 MAX_ROWS
设置为 0 是不允许的。您必须使用复制 ALTER TABLE
来执行此操作。(错误 #21960004)