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  /  ...  /  Setting NDB Comment Options

15.1.20.12 设置 NDB 注释选项

在 NDB Cluster 中,可以在表注释或列注释中设置多个特定于 NDB Cluster 的选项。可以在表注释中使用 NDB_TABLE 选项来控制读取任意副本和分区平衡。

NDB_COLUMN 可以在列注释中使用,以设置 blob 部分表列的大小,以存储 blob 值的部分由 NDB 存储的最大值。这适用于 BLOBMEDIUMBLOBLONGBLOBTEXTMEDIUMTEXTLONGTEXTJSON 列。列注释也可以用于控制 blob 列的内联大小。NDB_COLUMN 注释不支持 TINYBLOBTINYTEXT 列,因为这些列只有固定大小的内联部分,没有单独的部分存储在其他地方。

NDB_TABLE 可以在表注释中使用,以设置与分区平衡和表是否完全复制相关的选项。

本节的其余部分将描述这些选项及其使用。

NDB_COLUMN 选项

在 NDB Cluster 中,可以在 CREATE TABLEALTER TABLE 语句中使用列注释来指定 NDB_COLUMN 选项。NDB 支持两个列注释选项 BLOB_INLINE_SIZEMAX_BLOB_PART_SIZE。这些选项的语法如下所示:

COMMENT 'NDB_COLUMN=speclist'

speclist := spec[,spec]

spec := 
    BLOB_INLINE_SIZE=value
  | MAX_BLOB_PART_SIZE[={0|1}]

BLOB_INLINE_SIZE 指定了列中要存储的内联字节数;其预期值是一个介于 1 到 29980 之间的整数,包括这两个值。如果设置的值大于 29980,将引发错误;如果设置的值小于 1,则将使用该列类型的默认内联大小。

您应该注意,这个选项的最大值实际上是 NDB 表中一行可以存储的最大字节数;每个列都贡献了这个总数。

您还应该牢记,特别是在使用 TEXT 列时,MAX_BLOB_PART_SIZEBLOB_INLINE_SIZE 设置的值表示列的字节大小,而不是字符数,这取决于该列使用的字符集和排序规则。

要查看这个选项的效果,首先创建一个具有两个 BLOB 列的表,其中一个 (b1) 不带额外选项,另一个 (b2) 带有 BLOB_INLINE_SIZE 设置,如下所示:

mysql> CREATE TABLE t1 (
    ->    a INT NOT NULL PRIMARY KEY,
    ->    b1 BLOB,
    ->    b2 BLOB COMMENT 'NDB_COLUMN=BLOB_INLINE_SIZE=8000'
    ->  ) ENGINE NDB;
Query OK, 0 rows affected (0.32 sec)

您可以通过查询 ndbinfo.blobs 表来查看 BLOB 列的 BLOB_INLINE_SIZE 设置,如下所示:

mysql> SELECT 
    ->   column_name AS 'Column Name', 
    ->   inline_size AS 'Inline Size', 
    ->   part_size AS 'Blob Part Size' 
    -> FROM ndbinfo.blobs 
    -> WHERE table_name = 't1';
+-------------+-------------+----------------+
| Column Name | Inline Size | Blob Part Size |
+-------------+-------------+----------------+
| b1          |         256 |           2000 |
| b2          |        8000 |           2000 |
+-------------+-------------+----------------+
2 rows in set (0.01 sec)

您还可以检查 ndb_desc 实用程序的输出,如下所示,其中相关行使用加粗文本显示:

