• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • NDB群集中使用ALTER TABLE进行的在线操作

    MySQL NDB Cluster 8.0支持使用ALTER TABLEMySQL Server(ALGORITHM=DEFAULT|INPLACE|COPY)所采用的标准语法对在线表架构进行更改,并在其他地方进行了描述。

    注意

    NDB Cluster的某些较旧版本使用特定NDB于在线ALTER TABLE操作的语法。此语法已被删除。

    NDB表的可变宽度列上添加和删除索引的操作在线发生。在线操作不可复制;也就是说,它们不需要重新创建索引。它们不会锁定NDB群集中其他API节点无法访问的正在更改的表(但请参阅本节后面的NDB在线操作的局限性)。对于NDB在具有多个API节点的NDB集群中进行的表更改,此类操作不需要单用户模式;在线DDL操作期间,事务可以不间断地继续进行。

    ALGORITHM=INPLACE可用于对表进行在线ADD COLUMNADD INDEX(包括CREATE INDEX语句)和DROP INDEX操作NDBNDB还支持表的在线重命名。

    以前,表的列NDB不能在线重命名;NDB 8.0.18中删除了此限制。

    当前,您无法将基于磁盘的列添加到NDB在线表中。这意味着,如果希望将内存列添加到NDB使用表级STORAGE DISK选项的表中,则必须将新列声明为显式使用基于内存的存储。例如,假设您已经创建了表空间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=latin1
    1 row in set (0.03 sec)
    
    注意

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

    也可以在表上ALTER TABLE ... REORGANIZE PARTITION, ALGORITHM=INPLACE使用不带任何选项的语句。这可用于在已在线添加到群集的新数据节点之间重新分配NDB群集数据。这并没有执行任何碎片整理,这需要一个或空语句。有关更多信息,请参见“在线添加NDB群集数据节点”。partition_names INTO(partition_definitions)NDBOPTIMIZE TABLEALTER TABLE

    NDB在线操作的局限性

    DROP COLUMN不支持在线操作。

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

    • 一个网上给出ALTER TABLE只能使用一个ADD COLUMNADD INDEXDROP INDEX。可以在一个语句中在线添加一个或多个列;在一个语句中只能在线创建或删除一个索引。
    • 正在修改的表是不是相对于一个比其他API节点锁定在其网上,或操作(或或运行语句)。但是,在执行联机操作时,该表被锁定以防止源自同一 API节点的任何其他操作。ALTER TABLEADD COLUMNADD INDEXDROP INDEXCREATE INDEXDROP INDEX
    • 要更改的表必须具有显式主键;NDB为此,存储引擎创建的隐藏主键是不够的。
    • 该表使用的存储引擎无法在线更改。
    • 与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=latin1
      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)
    

    重命名操作不会FIXEDDYNAMIC列从列格式转换为列格式。有关的更多信息COLUMN_FORMAT,请参见“ CREATE TABLE语句”。

    KEYCONSTRAINTIGNORE关键字都以支持ALTER TABLEusing语句ALGORITHM=INPLACE

    禁止MAX_ROWS使用在线ALTER TABLE语句将其设置为0 。您必须使用复制ALTER TABLE来执行此操作。