概述
本章,您将学习在集群运行的情况下在线添加新数据节点。
众所周知,MySQL NDB Cluster 中的数据节点主要用来存储和复制数据。当生产环境下需要扩展数据的存储空间时,就需要在线添加新数据节点,因为生产环境下的 MySQL NDB Cluster 不允许完全关闭。
在添加新数据节点之前,以下的信息需要了解:
- 数据的重新分配 - 在线添加新数据节点需要 MySQL NDB Cluster 具有一种能力,即重新组织 NDB Cluster 表的数据以及索引,以便这些数据重新分布在所有的数据节点中(包括新数据节点)
- 部分启动 - 可以在未启动所有新数据节点的情况下添加新的节点组(节点组是相对于 SQL 节点来说的)。另外,即使集群处于降级状态(即仅部分启动的集群,或其中有一个或多个数据节点未运行的集群),仍然可以将新的节点组添加在集群中。在后一种情况下,必须确保集群中有足够的节点正在运行以维持正常运行,才能添加新的节点组
- 对正在进行操作的影响 - 正常的 DML (Data Manipulation Language,数据操作语言,主要指的是
insert、update、delete这些相关的语句)操作不会因为新添加的数据节点或表的重新组织或添加新的节点组而被影响。然而,若重新组织表时同时使用了 DDL(Data Definition Language,数据定义语言,主要指的是表和库的定义),则会被影响 -
对故障的处理 - 在节点组创建和重组表的过程中,数据节点的故障将按下表所示进行处理:
期间失败 "旧" 数据节点失败 "新" 数据节点失败 系统故障 节点组创建 若主数据节点以外的节点失败,节点组的创建操作将始终被前滚。如果主数据节点出现故障,若已经到达内部的提交点,则节点组的创建操作会被前滚;若未到达内部提交点,则节点组的创建操作会被回滚 若主数据节点以外的节点失败,节点组的创建操作将始终被前滚。如果主数据节点出现故障,若已经到达内部的提交点,则节点组的创建操作会被前滚;若未到达内部提交点,则节点组的创建操作会被回滚 若 create nodegroup的执行已经到达了内部的提交点,重启后集群会包含新的节点组。若create nodegroup的执行未到达内部的提交点,重启后集群不会包含新的节点组。重组表 若主数据节点以外的节点失败,重组表的操作将始终被前滚。如果主数据节点出现故障,若已经达到了内部的提交点,则重组表的操作会被前滚;若未到达内部提交点,则重组表的操作会被回滚 若主数据节点以外的节点失败,重组表的操作将始终被前滚。如果主数据节点出现故障,若已经达到了内部的提交点,则重组表的操作会被前滚;若未到达内部提交点,则重组表的操作会被回滚 如果 ALTER TABLE ... REORGANIZE PARTITION语句已经到达了内部的提交点,则重新启动集群时,属于表的数据和索引将使用 "新" 的数据节点进行分配。如果ALTER TABLE ... REORGANIZE PARTITION语句未到达内部的提交点,则重新启动集群时,属于表的数据和索引将仅使用 "旧" 的数据节点进行分配。
回滚(Roll back):撤销操作,恢复之前的状态
添加新数据节点的顺序步骤
在一个已经运行的集群环境中,若要添加新的数据节点,对应的顺序步骤有:
-
编辑管理节点的全局配置文件(config.ini),使全局配置文件中包含新数据节点的 "[ndbd]" 部分。若集群中存在多个管理节点,则需要对所有管理节点的 config.ini 进行变更
-
对单个管理节点执行滚动重启,直到完成所有管理节点的滚动重启。依次在对应的管理节点上执行
ndb_mgmd命令的 --reload 或者 --initial 选项- 若您在首个管理节点上使用 --initial 选项启动了 ndb_mgmd 进程,则剩余的其他管理节点也必须使用 --initial 选项启动 ndb_mgmd 进程
- 若您在首个管理节点上使用了任何其他的选项启动了 ndb_mgmd 进程,则剩余的其他管理节点都不应该使用 --reload 选项启动 ndb_mgmd 进程
-
完成集群中每个数据节点的滚动重启,单个数据节点的步骤如下:
- 停止 ndbd 进程(通过
kill或killall命令来实现) - 重新配置 /etc/my.cnf 文件(若需要的话)
- 使用
ndbd命令(注意!该命令不需要 --initial 选项)启动 ndbd 进程
- 停止 ndbd 进程(通过
-
完成集群中每个 SQL 节点的滚动重启,单个 SQL 节点的步骤如下:
- 停止 mysqld 进程(通过
kill或killall命令来实现) - 重新配置 /etc/my.cnf 文件(若需要的话)
- 使用
mysql.server start命令启动 mysqld 进程
- 停止 mysqld 进程(通过
-
对新数据节点的 /etc/my.cnf 进行配置且启动 ndbd 进程(
ndbd命令需要使用 --initial 选项) -
在管理节点
ndb_mgm命令的终端中执行一个或多个create nodegroup,以创建新数据节点所属的一个或多个新节点组 -
在所有数据节点(包括新数据节点)之间重新分配集群的数据,这可以通过
ALTER TABLE ... ALGORITHM=INPLACE,REORGANIZE PARTITION语句来完成 -
在 mysql 客户端中针对每个 NDBCLUSTER 表执行
OPTIMIZE TABLE语句来实现重组分区并回收 "旧" 节点上所使用的空间
实际操作
当前的集群信息:
| 操作系统 | 操作系统环境 | IP 地址 | 硬件信息 | NDB Cluster 版本 | 节点类型 |
|---|---|---|---|---|---|
| RL 8.10 | 纯命令行 | 192.168.100.10/24 | 1 core;4GB 内存;50GB 存储 | 8.4.8 LTS | 管理节点 |
| RL 8.10 | 纯命令行 | 192.168.100.12/24 | 1 core;4GB 内存;50GB 存储 | 8.4.8 LTS | 数据节点 A |
| RL 8.10 | 纯命令行 | 192.168.100.14/24 | 1 core;4GB 内存;50GB 存储 | 8.4.8 LTS | 数据节点 B |
| RL 8.10 | 纯命令行 | 192.168.100.16/24 | 1 core;4GB 内存;50GB 存储 | 8.4.8 LTS | SQL 节点 |
需求:使用滚动重启完成此操作 —— 在线添加两个新数据节点且要求它们属于新的节点组。
Q:为什么要添加两个数据节点而不是一个呢?
这与管理节点的 config.ini 文件内容有关:
Shell > vim /etc/mysql-cluster/config.ini
[ndbd default]
# 影响所有数据节点上 ndbd 进程的选项(键值对):
NoOfReplicas=2 # 段副本的数量
...
因为段副本的数量是 2 ,则数据节点的总数量必须是 2 的整数倍。
以下是新数据节点的基本信息:
| 操作系统 | 操作系统环境 | IP 地址 | 硬件信息 | NDB Cluster 版本 | 节点类型 |
|---|---|---|---|---|---|
| RL 8.10 | 纯命令行 | 192.168.100.18/24 | 1 core;4GB 内存;50GB 存储 | 8.4.8 LTS | 数据节点 C |
| RL 8.10 | 纯命令行 | 192.168.100.20/24 | 1 core;4GB 内存;50GB 存储 | 8.4.8 LTS | 数据节点 D |
对数据节点 C 进行配置:
Shell > wget https://dev.mysql.com/get/Downloads/MySQL-Cluster-8.4/mysql-cluster-8.4.8-linux-glibc2.28-x86_64.tar.xz
Shell > tar -xvf mysql-cluster-8.4.8-linux-glibc2.28-x86_64.tar.xz -C /usr/local/src/
Shell > cd /usr/local/src/mysql-cluster-8.4.8-linux-glibc2.28-x86_64/bin/ && cp -p ndbd /usr/local/bin/ && cp -p ndbmtd /usr/local/bin/
Shell > chmod a+x /usr/local/bin/*
Shell > vim /etc/my.cnf
[mysqld]
ndbcluster
[mysql_cluster]
ndb-connectstring=192.168.100.10
# 创建存放数据的目录
Shell > mkdir -p /usr/local/mysql/data/
对数据节点 D 进行配置:
Shell > wget https://dev.mysql.com/get/Downloads/MySQL-Cluster-8.4/mysql-cluster-8.4.8-linux-glibc2.28-x86_64.tar.xz
Shell > tar -xvf mysql-cluster-8.4.8-linux-glibc2.28-x86_64.tar.xz -C /usr/local/src/
Shell > cd /usr/local/src/mysql-cluster-8.4.8-linux-glibc2.28-x86_64/bin/ && cp -p ndbd /usr/local/bin/ && cp -p ndbmtd /usr/local/bin/
Shell > chmod a+x /usr/local/bin/*
Shell > vim /etc/my.cnf
[mysqld]
ndbcluster
[mysql_cluster]
ndb-connectstring=192.168.100.10
# 创建存放数据的目录
Shell > mkdir -p /usr/local/mysql/data/
第一步:编辑管理节点的全局配置文件(config.ini),使全局配置文件中包含新数据节点的 "[ndbd]" 部分。若集群中存在多个管理节点,则需要对所有管理节点的 config.ini 进行变更
# 这里的配置变更了每个节点的节点 ID
Shell (192.168.100.10) > vim /etc/mysql-cluster/config.ini
[ndbd default]
NoOfReplicas=2
DataMemory=98M
[ndb_mgmd]
HostName=192.168.100.10
DataDir=/var/log/mysql-cluster
NodeId=1
[ndbd]
HostName=192.168.100.12
NodeId=2
DataDir=/usr/local/mysql/data
[ndbd]
HostName=192.168.100.14
NodeId=3
DataDir=/usr/local/mysql/data
[ndbd]
HostName=192.168.100.18
NodeId=4
DataDir=/usr/local/mysql/data
[ndbd]
HostName=192.168.100.20
NodeId=5
DataDir=/usr/local/mysql/data
[mysqld]
HostName=192.168.100.16
NodeId=6
第二步:对单个管理节点执行滚动重启,直到完成所有管理节点的滚动重启。
Shell (192.168.100.10) > ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> 1 stop
Connected to management server at localhost port 1186 (using cleartext)
Node 1 has shutdown.
Disconnecting to allow Management Server to shutdown
ndb_mgm> quit
Shell (192.168.100.10) > ndb_mgmd --configdir=/etc/mysql-cluster/ -f /etc/mysql-cluster/config.ini --initial
Shell (192.168.100.10) > ndb_mgm -e "show"
Connected to management server at localhost port 1186 (using cleartext)
Cluster Configuration
---------------------
[ndbd(NDB)] 4 node(s)
id=2 @192.168.100.12 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 0, *)
id=3 @192.168.100.14 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 0)
id=4 (not connected, accepting connect from 192.168.100.18)
id=5 (not connected, accepting connect from 192.168.100.20)
[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.100.10 (mysql-8.4.8 ndb-8.4.8)
[mysqld(API)] 1 node(s)
id=6 (not connected, accepting connect from 192.168.100.16)
注意!实际生产环境下,若您有多个管理节点,则不应该一次性将所有管理节点关闭,而应该是滚动重启一个管理节点后,再配置下一个管理节点。
第三步:完成集群中每个数据节点的滚动重启,单个数据节点的步骤如下:
- 停止 ndbd 进程(通过
kill或killall命令来实现) - 重新配置 /etc/my.cnf 文件(若需要的话)
- 使用
ndbd命令(注意!该命令不需要 --initial 选项)启动 ndbd 进程
Shell (192.168.100.12) > killall ndbd
Shell (192.168.100.12) > ndbd
2026-04-17 11:37:09 [ndbd] INFO -- Angel connected to '192.168.100.10:1186'
2026-04-17 11:37:09 [ndbd] INFO -- Angel allocated nodeid: 2
Shell (192.168.100.14) > killall ndbd
Shell (192.168.100.14) > ndbd
2026-04-17 11:38:32 [ndbd] INFO -- Angel connected to '192.168.100.10:1186'
2026-04-17 11:38:32 [ndbd] INFO -- Angel allocated nodeid: 3
第四步:完成集群中每个 SQL 节点的滚动重启,单个 SQL 节点的步骤如下:
- 停止 mysqld 进程(通过
kill或killall命令来实现) - 重新配置 /etc/my.cnf 文件(若需要的话)
- 使用
mysql.server start命令启动 mysqld 进程
Shell (192.168.100.16) > killall mysqld
Shell (192.168.100.16) > /usr/local/mysql/support-files/mysql.server start
第五步:对新数据节点的 /etc/my.cnf 进行配置且启动 ndbd 进程
Shell (192.168.100.18) > ndbd --initial
2026-04-17 11:47:23 [ndbd] INFO -- Angel connected to '192.168.100.10:1186'
2026-04-17 11:47:23 [ndbd] INFO -- Angel allocated nodeid: 4
Shell (192.168.100.20) > ndbd --initial
2026-04-17 11:48:35 [ndbd] INFO -- Angel connected to '192.168.100.10:1186'
2026-04-17 11:48:36 [ndbd] INFO -- Angel allocated nodeid: 5
第六步:在管理节点 ndb_mgm 命令的终端中执行一个或多个 create nodegroup,以创建新数据节点所属的一个或多个新节点组。
# 目前的状态如下:
Shell (192.168.100.10) > ndb_mgm -e "show"
Connected to management server at localhost port 1186 (using cleartext)
Cluster Configuration
---------------------
[ndbd(NDB)] 4 node(s)
id=2 @192.168.100.12 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 0, *)
id=3 @192.168.100.14 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 0)
id=4 @192.168.100.18 (mysql-8.4.8 ndb-8.4.8, no nodegroup)
id=5 @192.168.100.20 (mysql-8.4.8 ndb-8.4.8, no nodegroup)
[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.100.10 (mysql-8.4.8 ndb-8.4.8)
[mysqld(API)] 1 node(s)
id=6 @192.168.100.16 (mysql-8.4.8 ndb-8.4.8)
Shell (192.168.100.10) > ndb_mgm
# 创建一个新的节点组,节点组包含节点 ID 为 4 和 5 的节点。请注意!正如前面文章提到的,您没办法指定节点组的 ID
ndb_mgm> create nodegroup 4,5
Connected to management server at localhost port 1186 (using cleartext)
Nodegroup 1 created
# 可以看到,集群系统给新节点组分配的节点组 ID 为1
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)] 4 node(s)
id=2 @192.168.100.12 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 0, *)
id=3 @192.168.100.14 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 0)
id=4 @192.168.100.18 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 1)
id=5 @192.168.100.20 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 1)
[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.100.10 (mysql-8.4.8 ndb-8.4.8)
[mysqld(API)] 1 node(s)
id=6 @192.168.100.16 (mysql-8.4.8 ndb-8.4.8)
第七步:在所有数据节点(包括新数据节点)之间重新分配集群的数据
创建新节点组后,现有的数据和索引不会自动分配到新节点组的各个数据节点中,您可以通过管理节点的以下命令查看到:
Shell (192.168.100.10) > ndb_mgm
# 从输出可知,还没有完成数据和索引的重新分布
ndb_mgm> ALL REPORT MEMORY
Connected to management server at localhost port 1186 (using cleartext)
Node 2: Data usage is 0%(11 32K pages of total 3130)
Node 2: Index usage is 0%(6 32K pages of total 3125)
Node 3: Data usage is 0%(11 32K pages of total 3130)
Node 3: Index usage is 0%(6 32K pages of total 3125)
Node 4: Data usage is 0%(0 32K pages of total 3136)
Node 4: Index usage is 0%(0 32K pages of total 3136)
Node 5: Data usage is 0%(0 32K pages of total 3136)
Node 5: Index usage is 0%(0 32K pages of total 3136)
每一个在新节点组创建之前使用 ndbcluster 存储引擎的表都需要重新组织表,而在节点组创建之后使用 ndbcluster 存储引擎创建的表则会自动重新组织。
# 要查看当前数据库中哪些表使用 ndbcluster 存储引擎,请使用该 SQL 语句
MySQL > select table_schema,table_name from information_schema.tables where engine='ndbcluster';
+--------------+------------------+
| TABLE_SCHEMA | TABLE_NAME |
+--------------+------------------+
| mysql | ndb_apply_status |
+--------------+------------------+
1 row in set (0.01 sec)
# 注意!重新组织表必须是一张一张表的来
MySQL > alter table mysql.ndb_apply_status algorithm=inplace,reorganize partition;
第八步:执行特定 SQL 语句重新组织分区
第七步有多少表,第八步就需要操作对应数量的表。
# 这里只有一张表,多个表可用逗号分隔
MySQL > optimize table mysql.ndb_apply_status;
最后
最后查看集群的状态:
Shell (192.168.100.10) > ndb_mgm
ndb_mgm> show
Connected to management server at localhost port 1186 (using cleartext)
Cluster Configuration
---------------------
[ndbd(NDB)] 4 node(s)
id=2 @192.168.100.12 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 0, *)
id=3 @192.168.100.14 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 0)
id=4 @192.168.100.18 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 1)
id=5 @192.168.100.20 (mysql-8.4.8 ndb-8.4.8, Nodegroup: 1)
[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.100.10 (mysql-8.4.8 ndb-8.4.8)
[mysqld(API)] 1 node(s)
id=6 @192.168.100.16 (mysql-8.4.8 ndb-8.4.8)
ndb_mgm> all report memory
Node 2: Data usage is 0%(11 32K pages of total 3129)
Node 2: Index usage is 0%(7 32K pages of total 3125)
Node 3: Data usage is 0%(11 32K pages of total 3129)
Node 3: Index usage is 0%(7 32K pages of total 3125)
Node 4: Data usage is 0%(1 32K pages of total 3135)
Node 4: Index usage is 0%(1 32K pages of total 3135)
Node 5: Data usage is 0%(1 32K pages of total 3135)
Node 5: Index usage is 0%(1 32K pages of total 3135)










