文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  NDB 集群中使用 ALTER TABLE 进行在线操作

25.6.12 NDB 集群中使用 ALTER TABLE 进行在线操作

MySQL NDB 集群支持使用 ALTER TABLE ... ALGORITHM=DEFAULT|INPLACE|COPY 进行在线表结构更改。NDB 集群处理 COPYINPLACE 的方式如下几段所述。

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

  • 指示数据节点创建表的空副本,并对该副本进行所需的架构更改。

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

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

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

复制 ALTER TABLE 时,不允许同时进行 DML 操作。

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

对于 ALGORITHM=INPLACE,NDB 集群处理程序指示数据节点进行所需的更改,并且不执行任何数据复制。

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

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

NDB 9.0 不支持 ALGORITHM=INSTANT

无论使用哪种算法,mysqld 在执行 ALTER TABLE 时都会获取全局架构锁 (GSL);这可以防止在集群中的此 SQL 节点或任何其他 SQL 节点上同时执行任何(其他)DDL 或备份。除非 ALTER TABLE 需要很长时间,否则这通常不会有问题。

注意

某些旧版本的 NDB 集群对 NDB 使用特定语法来进行在线 ALTER TABLE 操作。该语法现已删除。

NDB 表的可变宽度列上添加和删除索引的操作是在线进行的。在线操作是非复制的;也就是说,它们不需要重新创建索引。它们不会锁定正在被 NDB 集群中的其他 API 节点访问的表(但请参阅本节后面的 NDB 在线操作的限制)。此类操作不需要在具有多个 API 节点的 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)
注意

STORAGECOLUMN_FORMAT 关键字仅在 NDB 集群中受支持;在任何其他版本的 MySQL 中,尝试在 CREATE TABLEALTER TABLE 语句中使用这两个关键字中的任何一个都会导致错误。

还可以对 NDB 表使用语句 ALTER TABLE ... REORGANIZE PARTITION, ALGORITHM=INPLACE,而不使用 partition_names INTO (partition_definitions) 选项。这可用于在新数据节点之间重新分配 NDB 集群数据,这些数据节点已在线添加到集群中。这不会执行任何碎片整理,这需要 OPTIMIZE TABLE 或空 ALTER TABLE 语句。有关更多信息,请参阅 第 25.6.7 节“在线添加 NDB 集群数据节点”

NDB 在线操作的限制

不支持在线 DROP COLUMN 操作。

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

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

  • 正在更改的表没有针对除运行在线 ALTER TABLE ADD COLUMNADD INDEXDROP INDEX 操作(或 CREATE INDEXDROP INDEX 语句)之外的 API 节点锁定的。但是,在执行在线操作时,该表会针对源自相同 API 节点的任何其他操作锁定。

  • 要更改的表必须具有显式主键;NDB 存储引擎创建的隐藏主键不足以达到此目的。

  • 无法在线更改表使用的存储引擎。

  • 无法在线更改表使用的表空间。明确禁止使用诸如 ALTER TABLE ndb_table ... ALGORITHM=INPLACE, TABLESPACE=new_tablespace 之类的语句。

  • 与 NDB 集群磁盘数据表一起使用时,无法在线更改列的存储类型(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 关键字在线添加列,则该语句将失败并返回错误。

  • 无法在线对现有表列重新排序。

对于 NDB 表的在线 ALTER TABLE 操作,当在线添加固定格式的列或在线创建或删除索引时,它们将转换为动态格式,如下所示(为清楚起见,重复显示 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 语句”

使用 ALGORITHM=INPLACEALTER TABLE 语句支持 KEYCONSTRAINTIGNORE 关键字。

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