MySQL Cluster篇16 — 磁盘数据表

概述

本章,您将学习 MySQL NDB Cluster 中的磁盘数据表。

磁盘数据表是 ndbcluster 存储引擎下一种表级别的存储属性,主要特点有:

  • 将表的非主键、非索引列数据持久化存储在磁盘文件中
  • 仅将主键和索引字段保留在内存中
  • 占用内存低,可存储海量非索引数据
  • 一种存储数据的折中方案(即用磁盘换内存,用延迟换容量),目的不是为了提升性能,而是缓解内存压力

在 MySQL NDB Cluster 中,与磁盘数据表相对的是内存数据表,两者的对比如下表所示:

特性 内存数据表 磁盘数据表
存储位置 全部数据(含索引)在内存中 仅主键/索引在内存,其余在磁盘
内存占用 高(适用于小型表) 低(可存储海量非索引数据)
适用数据 小字段、高频访问(如用户状态) 大字段、低频访问(如日志、附件)
持久化 节点重启后需重新加载 原生持久化,无需加载
写入吞吐性能 高(适合 OLTP) 低(受磁盘 I/O 限制)
管理复杂度 极低 高(需配置表空间+日志组)

MySQL NDB Cluster 的磁盘数据表使用频率极低,属于边缘性、补丁式功能,仅在特定受限场景下启用。所以大致了解下就好,不要过分深入研究。

磁盘数据对象‌

磁盘数据表的实现依赖以下的‌磁盘数据对象‌(Disk Data Objects),它们共同构成数据持久化层:

  • 表空间(Tablespace) - 表空间的概念以前在 InnoDB 的架构中介绍过 —— 表空间是逻辑层与物理层的中间桥梁,是用户逻辑对象(表、索引等)的存储空间,用来统一管理空间中的数据文件。简单来说,表空间相当于是数据存放的容器。在 MySQL NDB Cluster 中,表空间是其他磁盘数据对象的存放容器。一个表空间包含一个或多个数据文件以及一个或多个撤销日志文件组。
  • 数据文件(Data file) - 用来存储列数据,归属于表空间。
  • 撤销日志文件(Undo log file) - ‌包含用于事务回滚所需的撤销信息,归属于一个撤销日志文件组。
  • 日志文件组(log file group) - 包含一个或多个撤销日志文件,归属于某个表空间。

撤销日志文件和数据文件保存在每个数据节点的文件系统中,默认情况下,其存放路径由管理节点 config.ini 中的 DataDir 参数决定,以 ndb_node_id_fs 目录名称显示(node_id 替换为具体的节点 ID)。

提示
只有那些将数据持久化到磁盘的表,才需要撤销日志来支持事务回滚和崩溃恢复;而完全存储在内存中的表,因为其设计目标是高性能与低延迟,不依赖磁盘持久化机制,所以根本不会使用撤销日志‌。

提示
MySQL NDB Cluster 中的强制规定:‌所有磁盘数据对象必须在整个命名空间中全局唯一,而不仅是同类型内唯一。例如,不能同时存在一个名为 dd1 的表空间和一个名为 dd1 的日志文件组。

要在磁盘上创建使用 ndbcluster 存储引擎的表,其步骤如下:

步骤 1 - 创建日志文件组并为其分配一个或多个 Undo log file
步骤 2 - 创建表空间,并将日志文件组以及一个或多个数据文件分配给该表空间
步骤 3 - 创建磁盘数据表,并指定其使用该表空间进行数据的存储

步骤 1 如下

# 使用任意一个 SQL 服务器(SQL 节点)进行登录
Shell (192.168.100.16)> /usr/local/mysql/bin/mysql -h localhost -u root --password="Google-,Bing500"

# 本示例中,创建了一个 lg_1 的日志文件组且包含了一个 undo_1.log 的撤销日志文件。其中日志文件组的初始大小为 16M,可选的撤销缓冲区为 2M
MySQL > create logfile group lg_1
add undofile 'undo_1.log'
initial_size=16M
undo_buffer_size=2M
engine=ndbcluster;

# 再往 lg_1 日志文件组里添加新的撤销日志文件
## 未指定撤销缓冲区大小,则默认大小为 8M
MySQL > alter logfile group lg_1
add undofile 'undo_2.log'
initial_size=12M
engine=ndbcluster;

注意点:

  • .log 文件后缀并不是强制要求,这里这是为了方便识别
  • 一个 NDB Cluster 中同一时间只能存在一个日志文件组
  • 在创建或修改日志文件组时,若使用了 add undofile之类的语法,则在每个数据服务器(数据节点)的数据目录里的 ndb_node_id_fs 目录会生成对应的文件,其中 node_id 替换为指定的节点 ID
  • 存储引擎必须是 ndbcluster

步骤 2 如下

Shell (192.168.100.16)> /usr/local/mysql/bin/mysql -h localhost -u root --password="Google-,Bing500"

