### 23.6.11 使用 NDB Cluster 中的 ALTER TABLE 进行在线操作

MySQL NDB Cluster 8.0 支持使用标准的在线表模式更改[`更改表`](alter-table.html)MySQL 服务器使用的语法 (`算法=默认|插入|复制`)，并在别处描述。

笔记

一些旧版本的 NDB Cluster 使用特定于[`新开发银行`](mysql-cluster.html)在线`更改表`操作。该语法已被删除。

在可变宽度列上添加和删除索引的操作[`新开发银行`](mysql-cluster.html)表在线发生。在线操作是非复制的；也就是说，它们不需要重新创建索引。它们不会锁定正在被 NDB Cluster 中其他 API 节点访问的表（但请参阅[NDB 在线操作的局限性](mysql-cluster-online-operations.html#mysql-cluster-online-limitations)，在本节后面）。此类操作不需要单用户模式[`新开发银行`](mysql-cluster.html)在具有多个 API 节点的 NDB 集群中进行的表更改；在线 DDL 操作期间，事务可以不间断地继续。

`算法=就地`可用于在线执行`添加列`,`添加索引`（包含`创建索引`声明），和`删除索引`上的操作[`新开发银行`](mysql-cluster.html)表。网上改名[`新开发银行`](mysql-cluster.html)也支持表格。

以前，列`新开发银行`无法在线重命名表；NDB 8.0 中删除了此限制。

目前您无法将基于磁盘的列添加到[`新开发银行`](mysql-cluster.html)在线表。这意味着，如果您希望将内存中的列添加到[`新开发银行`](mysql-cluster.html)使用表级的表`存储磁盘`选项，您必须将新列显式声明为使用基于内存的存储。例如——假设您已经创建了表空间`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
```

如果`存储内存`选项被省略：

```
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 动态`选项，自动采用动态列格式，但会发出警告，如下所示：

```
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=latin1
1 row in set (0.03 sec)
```

笔记

这`贮存`和`COLUMN_FORMAT`关键字仅在 NDB Cluster 中受支持；在任何其他版本的 MySQL 中，尝试在[`创建表`](create-table.html)要么[`更改表`](alter-table.html)语句导致错误。

也可以使用语句`ALTER TABLE ...重组​​分区，算法=INPLACE`没有`*`分区名称`* 进入 （*`分区定义`*)`选项开启[`新开发银行`](mysql-cluster.html)表。这可用于在已在线添加到集群的新数据节点之间重新分配 NDB Cluster 数据。这确实*不是*执行任何碎片整理，这需要[`优化表`](optimize-table.html)或为空[`更改表`](alter-table.html)陈述。有关详细信息，请参阅[第 23.6.7 节，“在线添加 NDB Cluster 数据节点”](mysql-cluster-online-add-node.html).

#### NDB 在线操作的局限性

在线的`删除列`不支持操作。

在线的[`更改表`](alter-table.html),[`创建索引`](create-index.html)， 要么[`删除索引`](drop-index.html)添加列或添加或删除索引的语句受到以下限制：

-   给定的在线[`更改表`](alter-table.html)只能使用其中之一`添加列`,`添加索引`， 要么`删除索引`.可以在单个语句中在线添加一个或多个列；在单个语句中只能在线创建或删除一个索引。

-   正在更改的表未针对 API 节点锁定，而在线节点除外[`更改表`](alter-table.html) `添加列`,`添加索引`， 要么`删除索引`操作（或[`创建索引`](create-index.html)要么[`删除索引`](drop-index.html)语句）运行。但是，该表被锁定以防止源自该表的任何其他操作。*相同的*执行在线操作时的 API 节点。

-   要更改的表必须具有显式主键；由创建的隐藏主键[`新开发银行`](mysql-cluster.html)存储引擎不足以实现此目的。

-   表使用的存储引擎不能在线更改。

-   表使用的表空间不能在线更改。从 NDB 8.0.21 开始，语句如[`更改表 *`ndb_table`* ...算法=插入，表空间=*`新表空间`*`](alter-table.html)是特别不允许的。（错误 #99269、错误 #31180526）

-   与 NDB Cluster 磁盘数据表一起使用时，无法更改存储类型 (`磁盘`要么`记忆`) 的在线专栏。这意味着，当您以在线执行操作的方式添加或删除索引时，并且您希望更改列的存储类型时，您必须使用`算法=复制`在添加或删除索引的语句中。

    在线添加的列不能使用[`斑点`](blob.html)要么[`文本`](blob.html)类型，并且必须满足以下条件：

-   列必须是动态的；也就是说，必须可以使用`COLUMN_FORMAT 动态`.如果你省略`COLUMN_FORMAT 动态`选项，自动采用动态列格式。

-   列必须允许`空值`值并且没有任何明确的默认值，除了`空值`.在线添加的列会自动创建为`默认空`, 可以在这里看到：

    ```
    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=latin1
    1 row in set (0.00 sec)
    ```

-   这些列必须添加到任何现有列之后。如果您尝试在任何现有列之前在线添加列或使用`第一的`关键字，语句失败并出现错误。

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

    对于在线[`更改表`](alter-table.html)上的操作[`新开发银行`](mysql-cluster.html)表中，固定格式的列在在线添加或在线创建或删除索引时会转换为动态列，如此处所示（重复`创建表`和`更改表`只是为了清楚起见而显示的陈述）：


```
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)
```

只有要在线添加的列必须是动态的。现有列不必；这包括表的主键，也可能是`固定的`，如此处所示：

```
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)
```

列不转换自`固定的`到`动态的`列格式通过重命名操作。有关更多信息`COLUMN_FORMAT`， 看[第 13.1.20 节，“CREATE TABLE 语句”](create-table.html).

这`钥匙`,`约束`， 和`忽视`支持关键字[`更改表`](alter-table.html)语句使用`算法=就地`.

环境`MAX_ROWS`到 0 使用在线`更改表`声明是不允许的。您必须使用复制`更改表`来执行此操作。（缺陷号 21960004）
