Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Online Operations with ALTER TABLE in NDB Cluster

25.6.12 NDB 集群中 ALTER TABLE 的在线操作

MySQL NDB 集群支持使用 ALTER TABLE ... ALGORITHM=DEFAULT|INPLACE|COPY 进行在线表模式更改。NDB 集群按照以下几段落所述处理 COPYINPLACE

对于 ALGORITHM=COPYmysqld NDB 集群处理器执行以下操作:

  • 告诉数据节点创建一个空的表副本,并对该副本进行所需的模式更改。

  • 从原始表中读取行,并将其写入副本中。

  • 告诉数据节点删除原始表,然后重命名副本。

我们有时将其称为 复制离线 ALTER TABLE

DML 操作不能与复制 ALTER TABLE 并发执行。

在其中执行复制 ALTER TABLE 语句的 mysqld 获取元数据锁,但这仅对该 mysqld 有效。其他 NDB 客户端可以在复制 ALTER TABLE 期间修改行数据,从而导致不一致。

对于 ALGORITHM=INPLACE,NDB 集群处理器告诉数据节点进行所需的更改,不执行任何数据复制。

我们也将其称为 非复制在线 ALTER TABLE

非复制 ALTER TABLE 允许并发 DML 操作。

ALGORITHM=INSTANT 不受 NDB 8.3 支持。

无论使用哪种算法,mysqld 在执行 ALTER TABLE 时获取全局模式锁(GSL);这将阻止在该集群中的任何 SQL 节点上执行其他 DDL 或备份操作。这通常不是问题,除非 ALTER TABLE 耗费很长时间。

Note

某些较旧的 NDB 集群版本使用了特定于 NDB 的在线 ALTER TABLE 操作语法。该语法现已被删除。

NDB 表上添加和删除变宽列索引的操作在线进行。在线操作是非复制的,即不需要重新创建索引。它们不锁定被修改的表,以便其他 API 节点在 NDB 集群中访问(但请参阅 NDB 在线操作的限制,本节后面)。这些操作不需要单用户模式来对 NDB 集群中的 NDB 表进行修改;事务可以在在线 DDL 操作期间不间断地继续。

ALGORITHM=INPLACE 可以用于在 NDB 表上执行在线 ADD COLUMNADD 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)
Note

关键字STORAGECOLUMN_FORMAT仅在NDB Cluster中支持;在任何其他版本的MySQL中,尝试在CREATE TABLEALTER TABLE语句中使用这些关键字将导致错误。

也可以使用语句ALTER TABLE ... REORGANIZE PARTITION, ALGORITHM=INPLACE在NDB表上,不带partition_names INTO (partition_definitions)选项。这可以在线重新分布NDB Cluster数据到新增加的数据节点中。这不执行任何碎片整理,需要OPTIMIZE TABLE或空ALTER TABLE语句。有关更多信息,请参阅第25.6.7节,“在线添加NDB Cluster数据节点”

NDB在线操作限制

在线DROP COLUMN操作不受支持。

在线ALTER TABLECREATE INDEXDROP INDEX语句添加列或添加或删除索引受以下限制:

  • 给定的在线ALTER TABLE只能使用一个ADD COLUMNADD INDEXDROP INDEX。一个或多个列可以在线添加到单个语句中;只有一个索引可以在线创建或删除在单个语句中。

  • 被修改的表不锁定对其他API节点的访问,除了执行在线ALTER TABLE ADD COLUMNADD INDEXDROP INDEX操作(或CREATE INDEXDROP INDEX语句)所在的API节点。然而,该表锁定对同一个API节点上的其他操作。

  • 要修改的表必须有一个明确的主键;由NDB存储引擎创建的隐藏主键不足以满足这个目的。

  • 表的存储引擎不能在线更改。

  • 表空间不能在线更改。语句如ALTER TABLE ndb_table ... ALGORITHM=INPLACE, TABLESPACE=new_tablespace被明确禁止。

  • 当使用NDB Cluster Disk Data表时,无法在线更改列的存储类型(DISKMEMORY)。这意味着,当你在线添加或删除索引时,如果你想更改列或列的存储类型,你必须在添加或删除索引的语句中使用ALGORITHM=COPY

在线添加的列不能使用BLOBTEXT类型,并且必须满足以下条件:

  • 列必须是动态的,即可以使用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 TABLEALTER 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 语句”

ALTER TABLE 语句中支持 KEYCONSTRAINTIGNORE 关键字,使用 ALGORITHM=INPLACE

使用在线 ALTER TABLE 语句将 MAX_ROWS 设置为 0 是不允许的。您必须使用复制 ALTER TABLE 来执行此操作。(Bug #21960004)