# 创建一个新表空间时,必须指定日志文件组以及至少一个数据文件。创建表空间成功后,您可以继续在表空间中添加更多的数据文件,也可以从表空间中删除数据文件。
MySQL > create tablespace ts_1
add datafile 'data_1.dat'
use logfile group lg_1
initial_size=32M
engine=ndbcluster;

MySQL > alter tablespace ts_1
add datafile 'data_2.dat'
initial_size=48M 
engine=ndbcluster;

注意点:

  • .dat 文件后缀并不是强制要求,这里这是为了方便识别
  • 在创建或修改表空间时,若使用了 add datafile 之类的语法,则在每个数据服务器(数据节点)的数据目录里的 ndb_node_id_fs 目录会生成对应的文件,其中 node_id 替换为指定的节点 ID
  • 存储引擎必须是 ndbcluster

步骤 3 如下


Shell (192.168.100.16)> /usr/local/mysql/bin/mysql -h localhost -u root --password="Google-,Bing500"

MySQL > use db1;

# 创建磁盘数据表。该表中没有索引的列将使用 ts_1 这个表空间。众所周知,主键、外键、唯一约束都会自动生成索引。
# 约束:一种对表中数据进行限制的规则
# 新建表时添加的索引,即普通索引(多列),其中未定义索引名称
MySQL > create table if not exists 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 ;

查看索引信息:

MySQL > show index from db1.dt_1\G;
*************************** 1. row ***************************
        Table: dt_1
   Non_unique: 0
     Key_name: PRIMARY  ←← 这里
 Seq_in_index: 1
  Column_name: member_id  ←← 这里
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
      Visible: YES
   Expression: NULL
*************************** 2. row ***************************
        Table: dt_1
   Non_unique: 1
     Key_name: last_name  ←← 这里
 Seq_in_index: 1          ←← 这里
  Column_name: last_name  ←← 这里
    Collation: A
  Cardinality: NULL
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
      Visible: YES
   Expression: NULL
*************************** 3. row ***************************
        Table: dt_1
   Non_unique: 1
     Key_name: last_name   ←← 这里
 Seq_in_index: 2           ←← 这里
  Column_name: first_name  ←← 这里
    Collation: A
  Cardinality: NULL
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
      Visible: YES
   Expression: NULL
3 rows in set (0.00 sec)

获取磁盘数据表的信息:

MySQL > select 
file_name, file_type, tablespace_name, table_name, logfile_group_name, free_extents, total_extents
from information_schema.files
where engine='ndbcluster';

+--------------+-----------+-----------------+------------+--------------------+--------------+---------------+
| FILE_NAME    | FILE_TYPE | TABLESPACE_NAME | TABLE_NAME | LOGFILE_GROUP_NAME | FREE_EXTENTS | TOTAL_EXTENTS |
+--------------+-----------+-----------------+------------+--------------------+--------------+---------------+
| ./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.03 sec)

对应关系:


                        -----> data_1.dat (数据文件)
                        |
                        |
                        |
    ts_1 (表空间) ------- ----> data_2.dat (数据文件)
                        |
                        |                               ------> undo_1.log (撤销日志文件)
                        |                               |
                        -----> lg_1 (日志文件组)  -------
                                                        |
                                                        -----> undo_2.log (撤销日志文件)

节点 ID 为 2 的文件数信息(输出太多,省略了一部分):

