在本节中,我们将提供一个详细的示例,说明如何在线添加新的 NDB 集群数据节点,从具有单个节点组中的 2 个数据节点的 NDB 集群开始,到具有 2 个节点组中的 4 个数据节点的集群结束。
**起始配置。** 为了便于说明,我们假设使用最小配置,并且集群使用仅包含以下信息的 config.ini
文件
[ndbd default]
DataMemory = 100M
IndexMemory = 100M
NoOfReplicas = 2
DataDir = /usr/local/mysql/var/mysql-cluster
[ndbd]
Id = 1
HostName = 198.51.100.1
[ndbd]
Id = 2
HostName = 198.51.100.2
[mgm]
HostName = 198.51.100.10
Id = 10
[api]
Id=20
HostName = 198.51.100.20
[api]
Id=21
HostName = 198.51.100.21
我们在数据节点 ID 和其他节点之间留了一个间隙。这使得稍后更容易为新添加的数据节点分配尚未使用的节点 ID。
我们还假设您已经使用适当的命令行或 my.cnf
选项启动了集群,并且在管理客户端中运行 SHOW
会产生类似于此处显示的输出
-- NDB Cluster -- Management Client --
ndb_mgm> SHOW
Connected to Management Server at: 198.51.100.10:1186 (using cleartext)
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=1 @198.51.100.1 (9.0.0-ndb-9.0.0, Nodegroup: 0, *)
id=2 @198.51.100.2 (9.0.0-ndb-9.0.0, Nodegroup: 0)
[ndb_mgmd(MGM)] 1 node(s)
id=10 @198.51.100.10 (9.0.0-ndb-9.0.0)
[mysqld(API)] 2 node(s)
id=20 @198.51.100.20 (9.0.0-ndb-9.0.0)
id=21 @198.51.100.21 (9.0.0-ndb-9.0.0)
最后,我们假设集群包含一个按此处所示创建的 NDBCLUSTER
表
USE n;
CREATE TABLE ips (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
country_code CHAR(2) NOT NULL,
type CHAR(4) NOT NULL,
ip_address VARCHAR(15) NOT NULL,
addresses BIGINT UNSIGNED DEFAULT NULL,
date BIGINT UNSIGNED DEFAULT NULL
) ENGINE NDBCLUSTER;
本节后面显示的内存使用情况和相关信息是在向该表中插入大约 50000 行后生成的。
**步骤 1:更新配置文件。** 在文本编辑器中打开集群全局配置文件,并添加与 2 个新数据节点对应的 [ndbd]
部分。(我们为这些数据节点指定 ID 3 和 4,并假设它们将分别在地址为 198.51.100.3 和 198.51.100.4 的主机上运行。)添加新部分后,config.ini
文件的内容应如下所示,其中对文件的添加以粗体显示
[ndbd default]
DataMemory = 100M
IndexMemory = 100M
NoOfReplicas = 2
DataDir = /usr/local/mysql/var/mysql-cluster
[ndbd]
Id = 1
HostName = 198.51.100.1
[ndbd]
Id = 2
HostName = 198.51.100.2
[ndbd]
Id = 3
HostName = 198.51.100.3
[ndbd]
Id = 4
HostName = 198.51.100.4
[mgm]
HostName = 198.51.100.10
Id = 10
[api]
Id=20
HostName = 198.51.100.20
[api]
Id=21
HostName = 198.51.100.21
完成必要的更改后,保存文件。
**步骤 2:重新启动管理服务器。** 重新启动集群管理服务器需要您发出单独的命令来停止管理服务器,然后再重新启动它,如下所示
使用管理客户端
STOP
命令停止管理服务器,如下所示ndb_mgm> 10 STOP Node 10 has shut down. Disconnecting to allow Management Server to shutdown $>
因为关闭管理服务器会导致管理客户端终止,所以您必须从系统 shell 启动管理服务器。为简单起见,我们假设
config.ini
与管理服务器二进制文件位于同一目录中,但在实践中,您必须提供配置文件的正确路径。您还必须提供--reload
或--initial
选项,以便管理服务器从文件中读取新配置,而不是从其配置缓存中读取。如果您的 shell 的当前目录也与管理服务器二进制文件所在的目录相同,则可以按此处所示调用管理服务器$> ndb_mgmd -f config.ini --reload 2008-12-08 17:29:23 [MgmSrvr] INFO -- NDB Cluster Management Server. 9.0.0-ndb-9.0.0 2008-12-08 17:29:23 [MgmSrvr] INFO -- Reading cluster configuration from 'config.ini'
如果在重新启动 ndb_mgm 进程后,您在管理客户端中检查 SHOW
的输出,您现在应该会看到类似这样的内容
-- NDB Cluster -- Management Client --
ndb_mgm> SHOW
Connected to Management Server at: 198.51.100.10:1186 (using cleartext)
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=1 @198.51.100.1 (9.0.0-ndb-9.0.0, Nodegroup: 0, *)
id=2 @198.51.100.2 (9.0.0-ndb-9.0.0, Nodegroup: 0)
id=3 (not connected, accepting connect from 198.51.100.3)
id=4 (not connected, accepting connect from 198.51.100.4)
[ndb_mgmd(MGM)] 1 node(s)
id=10 @198.51.100.10 (9.0.0-ndb-9.0.0)
[mysqld(API)] 2 node(s)
id=20 @198.51.100.20 (9.0.0-ndb-9.0.0)
id=21 @198.51.100.21 (9.0.0-ndb-9.0.0)
**步骤 3:对现有数据节点执行滚动重启。** 此步骤可以使用 RESTART
命令完全在集群管理客户端中完成,如下所示
ndb_mgm> 1 RESTART
Node 1: Node shutdown initiated
Node 1: Node shutdown completed, restarting, no start.
Node 1 is being restarted
ndb_mgm> Node 1: Start initiated (version 9.0.0)
Node 1: Started (version 9.0.0)
ndb_mgm> 2 RESTART
Node 2: Node shutdown initiated
Node 2: Node shutdown completed, restarting, no start.
Node 2 is being restarted
ndb_mgm> Node 2: Start initiated (version 9.0.0)
ndb_mgm> Node 2: Started (version 9.0.0)
发出每个
命令后,请等待管理客户端报告 X
RESTART节点
,然后再继续进行任何操作。X
:已启动(版本 ...)
您可以通过检查 mysql 客户端中的 ndbinfo.nodes
表来验证是否已使用更新的配置重新启动了所有现有数据节点。
**步骤 4:对所有集群 API 节点执行滚动重启。** 使用 mysqladmin shutdown 后跟 mysqld_safe(或其他启动脚本)关闭并重新启动充当集群中 SQL 节点的每个 MySQL 服务器。这应该类似于此处显示的内容,其中 password
是给定 MySQL 服务器实例的 MySQL root
密码
$> mysqladmin -uroot -ppassword shutdown
081208 20:19:56 mysqld_safe mysqld from pid file
/usr/local/mysql/var/tonfisk.pid ended
$> mysqld_safe --ndbcluster --ndb-connectstring=198.51.100.10 &
081208 20:20:06 mysqld_safe Logging to '/usr/local/mysql/var/tonfisk.err'.
081208 20:20:06 mysqld_safe Starting mysqld daemon with databases
from /usr/local/mysql/var
当然,确切的输入和输出取决于 MySQL 在系统上的安装方式和位置,以及您选择启动它的选项(以及这些选项中的一些或全部是否在 my.cnf
文件中指定)。
**步骤 5:执行新数据节点的初始启动。** 从每个新数据节点主机上的系统 shell 中,使用 --initial
选项启动数据节点,如下所示
$> ndbd -c 198.51.100.10 --initial
与重新启动现有数据节点的情况不同,您可以同时启动新数据节点;您不需要等待一个启动完成后再启动另一个。
等待两个新数据节点都启动后再继续下一步。新数据节点启动后,您可以在管理客户端 SHOW
命令的输出中看到它们尚不属于任何节点组(如此处以粗体显示)
ndb_mgm> SHOW
Connected to Management Server at: 198.51.100.10:1186 (using cleartext)
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=1 @198.51.100.1 (9.0.0-ndb-9.0.0, Nodegroup: 0, *)
id=2 @198.51.100.2 (9.0.0-ndb-9.0.0, Nodegroup: 0)
id=3 @198.51.100.3 (9.0.0-ndb-9.0.0, no nodegroup)
id=4 @198.51.100.4 (9.0.0-ndb-9.0.0, no nodegroup)
[ndb_mgmd(MGM)] 1 node(s)
id=10 @198.51.100.10 (9.0.0-ndb-9.0.0)
[mysqld(API)] 2 node(s)
id=20 @198.51.100.20 (9.0.0-ndb-9.0.0)
id=21 @198.51.100.21 (9.0.0-ndb-9.0.0)
**步骤 6:创建新的节点组。** 您可以通过在集群管理客户端中发出 CREATE NODEGROUP
命令来完成此操作。此命令将要包含在新节点组中的数据节点的节点 ID 的逗号分隔列表作为其参数,如下所示
ndb_mgm> CREATE NODEGROUP 3,4
Nodegroup 1 created
通过再次发出 SHOW
,您可以验证数据节点 3 和 4 是否已加入新的节点组(再次以粗体显示)
ndb_mgm> SHOW
Connected to Management Server at: 198.51.100.10:1186 (using cleartext)
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=1 @198.51.100.1 (9.0.0-ndb-9.0.0, Nodegroup: 0, *)
id=2 @198.51.100.2 (9.0.0-ndb-9.0.0, Nodegroup: 0)
id=3 @198.51.100.3 (9.0.0-ndb-9.0.0, Nodegroup: 1)
id=4 @198.51.100.4 (9.0.0-ndb-9.0.0, Nodegroup: 1)
[ndb_mgmd(MGM)] 1 node(s)
id=10 @198.51.100.10 (9.0.0-ndb-9.0.0)
[mysqld(API)] 2 node(s)
id=20 @198.51.100.20 (9.0.0-ndb-9.0.0)
id=21 @198.51.100.21 (9.0.0-ndb-9.0.0)
**步骤 7:重新分配集群数据。** 创建节点组时,现有数据和索引不会自动分配到新节点组的数据节点,您可以通过在管理客户端中发出适当的 REPORT
命令来查看
ndb_mgm> ALL REPORT MEMORY
Node 1: Data usage is 5%(177 32K pages of total 3200)
Node 1: Index usage is 0%(108 8K pages of total 12832)
Node 2: Data usage is 5%(177 32K pages of total 3200)
Node 2: Index usage is 0%(108 8K pages of total 12832)
Node 3: Data usage is 0%(0 32K pages of total 3200)
Node 3: Index usage is 0%(0 8K pages of total 12832)
Node 4: Data usage is 0%(0 32K pages of total 3200)
Node 4: Index usage is 0%(0 8K pages of total 12832)
通过使用带有 -p
选项的 ndb_desc,这会导致输出包含分区信息,您可以看到该表仍然只使用 2 个分区(在输出的 每个分区信息
部分中,此处以粗体显示)
$> ndb_desc -c 198.51.100.10 -d n ips -p
-- ips --
Version: 1
Fragment type: 9
K Value: 6
Min load factor: 78
Max load factor: 80
Temporary table: no
Number of attributes: 6
Number of primary keys: 1
Length of frm data: 340
Row Checksum: 1
Row GCI: 1
SingleUserMode: 0
ForceVarPart: 1
FragmentCount: 2
TableStatus: Retrieved
-- Attributes --
id Bigint PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
country_code Char(2;latin1_swedish_ci) NOT NULL AT=FIXED ST=MEMORY
type Char(4;latin1_swedish_ci) NOT NULL AT=FIXED ST=MEMORY
ip_address Varchar(15;latin1_swedish_ci) NOT NULL AT=SHORT_VAR ST=MEMORY
addresses Bigunsigned NULL AT=FIXED ST=MEMORY
date Bigunsigned NULL AT=FIXED ST=MEMORY
-- Indexes --
PRIMARY KEY(id) - UniqueHashIndex
PRIMARY(id) - OrderedIndex
-- Per partition info --
Partition Row count Commit count Frag fixed memory Frag varsized memory
0 26086 26086 1572864 557056
1 26329 26329 1605632 557056
您可以通过在 mysql 客户端中为每个 NDB
表执行 ALTER TABLE ... ALGORITHM=INPLACE, REORGANIZE PARTITION
语句,使数据重新分配到所有数据节点中。
ALTER TABLE ... ALGORITHM=INPLACE, REORGANIZE PARTITION
不适用于使用 MAX_ROWS
选项创建的表。请改用 ALTER TABLE ... ALGORITHM=INPLACE, MAX_ROWS=...
来重新组织此类表。
请记住,使用 MAX_ROWS
来设置每个表的分区数已被弃用,您应该改用 PARTITION_BALANCE
;有关详细信息,请参见 第 15.1.20.12 节 “设置 NDB 注释选项”。
发出语句 ALTER TABLE ips ALGORITHM=INPLACE, REORGANIZE PARTITION
后,您可以使用 ndb_desc 看到此表的数据现在使用 4 个分区存储,如下所示(输出的相关部分以粗体显示)
$> ndb_desc -c 198.51.100.10 -d n ips -p
-- ips --
Version: 16777217
Fragment type: 9
K Value: 6
Min load factor: 78
Max load factor: 80
Temporary table: no
Number of attributes: 6
Number of primary keys: 1
Length of frm data: 341
Row Checksum: 1
Row GCI: 1
SingleUserMode: 0
ForceVarPart: 1
FragmentCount: 4
TableStatus: Retrieved
-- Attributes --
id Bigint PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
country_code Char(2;latin1_swedish_ci) NOT NULL AT=FIXED ST=MEMORY
type Char(4;latin1_swedish_ci) NOT NULL AT=FIXED ST=MEMORY
ip_address Varchar(15;latin1_swedish_ci) NOT NULL AT=SHORT_VAR ST=MEMORY
addresses Bigunsigned NULL AT=FIXED ST=MEMORY
date Bigunsigned NULL AT=FIXED ST=MEMORY
-- Indexes --
PRIMARY KEY(id) - UniqueHashIndex
PRIMARY(id) - OrderedIndex
-- Per partition info --
Partition Row count Commit count Frag fixed memory Frag varsized memory
0 12981 52296 1572864 557056
1 13236 52515 1605632 557056
2 13105 13105 819200 294912
3 13093 13093 819200 294912
通常,ALTER TABLE
与分区标识符列表和一组分区定义一起使用,以便为已显式分区的表创建新的分区方案。它在这里用于将数据重新分配到新的 NDB 集群节点组是一种例外情况;以这种方式使用时,table_name
[ALGORITHM=INPLACE,] REORGANIZE PARTITIONREORGANIZE PARTITION
后面没有其他关键字或标识符。
有关详细信息,请参见 第 15.1.9 节 “ALTER TABLE 语句”。
此外,对于每个表,ALTER TABLE
语句后面应该跟一个 OPTIMIZE TABLE
,以回收浪费的空间。您可以使用以下针对信息架构 TABLES
表的查询来获取所有 NDBCLUSTER
表的列表
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE ENGINE = 'NDBCLUSTER';
NDB 集群表的 INFORMATION_SCHEMA.TABLES.ENGINE
值始终为 NDBCLUSTER
,而不管用于创建表的 CREATE TABLE
语句(或用于从其他存储引擎转换现有表的 ALTER TABLE
语句)在其 ENGINE
选项中使用的是 NDB
还是 NDBCLUSTER
。
在 ALL REPORT MEMORY
的输出中执行这些语句后,您可以看到数据和索引现在已重新分配到所有集群数据节点之间,如下所示
ndb_mgm> ALL REPORT MEMORY
Node 1: Data usage is 5%(176 32K pages of total 3200)
Node 1: Index usage is 0%(76 8K pages of total 12832)
Node 2: Data usage is 5%(176 32K pages of total 3200)
Node 2: Index usage is 0%(76 8K pages of total 12832)
Node 3: Data usage is 2%(80 32K pages of total 3200)
Node 3: Index usage is 0%(51 8K pages of total 12832)
Node 4: Data usage is 2%(80 32K pages of total 3200)
Node 4: Index usage is 0%(50 8K pages of total 12832)
由于一次只能对 NDBCLUSTER
表执行一个 DDL 操作,因此在发出下一个语句之前,必须等待每个 ALTER TABLE ... REORGANIZE PARTITION
语句完成。
对于在添加新数据节点之后创建的 NDBCLUSTER
表,无需发出 ALTER TABLE ... REORGANIZE PARTITION
语句;添加到此类表的数据会自动分布在所有数据节点之间。但是,在添加新节点之前存在的 NDBCLUSTER
表中,在使用 ALTER TABLE ... REORGANIZE PARTITION
对这些表进行重新组织之前,现有数据和新数据都不会使用新节点进行分布。
**无需滚动重启的替代过程。** 可以通过配置额外的数据节点,但在首次启动集群时不启动它们,来避免滚动重启的需要。与之前一样,我们假设您希望在一个节点组中启动两个数据节点(节点 1 和 2),然后通过添加由节点 3 和 4 组成的第二个节点组将集群扩展到四个数据节点。
[ndbd default]
DataMemory = 100M
IndexMemory = 100M
NoOfReplicas = 2
DataDir = /usr/local/mysql/var/mysql-cluster
[ndbd]
Id = 1
HostName = 198.51.100.1
[ndbd]
Id = 2
HostName = 198.51.100.2
[ndbd]
Id = 3
HostName = 198.51.100.3
Nodegroup = 65536
[ndbd]
Id = 4
HostName = 198.51.100.4
Nodegroup = 65536
[mgm]
HostName = 198.51.100.10
Id = 10
[api]
Id=20
HostName = 198.51.100.20
[api]
Id=21
HostName = 198.51.100.21
可以在以后上线的数据节点(节点 3 和 4)可以使用 NodeGroup = 65536
进行配置,在这种情况下,可以像这样启动节点 1 和 2:
$> ndbd -c 198.51.100.10 --initial
管理服务器将使用 NodeGroup = 65536
配置的数据节点视为在等待由 StartNoNodeGroupTimeout
数据节点配置参数的设置确定的时间段后,使用 --nowait-nodes=3,4
启动了节点 1 和 2。默认情况下,这是 15 秒(15000 毫秒)。
StartNoNodegroupTimeout
对于集群中的所有数据节点必须相同;因此,您应该始终在 config.ini
文件的 [ndbd default]
部分设置它,而不是为单个数据节点设置。
当您准备好添加第二个节点组时,只需执行以下附加步骤:
启动数据节点 3 和 4,为每个新节点调用一次数据节点进程。
$> ndbd -c 198.51.100.10 --initial
在管理客户端中发出适当的
CREATE NODEGROUP
命令。ndb_mgm> CREATE NODEGROUP 3,4
在 mysql 客户端中,为每个现有的
NDBCLUSTER
表发出ALTER TABLE ... REORGANIZE PARTITION
和OPTIMIZE TABLE
语句。(如本节其他地方所述,在完成此操作之前,现有 NDB Cluster 表无法使用新节点进行数据分发。)