Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 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=COPY,NDB 集群 handler mysqld执行以下操作:

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

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

  • 通知数据节点删除原始表,然后重新命名副本。

我们有时称之为copyingofflineALTER TABLE

在 copying ALTER TABLE期间,不允许并发执行 DML 操作。

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

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

我们还将其称为一个非复制在线ALTER TABLE

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

ALGORITHM=INSTANT在NDB 8.4中不受支持。

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

Note

一些较旧的NDB集群版本使用特定的NDB语法来执行在线ALTER TABLE操作。该语法已经被删除。

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

ALGORITHM=INPLACE 可以用来在NDB表上执行在线ADD COLUMNADD INDEX(包括CREATE INDEX语句)和DROP INDEX操作。在线重命名NDB表也支持。

磁盘基于的列不能在线添加到NDB表中。这意味着,如果您想将内存中的列添加到使用表级别STORAGE DISK选项的NDB表,您必须显式地声明新列使用内存存储。例如—假设您已经创建了表空间ts1— suppose that you create table t1 as follows:

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集群中支持;在MySQL的任何其他版本中,尝试在CREATE TABLEALTER TABLE语句中使用这些关键字将导致错误。

还可以使用语句ALTER TABLE ... REORGANIZE PARTITION, ALGORITHM=INPLACENDB表中没有partition_ names INTO (partition_definitions)选项。这可以用于在线添加新的数据节点到集群中,重新分布NDB集群中的数据。这个操作不会执行任何碎片整理,这需要OPTIMIZE TABLE或空的ALTER TABLE语句。更多信息,请见第25.6.7节,“在线添加NDB集群数据节点”.

不支持在线

Online ALTER TABLE, CREATE INDEX, or DROP INDEX statements that add columns or add or drop indexes are subject to the following limitations:

  • 在线执行的ALTER TABLE语句只能使用其中的一个:ADD COLUMNADD INDEXDROP INDEX。可以在单个语句中添加一个或多个列,但只能在线创建或删除一个索引。

  • 正在被修改的表对API节点中的其他节点没有锁定,除了执行在线ALTER TABLE ADD COLUMNADD INDEXDROP INDEX操作(或CREATE INDEXDROP INDEX语句)时。但是,这个表对来自同一个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关键字,语句将失败并出现错误。

  • 不能在线重新排序现有表列。

对于在线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 Statement”

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

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