Shell (192.168.100.12)> tree /usr/local/mysql/data/ndb_2_fs/
/usr/local/mysql/data/ndb_2_fs/
├── D1
│   ├── DBDICT
│   │   ├── P0.SchemaLog
│   │   ├── T1
│   │   │   └── S0.TableList
│   │   ├── T10
│   │   │   └── S0.TableList
│   │   ├── T11
│   │   │   └── S0.TableList
...
│   │   ├── T19
│   │   │   └── S0.TableList
│   │   ├── T2
│   │   │   └── S0.TableList
│   │   ├── T20
│   │   │   └── S0.TableList
...
│   │   ├── T23
│   │   │   └── S0.TableList
│   │   ├── T24
│   │   │   └── S0.TableList
│   │   ├── T3
│   │   │   └── S0.TableList
│   │   ├── T4
│   │   │   └── S0.TableList
...
│   │   └── T9
│   │       └── S0.TableList
│   ├── DBDIH
│   │   ├── P0.sysfile
│   │   ├── S10.FragList
│   │   ├── S11.FragList
...
│   │   ├── S15.FragList
│   │   ├── S22.FragList
│   │   ├── S23.FragList
│   │   ├── S24.FragList
│   │   ├── S2.FragList
│   │   ├── S3.FragList
...
│   │   └── S9.FragList
│   └── NDBCNTR
│       └── P0.sysfile
├── D10
│   └── DBLQH
│       ├── S0.FragLog
│       ├── S10.FragLog
│       ├── S11.FragLog
...
│       ├── S15.FragLog
│       ├── S1.FragLog
│       ├── S2.FragLog
...
│       └── S9.FragLog
├── D11
│   └── DBLQH
│       ├── S0.FragLog
│       ├── S10.FragLog
│       ├── S11.FragLog
│       ├── S12.FragLog
...
│       ├── S15.FragLog
│       ├── S1.FragLog
│       ├── S2.FragLog
...
│       └── S9.FragLog
├── D2
│   ├── DBDICT
│   │   ├── P0.SchemaLog
│   │   ├── T1
│   │   │   └── S0.TableList
│   │   ├── T10
│   │   │   └── S0.TableList
│   │   ├── T11
│   │   │   └── S0.TableList
│   │   ├── T12
│   │   │   └── S0.TableList
...
│   │   ├── T19
│   │   │   └── S0.TableList
│   │   ├── T2
│   │   │   └── S0.TableList
│   │   ├── T20
│   │   │   └── S0.TableList
...
│   │   ├── T24
│   │   │   └── S0.TableList
│   │   ├── T3
│   │   │   └── S0.TableList
│   │   ├── T4
│   │   │   └── S0.TableList
...
│   │   └── T9
│   │       └── S0.TableList
│   ├── DBDIH
│   │   ├── P0.sysfile
│   │   ├── S10.FragList
│   │   ├── S11.FragList
...
│   │   ├── S15.FragList
│   │   ├── S22.FragList
│   │   ├── S23.FragList
│   │   ├── S24.FragList
│   │   ├── S2.FragList
│   │   ├── S3.FragList
...
│   │   └── S9.FragList
│   └── NDBCNTR
│       └── P0.sysfile
├── D8
│   └── DBLQH
│       ├── S0.FragLog
│       ├── S10.FragLog
│       ├── S11.FragLog
...
│       ├── S15.FragLog
│       ├── S1.FragLog
│       ├── S2.FragLog
...
│       └── S9.FragLog
├── D9
│   └── DBLQH
│       ├── S0.FragLog
│       ├── S10.FragLog
...
│       ├── S15.FragLog
│       ├── S1.FragLog
...
│       └── S9.FragLog
├── LCP
│   ├── 0
│   │   ├── T10F0.ctl
│   │   ├── T10F0.Data
│   │   ├── T10F2.ctl
│   │   ├── T10F2.Data
│   │   ├── T11F0.ctl
│   │   ├── T11F0.Data
│   │   ├── T11F2.ctl
│   │   ├── T11F2.Data
│   │   ├── T13F0.ctl
│   │   ├── T13F0.Data
│   │   ├── T13F2.ctl
│   │   ├── T13F2.Data
│   │   ├── T15F0.ctl
│   │   ├── T15F0.Data
│   │   ├── T15F2.ctl
│   │   ├── T15F2.Data
│   │   ├── T4F0.ctl
│   │   ├── T4F0.Data
│   │   ├── T4F2.ctl
│   │   ├── T4F2.Data
│   │   ├── T5F0.ctl
│   │   ├── T5F0.Data
│   │   ├── T5F2.ctl
│   │   ├── T5F2.Data
│   │   ├── T6F0.ctl
│   │   ├── T6F0.Data
│   │   ├── T6F2.ctl
│   │   ├── T6F2.Data
│   │   ├── T7F0.ctl
│   │   ├── T7F0.Data
│   │   ├── T7F2.ctl
│   │   ├── T7F2.Data
│   │   ├── T8F0.ctl
│   │   ├── T8F0.Data
│   │   ├── T8F2.ctl
│   │   └── T8F2.Data
│   └── 1
│       ├── T2F0.ctl
│       ├── T2F0.Data
│       ├── T2F2.ctl
│       ├── T2F2.Data
│       ├── T3F0.ctl
│       ├── T3F0.Data
│       ├── T3F2.ctl
│       └── T3F2.Data
├── LG
│   ├── undo_1.log
│   └── undo_2.log
└── TS
    ├── data_1.dat
    └── data_2.dat

69 directories, 200 files

要删除磁盘上使用 ndbcluster 存储引擎的表,需有几个前提条件:

  • 只要有表在使用表空间,就不能删除表空间的任意数据文件
  • 表空间包含任意数量的数据文件,就不能删除该表空间
  • 只要表空间还在使用日志文件组,就不能删除对应的日志文件组

删除的顺序过程如下:

  1. 删除表
  2. 删除表空间中关联的数据文件
  3. 删除表空间
  4. 删除日志文件组
MySQL > drop table db1.dt_1;

MySQL > alter tablespace ts_1 drop datafile 'data_1.dat';

MySQL > alter tablespace ts_1 drop datafile 'data_2.dat';

MySQL > drop tablespace ts_1;

MySQL > drop logfile group lg_1;
Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