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
如下所示
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 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
,如下所示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
关键字,则该语句将失败并出现错误。无法在线重新排序现有表列。
对于 NDB
表的在线 ALTER TABLE
操作,当它们在线添加或在线创建或删除索引时,固定格式列将转换为动态列,如下所示(为了清楚起见,重复显示了前面显示的 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 语句”。
KEY
、CONSTRAINT
和 IGNORE
关键字在使用 ALGORITHM=INPLACE
的 ALTER TABLE
语句中受支持。
使用在线 ALTER TABLE
语句将 MAX_ROWS
设置为 0 是不允许的。您必须使用复制 ALTER TABLE
来执行此操作。(错误 #21960004)