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


25.6.11.1 NDB 集群磁盘数据对象

NDB 集群磁盘数据存储使用以下对象实现:

  • 表空间(Tablespace):作为其他磁盘数据对象的容器。一个表空间包含一个或多个数据文件和一个或多个undo日志文件组。

  • 数据文件(Data file):存储列数据。数据文件直接分配给表空间。

  • Undo日志文件(Undo log file):包含回滚事务所需的undo信息。分配给undo日志文件组。

  • 日志文件组(log file group):包含一个或多个undo日志文件。分配给表空间。

Undo日志文件和数据文件是每个数据节点的文件系统中的实际文件;默认情况下,它们将被放置在ndb_node_id_fs中,指定在NDB 集群config.ini文件中的DataDir路径中,其中node_id是数据节点的节点ID。可以通过在创建undo日志或数据文件时指定绝对或相对路径来将它们放置到其他位置。后续在本节中显示这些语句。

Undo日志文件仅供磁盘数据表使用,不需要或不用于存储在内存中的NDB表。

NDB 集群表空间和日志文件组不是文件实现的。

虽然不是所有磁盘数据对象都实现为文件,但是它们共享同一个命名空间。这意味着每个磁盘数据对象必须具有唯一的名称(而不仅是给定类型中的每个磁盘数据对象)。例如,你不能同时拥有一个表空间和日志文件组, ambos 命名为dd1.

假设你已经设置了包含管理节点、SQL 节点的 NDB 集群,然后创建 NDB 集群表在磁盘上的基本步骤如下:

  1. 创建一个日志文件组,并将一个或多个回滚日志文件分配给它(回滚日志文件也称为undofile)。

  2. 创建一个表空间;将日志文件组,以及一个或多个数据文件,分配给表空间。

  3. 创建一个磁盘数据表,该表使用该表空间来存储数据。