$> ndb_desc -d test t1
-- t --
Version: 1
Fragment type: HashMapPartition
K Value: 6
Min load factor: 78
Max load factor: 80
Temporary table: no
Number of attributes: 3
Number of primary keys: 1
Length of frm data: 945
Max Rows: 0
Row Checksum: 1
Row GCI: 1
SingleUserMode: 0
ForceVarPart: 1
PartitionCount: 2
FragmentCount: 2
PartitionBalance: FOR_RP_BY_LDM
ExtraRowGciBits: 0
ExtraRowAuthorBits: 0
TableStatus: Retrieved
Table options: readbackup
HashMap: DEFAULT-HASHMAP-3840-2
-- Attributes --
a Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
b1 Blob(256,2000,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_64_1
b2 Blob(8000,2000,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_64_2
-- Indexes -- 
PRIMARY KEY(a) - UniqueHashIndex
PRIMARY(a) - OrderedIndex

NDBT_ProgramExit: 0 - OK

对于 MAX_BLOB_PART_SIZE= 号和其后的值是可选的。使用任何不是 0 或 1 的值将导致语法错误。

使用 MAX_BLOB_PART_SIZE 在列注释中的效果是将 TEXTBLOB 列的 blob 部分大小设置为 NDB 支持的最大字节数(13948)。这个选项可以应用于 MySQL 支持的任何 blob 列类型,除了 TINYBLOBTINYTEXTBLOBMEDIUMBLOBLONGBLOBTEXTMEDIUMTEXTLONGTEXT)。与 BLOB_INLINE_SIZE 不同,MAX_BLOB_PART_SIZEJSON 列没有影响。

要查看此选项的效果,我们首先在 mysql 客户端中运行以下 SQL 语句,以创建一个具有两个 BLOB 列的表,一个 (c1) 不带额外选项,另一个 (c2) 带有 MAX_BLOB_PART_SIZE

mysql> CREATE TABLE test.t2 (
    ->   p INT PRIMARY KEY, 
    ->   c1 BLOB, 
    ->   c2 BLOB COMMENT 'NDB_COLUMN=MAX_BLOB_PART_SIZE'
    -> ) ENGINE NDB;
Query OK, 0 rows affected (0.32 sec)

从系统 shell 中,运行 ndb_desc 实用程序,以获取刚刚创建的表的信息,如下所示:

$> ndb_desc -d test t2
-- t --
Version: 1
Fragment type: HashMapPartition
K Value: 6
Min load factor: 78
Max load factor: 80
Temporary table: no
Number of attributes: 3
Number of primary keys: 1
Length of frm data: 324
Row Checksum: 1
Row GCI: 1
SingleUserMode: 0
ForceVarPart: 1
FragmentCount: 2
ExtraRowGciBits: 0
ExtraRowAuthorBits: 0
TableStatus: Retrieved
HashMap: DEFAULT-HASHMAP-3840-2
-- Attributes --
p Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
c1 Blob(256,2000,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_22_1
c2 Blob(256,13948,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_22_2
-- Indexes -- 
PRIMARY KEY(p) - UniqueHashIndex
PRIMARY(p) - OrderedIndex

输出中的列信息在 Attributes 下列出;对于列 c1c2,它显示在这里,以加粗文本形式显示。对于 c1,blob 部分大小为 2000,默认值;对于 c2,它是 13948,由 MAX_BLOB_PART_SIZE 设置。

您也可以查询 ndbinfo.blobs 表以查看此信息,如下所示:

mysql> SELECT 
    ->   column_name AS 'Column Name', 
    ->   inline_size AS 'Inline Size', 
    ->   part_size AS 'Blob Part Size' 
    -> FROM ndbinfo.blobs 
    -> WHERE table_name = 't2';
+-------------+-------------+----------------+
| Column Name | Inline Size | Blob Part Size |
+-------------+-------------+----------------+
| c1          |         256 |           2000 |
| c2          |         256 |          13948 |
+-------------+-------------+----------------+
2 rows in set (0.00 sec)

您可以使用 ALTER TABLE 语句更改给定 blob 列的 blob 部分大小,例如这样一个语句,并使用 SHOW CREATE TABLE 验证更改:

mysql> ALTER TABLE test.t2 
    ->    DROP COLUMN c1, 
    ->     ADD COLUMN c1 BLOB COMMENT 'NDB_COLUMN=MAX_BLOB_PART_SIZE',
    ->     CHANGE COLUMN c2 c2 BLOB AFTER c1;
Query OK, 0 rows affected (0.47 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE test.t2\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t2` (
  `p` int(11) NOT NULL,
  `c1` blob COMMENT 'NDB_COLUMN=MAX_BLOB_PART_SIZE',
  `c2` blob,
  PRIMARY KEY (`p`)
) ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql> EXIT
Bye

输出 ndb_desc 显示 blob 列的 blob 部分大小已经如预期那样更改:

$> ndb_desc -d test t2
-- t --
Version: 16777220
Fragment type: HashMapPartition
K Value: 6
Min load factor: 78
Max load factor: 80
Temporary table: no
Number of attributes: 3
Number of primary keys: 1
Length of frm data: 324
Row Checksum: 1
Row GCI: 1
SingleUserMode: 0
ForceVarPart: 1
FragmentCount: 2
ExtraRowGciBits: 0
ExtraRowAuthorBits: 0
TableStatus: Retrieved
HashMap: DEFAULT-HASHMAP-3840-2
-- Attributes --
p Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
c1 Blob(256,13948,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_26_1
c2 Blob(256,2000,0) NULL AT=MEDIUM_VAR ST=MEMORY BV=2 BT=NDB$BLOB_26_2
-- Indexes -- 
PRIMARY KEY(p) - UniqueHashIndex
PRIMARY(p) - OrderedIndex

NDBT_ProgramExit: 0 - OK

您也可以通过再次运行对 ndbinfo.blobs 的查询来查看更改:

mysql> SELECT 
    ->   column_name AS 'Column Name', 
    ->   inline_size AS 'Inline Size', 
    ->   part_size AS 'Blob Part Size' 
    -> FROM ndbinfo.blobs 
    -> WHERE table_name = 't2';
+-------------+-------------+----------------+
| Column Name | Inline Size | Blob Part Size |
+-------------+-------------+----------------+
| c1          |         256 |          13948 |
| c2          |         256 |           2000 |
+-------------+-------------+----------------+
2 rows in set (0.00 sec)

可以同时设置 BLOB_INLINE_SIZEMAX_BLOB_PART_SIZE 对于 blob 列,如下所示的 CREATE TABLE 语句:

mysql> CREATE TABLE test.t3 (
    ->   p INT NOT NULL PRIMARY KEY,
    ->   c1 JSON,
    ->   c2 JSON COMMENT 'NDB_COLUMN=BLOB_INLINE_SIZE=5000,MAX_BLOB_PART_SIZE'
    -> ) ENGINE NDB;
Query OK, 0 rows affected (0.28 sec)

查询 blobs 表显示语句工作正常:

mysql> SELECT 
    ->   column_name AS 'Column Name', 
    ->   inline_size AS 'Inline Size', 
    ->   part_size AS 'Blob Part Size' 
    -> FROM ndbinfo.blobs 
    -> WHERE table_name = 't3';
+-------------+-------------+----------------+
| Column Name | Inline Size | Blob Part Size |
+-------------+-------------+----------------+
| c1          |        4000 |           8100 |
| c2          |        5000 |           8100 |
+-------------+-------------+----------------+
2 rows in set (0.00 sec)

您也可以通过检查 ndb_desc 的输出来验证语句的工作:

必须使用复制 ALTER TABLE 来更改列的 blob 部分大小;无法在线执行此操作(见 第 25.6.12 节,“NDB 集群中的在线操作”)。

有关 NDB 存储 blob 类型列的更多信息,请参阅 字符串类型存储要求

NDB_TABLE 选项

对于 NDB 集群表,在 CREATE TABLEALTER TABLE 语句中,表注释也可以用于指定 NDB_TABLE 选项,该选项由一个或多个名称-值对组成,使用逗号分隔,如果需要,紧跟在字符串 NDB_TABLE= 之后。完整的名称和值语法如下所示:

COMMENT="NDB_TABLE=ndb_table_option[,ndb_table_option[,...]]"

ndb_table_option: {
    NOLOGGING={1 | 0}
  | READ_BACKUP={1 | 0}
  | PARTITION_BALANCE={FOR_RP_BY_NODE | FOR_RA_BY_NODE | FOR_RP_BY_LDM
                      | FOR_RA_BY_LDM | FOR_RA_BY_LDM_X_2
                      | FOR_RA_BY_LDM_X_3 | FOR_RA_BY_LDM_X_4}
  | FULLY_REPLICATED={1 | 0}
}

引号字符串中不允许出现空格。该字符串不区分大小写。

在接下来的几段中,将详细描述可以作为注释的一部分设置的四个 NDB 表选项。

NOLOGGING:默认情况下,NDB 表被记录并检查点。这使它们对整个集群故障具有持久性。使用 NOLOGGING 创建或修改表时,意味着该表不被 redo 记录或包含在本地检查点中。在这种情况下,该表仍然在数据节点之间复制以实现高可用性,并使用事务更新,但对其所做的更改不记录在数据节点的 redo 日志中,也不将其内容检查点到磁盘上;在从集群故障恢复时,集群保留表定义,但没有行,即表为空。

使用这种非日志表可以减少数据节点对磁盘 I/O 和存储的需求,以及检查点 CPU。这可能适合生命周期短暂、频繁更新的数据,而在极少数集群故障事件中,数据丢失是可接受的。

也可以使用ndb_table_no_logging系统变量来使在该变量生效期间创建或修改的 NDB 表像使用 NOLOGGING 注释一样。与直接使用注释不同的是,在这种情况下,SHOW CREATE TABLE 的输出中没有任何内容表明它是一个非日志表。建议使用表注释方法,因为它提供了每个表的控制功能,并且该表模式的一部分嵌入到表创建语句中,可以被 SQL 基于工具轻松地找到。

READ_BACKUP:将该选项设置为 1 将具有与启用 ndb_read_backup 相同的效果;启用从任何副本读取。这样做将大大提高表的读取性能,而写入性能的代价相对较小。1 是 READ_BACKUP 的默认值,而 ndb_read_backup 的默认值是 ON(之前,默认情况下,从任何副本读取是禁用的)。

您可以在线上设置现有表的 READ_BACKUP,使用类似于以下之一的 ALTER TABLE 语句:

ALTER TABLE ... ALGORITHM=INPLACE, COMMENT="NDB_TABLE=READ_BACKUP=1";

ALTER TABLE ... ALGORITHM=INPLACE, COMMENT="NDB_TABLE=READ_BACKUP=0";

有关 ALTER TABLEALGORITHM 选项的更多信息,请参阅 第 25.6.12 节,“NDB 集群中的在线操作 ALTER TABLE”

PARTITION_BALANCE:提供了对分区的分配和放置的附加控制。支持以下四种方案:

  1. FOR_RP_BY_NODE:每个节点一个分区。

    每个节点上的一个 LDM 存储一个主分区。每个分区在所有节点上的同一个 LDM(同一个 ID)中存储。

  2. FOR_RA_BY_NODE:每个节点组一个分区。

    每个节点存储一个分区,可以是主副本或备份副本。每个分区在所有节点上的同一个 LDM 中存储。

  3. FOR_RP_BY_LDM:每个节点上的每个 LDM 一个分区;默认设置。

    如果 READ_BACKUP 设置为 1,则使用此设置。

  4. FOR_RA_BY_LDM:每个节点组中的每个 LDM 一个分区。

    这些分区可以是主分区或备份分区。

  5. FOR_RA_BY_LDM_X_2:每个节点组中的LDM中有两个分区。

    这些分区可以是主分区或备份分区。

  6. FOR_RA_BY_LDM_X_3:每个节点组中的LDM中有三个分区。

    这些分区可以是主分区或备份分区。

  7. FOR_RA_BY_LDM_X_4:每个节点组中的LDM中有四个分区。

    这些分区可以是主分区或备份分区。

PARTITION_BALANCE 是设置每个表的分区数的首选接口。使用 MAX_ROWS 强制设置分区数已经弃用,但为了向后兼容性继续支持;它可能在未来版本的 MySQL NDB Cluster 中被删除。(Bug #81759, Bug #23544301)

FULLY_REPLICATED 控制表是否完全复制,即每个数据节点是否拥有表的完整副本。要启用表的完全复制,请使用 FULLY_REPLICATED=1

此设置也可以使用 ndb_fully_replicated 系统变量控制。将其设置为 ON 可以默认启用该选项 для所有新的 NDB 表;默认值为 OFFndb_data_node_neighbour 系统变量也用于完全复制的表,以确保当访问完全复制的表时,我们访问的是本地的数据节点。

下面是一个使用注释创建 NDB 表的 CREATE TABLE 语句示例:

mysql> CREATE TABLE t1 (
     >     c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
     >     c2 VARCHAR(100),
     >     c3 VARCHAR(100) )
     > ENGINE=NDB
     >
COMMENT="NDB_TABLE=READ_BACKUP=0,PARTITION_BALANCE=FOR_RP_BY_NODE";

该注释将作为 SHOW CREATE TABLE 输出的一部分显示。该注释的文本也可以从查询 MySQL 信息模式 TABLES 表中获得,如下所示:

mysql> SELECT TABLE_NAME, TABLE_SCHEMA, TABLE_COMMENT
     > FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME="t1"\G
*************************** 1. row ***************************
   TABLE_NAME: t1
 TABLE_SCHEMA: test
TABLE_COMMENT: NDB_TABLE=READ_BACKUP=0,PARTITION_BALANCE=FOR_RP_BY_NODE
1 row in set (0.01 sec)

该注释语法也支持 ALTER TABLE 语句用于 NDB 表,如下所示:

mysql> ALTER TABLE t1 COMMENT="NDB_TABLE=PARTITION_BALANCE=FOR_RA_BY_NODE";
Query OK, 0 rows affected (0.40 sec)
Records: 0  Duplicates: 0  Warnings: 0

TABLE_COMMENT 列显示了重新创建表所需的注释,类似于 ALTER TABLE 语句后的注释:

mysql> SELECT TABLE_NAME, TABLE_SCHEMA, TABLE_COMMENT
    ->     FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME="t1"\G
*************************** 1. row ***************************
   TABLE_NAME: t1
 TABLE_SCHEMA: test
TABLE_COMMENT: NDB_TABLE=READ_BACKUP=0,PARTITION_BALANCE=FOR_RP_BY_NODE
1 row in set (0.01 sec)
mysql> SELECT TABLE_NAME, TABLE_SCHEMA, TABLE_COMMENT
     > FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME="t1";
+------------+--------------+--------------------------------------------------+
| TABLE_NAME | TABLE_SCHEMA | TABLE_COMMENT                                    |
+------------+--------------+--------------------------------------------------+
| t1         | c            | NDB_TABLE=PARTITION_BALANCE=FOR_RA_BY_NODE       |
| t1         | d            |                                                  |
+------------+--------------+--------------------------------------------------+
2 rows in set (0.01 sec)

请注意,使用 ALTER TABLE 语句的表注释将替换表可能拥有的任何现有注释。

mysql> ALTER TABLE t1 COMMENT="NDB_TABLE=PARTITION_BALANCE=FOR_RA_BY_NODE";
Query OK, 0 rows affected (0.40 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SELECT TABLE_NAME, TABLE_SCHEMA, TABLE_COMMENT
     > FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME="t1";
+------------+--------------+--------------------------------------------------+
| TABLE_NAME | TABLE_SCHEMA | TABLE_COMMENT                                    |
+------------+--------------+--------------------------------------------------+
| t1         | c            | NDB_TABLE=PARTITION_BALANCE=FOR_RA_BY_NODE       |
| t1         | d            |                                                  |
+------------+--------------+--------------------------------------------------+
2 rows in set (0.01 sec)

您也可以在 ndb_desc 的输出中看到 PARTITION_BALANCE 选项的值。ndb_desc 也显示表是否设置了 READ_BACKUPFULLY_REPLICATED 选项。请参阅该程序的描述以获取更多信息。