这些任务可以使用在mysql客户端或其他 MySQL 客户端应用程序中执行 SQL 语句,例如以下示例所示。

  1. 我们使用CREATE LOGFILE GROUP 创建一个名为 lg_1 的日志文件组。这个日志文件组将由两个回滚日志文件组成,我们将其命名为 undo_1.logundo_2.log,初始大小分别为 16 MB 和 12 MB。 (默认的初始大小为 128 MB。) 可选地,您也可以指定日志文件组的回滚缓冲区的大小或让其采用默认值 8 MB。在这个示例中,我们将 UNDO 缓冲区的大小设置为 2 MB。一个日志文件组必须包含至少一个回滚日志文件,所以我们在这个CREATE LOGFILE GROUP 语句中添加 undo_1.loglg_1

    CREATE LOGFILE GROUP lg_1
        ADD UNDOFILE 'undo_1.log'
        INITIAL_SIZE 16M
        UNDO_BUFFER_SIZE 2M
        ENGINE NDBCLUSTER;

    要将 undo_2.log 添加到日志文件组中,请使用以下ALTER LOGFILE GROUP 语句:

    ALTER LOGFILE GROUP lg_1
        ADD UNDOFILE 'undo_2.log'
        INITIAL_SIZE 12M
        ENGINE NDBCLUSTER;

    需要注意的一些事项:

    • 在这里使用的 .log 文件扩展名不是必需的。我们只是为了使日志文件易于识别而使用它。

    • 每个CREATE LOGFILE GROUPALTER LOGFILE GROUP语句都必须包含一个ENGINE选项。该选项的唯一允许值是NDBCLUSTERNDB

      Important

      在同一个 NDB 集群中,至多只能存在一个日志文件组。

    • 当您使用DataDir中的ndb_node_id_fs目录在每个数据节点中创建一个 undo 日志文件时,文件名将是filename。每个 undo 日志文件的大小由 SQL 语句指定。例如,如果 NDB 集群有 4 个数据节点,那么上面显示的ALTER LOGFILE GROUP语句创建了 4 个 undo 日志文件,每个文件在每个数据节点的数据目录中,文件名为undo_2.log,每个文件大小为 12 MB。

    • UNDO_BUFFER_SIZE受系统内存可用量限制。

    • 请查看第15.1.16节,“CREATE LOGFILE GROUP 语句”第15.1.6节,“ALTER LOGFILE GROUP 语句”,了解这些语句的更多信息。

  2. 现在我们可以创建一个表空间—an abstract container for files used by Disk Data tables to store data。一个表空间与特定的日志文件组相关联;在创建新表空间时,您必须指定用于undo日志记录的日志文件组。您还需要至少指定一个数据文件;您可以在表空间创建后添加更多数据文件。也可以从表空间中删除数据文件(请参阅本节后面的示例)。

    假设我们想创建一个名为ts_1的表空间,该表空间使用lg_1作为其日志文件组。我们想要该表空间包含两个数据文件,名为data_1.datdata_2.dat,初始大小分别为32 MB和48 MB(默认值为128 MB)。我们可以使用以下两个SQL语句来实现:

    CREATE TABLESPACE ts_1
        ADD DATAFILE 'data_1.dat'
        USE LOGFILE GROUP lg_1
        INITIAL_SIZE 32M
        ENGINE NDBCLUSTER;
    
    ALTER TABLESPACE ts_1
        ADD DATAFILE 'data_2.dat'
        INITIAL_SIZE 48M;

    CREATE TABLESPACE语句创建一个名为ts_1的表空间,包含数据文件data_1.dat,并将ts_1与日志文件组lg_1相关联。ALTER TABLESPACE语句添加第二个数据文件(data_2.dat)。

    一些需要注意的项目:

    • 与在本示例中用于undo日志文件的.log文件扩展名一样,.dat文件扩展名没有特别的意义;它仅用于易于识别。

    • 使用ADD DATAFILE 'filename'将数据文件添加到表空间时,会在每个数据节点的DataDir目录中创建一个名为filename的文件,where node_id是数据节点的节点ID。每个数据文件的大小将根据SQL语句指定。例如,如果NDB集群有4个数据节点,那么上面显示的ALTER TABLESPACE语句创建了4个数据文件,每个文件在对应的4个数据节点的数据目录中,各文件名为data_2.dat,每个文件大小为48MB。

    • NDB保留了每个表空间的4%用于数据节点重启时使用。这部分空间不可用来存储数据。

    • CREATE 表空间 语句必须包含一个ENGINE子句;只能在使用相同存储引擎的表空间中创建表。对于NDB表空间,ALTER 表空间 仅在ALTER 表空间 ... ADD DATAFILE中接受一个ENGINE子句,对于任何其他ALTER 表空间语句,ENGINE将被拒绝。对于NDB表空间,ENGINE选项的唯一允许值是NDBCLUSTERNDB.

    • 对给定表空间中的所有数据文件执行extent分配操作,以轮询方式。

    • 有关CREATE 表空间ALTER 表空间语句的更多信息,请见第15.1.21节,“CREATE 表空间语句”,和第15.1.10节,“ALTER 表空间语句”.

  3. 现在可以创建一个表,其中未索引的列存储在磁盘上,使用表空间ts_1中的文件:

    CREATE TABLE dt_1 (
        member_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        last_name VARCHAR(50) NOT NULL,
        first_name VARCHAR(50) NOT NULL,
        dob DATE NOT NULL,
        joined DATE NOT NULL,
        INDEX(last_name, first_name)
        )
        TABLESPACE ts_1 STORAGE DISK
        ENGINE NDBCLUSTER;

    TABLESPACE ts_1 STORAGE DISK 告诉NDB存储引擎使用表空间ts_1在磁盘上进行数据存储。

    一旦创建了表ts_1,您可以像对任何其他 MySQL 表一样执行INSERTSELECTUPDATEDELETE语句。

    还可以使用STORAGE子句在CREATE TABLEALTER TABLE语句中定义列的定义中指定某个列是否存储在磁盘上或内存中。STORAGE DISK将导致该列被存储在磁盘上,而STORAGE MEMORY将导致使用内存存储。请参阅第15.1.20节,“CREATE TABLE 语句”,了解更多信息。

您可以通过查询 INFORMATION_SCHEMA 数据库中的 FILES 表来获取关于 NDB 硬盘数据文件和undo日志文件的信息,示例如下:

mysql> SELECT
              FILE_NAME AS File, FILE_TYPE AS Type,
              TABLESPACE_NAME AS Tablespace, TABLE_NAME AS Name,
              LOGFILE_GROUP_NAME AS 'File group',
              FREE_EXTENTS AS Free, TOTAL_EXTENTS AS Total
          FROM INFORMATION_SCHEMA.FILES
          WHERE ENGINE='ndbcluster';
+--------------+----------+------------+------+------------+------+---------+
| File         | Type     | Tablespace | Name | File group | Free | Total   |
+--------------+----------+------------+------+------------+------+---------+
| ./undo_1.log | UNDO LOG | lg_1       | NULL | lg_1       |    0 | 4194304 |
| ./undo_2.log | UNDO LOG | lg_1       | NULL | lg_1       |    0 | 3145728 |
| ./data_1.dat | DATAFILE | ts_1       | NULL | lg_1       |   32 |      32 |
| ./data_2.dat | DATAFILE | ts_1       | NULL | lg_1       |   48 |      48 |
+--------------+----------+------------+------+------------+------+---------+
4 rows in set (0.00 sec)

更多信息和示例,请见第28.3.15节,“INFORMATION_SCHEMA FILES 表”

磁盘上的列索引隐式存储.  对于前面示例中定义的表 dt_1,只有 dobjoined 列被存储在磁盘上。这是因为对 idlast_namefirst_name 列的索引已经存在,因此这些列的数据存储在 RAM 中。只有未索引的列可以被存储在磁盘上;索引和索引列数据继续存储在内存中。这是 Disk Data 表设计时需要考虑的权衡:索引使用与 RAM 保持的平衡。

您不能将已明确声明为STORAGE DISK的列添加索引,除非首先将其存储类型更改为MEMORY;任何尝试这样做都会失败并出现错误。隐式使用磁盘存储的列可以被索引;当这样做时,该列的存储类型将自动更改为MEMORY。在这里,我们称之为“隐式”,指的是父表中未声明存储类型,但继承自父表的列。在以下CREATE TABLE语句(使用之前定义的表空间ts_1)中,列c2c3隐式使用磁盘存储:

mysql> CREATE TABLE ti (
    ->     c1 INT PRIMARY KEY,
    ->     c2 INT,
    ->     c3 INT,
    ->     c4 INT
    -> )
    ->     STORAGE DISK
    ->     TABLESPACE ts_1
    ->     ENGINE NDBCLUSTER;
Query OK, 0 rows affected (1.31 sec)

因为c2c3c4本身没有声明为STORAGE DISK,因此可以对它们进行索引。这里,我们使用CREATE INDEXALTER TABLE分别添加索引到c2c3

mysql> CREATE INDEX i1 ON ti(c2);
Query OK, 0 rows affected (2.72 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE ti ADD INDEX i2(c3);
Query OK, 0 rows affected (0.92 sec)
Records: 0  Duplicates: 0  Warnings: 0

SHOW CREATE TABLE 确认了索引已经添加。

mysql> SHOW CREATE TABLE ti\G
*************************** 1. row ***************************
       Table: ti
Create Table: CREATE TABLE `ti` (
  `c1` int(11) NOT NULL,
  `c2` int(11) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  `c4` int(11) DEFAULT NULL,
  PRIMARY KEY (`c1`),
  KEY `i1` (`c2`),
  KEY `i2` (`c3`)
) /*!50100 TABLESPACE `ts_1` STORAGE DISK */ ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

您可以使用ndb_desc查看现在使用内存而不是磁盘存储的索引列(强调文本):

$> ./ndb_desc -d test t1
-- t1 --
Version: 33554433
Fragment type: HashMapPartition
K Value: 6
Min load factor: 78
Max load factor: 80
Temporary table: no
Number of attributes: 4
Number of primary keys: 1
Length of frm data: 317
Max Rows: 0
Row Checksum: 1
Row GCI: 1
SingleUserMode: 0
ForceVarPart: 1
PartitionCount: 4
FragmentCount: 4
PartitionBalance: FOR_RP_BY_LDM
ExtraRowGciBits: 0
ExtraRowAuthorBits: 0
TableStatus: Retrieved
Table options:
HashMap: DEFAULT-HASHMAP-3840-4
-- Attributes --
c1 Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
c2 Int NULL AT=FIXED ST=MEMORY
c3 Int NULL AT=FIXED ST=MEMORY
c4 Int NULL AT=FIXED ST=DISK
-- Indexes --
PRIMARY KEY(c1) - UniqueHashIndex
i2(c3) - OrderedIndex
PRIMARY(c1) - OrderedIndex
i1(c2) - OrderedIndex

性能注意.  使用 Disk Data 存储的集群性能将大幅改善,如果 Disk Data 文件与数据节点文件系统分开存储。这必须对每个数据节点进行,以获得明显的性能提高。

您可以使用绝对和相对文件系统路径与ADD UNDOFILEADD DATAFILE ; 相对路径将根据数据节点的数据目录进行计算。

日志文件组、表空间和使用这些的 Disk Data 表必须按照特定的顺序创建。这同样适用于删除这些对象,subject to the following constraints:

  • 不能在任何表空间使用它的情况下删除日志文件组。

  • 不能在包含数据文件的情况下删除表空间。

  • 不能在表空间中有任何表正在使用的情况下删除数据文件。

  • 不能删除与其他表空间相关的文件,除非这些文件是与当前表空间相关的。

例如,要删除到目前为止在本节中创建的所有对象,可以使用以下语句:

mysql> DROP TABLE dt_1;

mysql> ALTER TABLESPACE ts_1
    -> DROP DATAFILE 'data_2.dat';

mysql> ALTER TABLESPACE ts_1
    -> DROP DATAFILE 'data_1.dat';

mysql> DROP TABLESPACE ts_1;

mysql> DROP LOGFILE GROUP lg_1;

这些语句必须按照显示的顺序执行,except that the two ALTER TABLESPACE ... DROP DATAFILE statements may be executed in either order。

Note

NDB 集群的 older 版本使用了ENGINE 子句与 ALTER TABLESPACE ... DROP DATAFILEDROP TABLESPACE。从 NDB 8.4 开始,这些语句在这两个语句中不再支持。