21.5.7.3 在线添加 NDB 群集数据节点:详细示例

在本节中,我们提供一个详细的示例,说明如何在线添加新的 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

Note

我们在数据节点 ID 和其他节点之间的 Sequences 上留下了空白。这使以后更容易将尚未使用的节点 ID 分配给新添加的数据节点。

我们还假设您已经使用适当的命令行或my.cnf选项启动了集群,并且在 ManagementClient 端中运行SHOW会产生类似于此处所示的输出:

-- NDB Cluster -- Management Client --
ndb_mgm> SHOW
Connected to Management Server at: 198.51.100.10:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=1    @198.51.100.1  (5.7.31-ndb-7.5.20, Nodegroup: 0, *)
id=2    @198.51.100.2  (5.7.31-ndb-7.5.20, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=10   @198.51.100.10  (5.7.31-ndb-7.5.20)

[mysqld(API)]   2 node(s)
id=20   @198.51.100.20  (5.7.31-ndb-7.5.20)
id=21   @198.51.100.21  (5.7.31-ndb-7.5.20)

最后,我们假设集群包含一个单独的NDBCLUSTERtable,如下所示:

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;

本节后面显示的内存使用情况和相关信息是在该 table 中插入大约 50000 行之后生成的。

Note

在此示例中,我们显示了用于数据节点进程的单线程ndbd。如果您正在使用多线程ndbmtd,请在随后的步骤中将ndbmtd替换为ndbd,也可以应用此示例。

步骤 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:重新启动 Management 服务器. 重新启动群集 Management 服务器要求您发出单独的命令来停止 Management 服务器,然后再次启动它,如下所示:

  • 使用 ManagementClient 端STOP命令停止 Management 服务器,如下所示:
ndb_mgm> 10 STOP
Node 10 has shut down.
Disconnecting to allow Management Server to shutdown

shell>
  • 因为关闭 Management 服务器会导致 ManagementClient 端终止,所以您必须从系统 Shell 启动 Management 服务器。为简单起见,我们假定config.ini与 Management 服务器二进制文件位于同一目录中,但是实际上,您必须提供配置文件的正确路径。您还必须提供--reload--initial选项,以便 Management 服务器从文件而不是其配置缓存中读取新配置。如果 Shell 程序的当前目录也与 Management 服务器二进制文件所在的目录相同,则可以按如下所示调用 Management 服务器:
shell> ndb_mgmd -f config.ini --reload
2008-12-08 17:29:23 [MgmSrvr] INFO     -- NDB Cluster Management Server. 5.7.31-ndb-7.5.20
2008-12-08 17:29:23 [MgmSrvr] INFO     -- Reading cluster configuration from 'config.ini'

如果您在重新启动ndb_mgm进程后在 ManagementClient 端中检查SHOW的输出,则现在应该看到类似以下内容:

-- NDB Cluster -- Management Client --
ndb_mgm> SHOW
Connected to Management Server at: 198.51.100.10:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=1    @198.51.100.1  (5.7.31-ndb-7.5.20, Nodegroup: 0, *)
id=2    @198.51.100.2  (5.7.31-ndb-7.5.20, 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  (5.7.31-ndb-7.5.20)

[mysqld(API)]   2 node(s)
id=20   @198.51.100.20  (5.7.31-ndb-7.5.20)
id=21   @198.51.100.21  (5.7.31-ndb-7.5.20)

步骤 3:对现有数据节点执行滚动重启. 此步骤完全可以使用RESTART命令在集群 ManagementClient 端中完成,如下所示:

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 7.5.20)
Node 1: Started (version 7.5.20)

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 7.5.20)

ndb_mgm> Node 2: Started (version 7.5.20)

Important

发出每个X RESTART命令后,请等到 ManagementClient 端报告Node X: Started (version ...) 之前,然后再 continue 进行操作。

您可以通过检查mysqlClient 端中的ndbinfo.nodestable 来验证是否使用更新后的配置重新启动了所有现有数据节点。

步骤 4:对所有集群 API 节点执行滚动重启. 使用mysqladmin shutdownmysqld_safe(或其他启动脚本)关闭并重启集群中充当 SQL 节点的每个 MySQL 服务器。这应该类似于此处显示的内容,其中* password *是给定 MySQL 服务器实例的 MySQL root密码:

shell> mysqladmin -uroot -ppassword shutdown
081208 20:19:56 mysqld_safe mysqld from pid file
/usr/local/mysql/var/tonfisk.pid ended
shell> 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

当然,确切的 Importing 和输出取决于系统上安装 MySQL 的方式和位置,以及选择启动它的选项(以及是否在my.cnf文件中指定了这些选项中的某些或全部)。

步骤 5:执行新数据节点的初始启动. 使用--initial选项从每个主机上的新数据节点的系统 Shell 中启动数据节点,如下所示:

shell> ndbd -c 198.51.100.10 --initial

Note

与重新启动现有数据节点的情况不同,您可以同时启动新的数据节点。您无需 await 一个完成就可以启动另一个。

await 直到两个新的数据节点都已启动,然后再 continue 进行下一步。新数据节点启动后,您可以在 ManagementClient 端SHOW命令的输出中看到它们尚未属于任何节点组(如此处的粗体所示):

ndb_mgm> SHOW
Connected to Management Server at: 198.51.100.10:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=1    @198.51.100.1  (5.7.31-ndb-7.5.20, Nodegroup: 0, *)
id=2    @198.51.100.2  (5.7.31-ndb-7.5.20, Nodegroup: 0)
id=3    @198.51.100.3  (5.7.31-ndb-7.5.20, no nodegroup)
id=4    @198.51.100.4  (5.7.31-ndb-7.5.20, no nodegroup)

[ndb_mgmd(MGM)] 1 node(s)
id=10   @198.51.100.10  (5.7.31-ndb-7.5.20)

[mysqld(API)]   2 node(s)
id=20   @198.51.100.20  (5.7.31-ndb-7.5.20)
id=21   @198.51.100.21  (5.7.31-ndb-7.5.20)

步骤 6:创建新的节点组. 您可以通过在集群 ManagementClient 端中发出CREATE NODEGROUP命令来完成此操作。此命令将新节点组中要包含的数据节点的节点 ID 的逗号分隔列 table 作为参数,如下所示:

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
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=1    @198.51.100.1  (5.7.31-ndb-7.5.20, Nodegroup: 0, *)
id=2    @198.51.100.2  (5.7.31-ndb-7.5.20, Nodegroup: 0)
id=3    @198.51.100.3  (5.7.31-ndb-7.5.20, Nodegroup: 1)
id=4    @198.51.100.4  (5.7.31-ndb-7.5.20, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=10   @198.51.100.10  (5.7.31-ndb-7.5.20)

[mysqld(API)]   2 node(s)
id=20   @198.51.100.20  (5.7.31-ndb-7.5.20)
id=21   @198.51.100.21  (5.7.31-ndb-7.5.20)

步骤 7:重新分配群集数据. 创建节点组后,现有数据和索引不会自动分配到新节点组的数据节点,如在 ManagementClient 端中发出相应的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)

通过将ndb_desc-p选项一起使用,这会导致输出包含分区信息,您可以看到该 table 仍仅使用 2 个分区(在输出的Per partition info部分中,此处以粗体显示):

shell> 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

NDBT_ProgramExit: 0 - OK

通过在mysqlClient 端中为每个NDBtable 执行ALTER TABLE ... ALGORITHM =插入,重新组织分区语句,可以使数据在所有数据节点之间重新分配。

Important

ALTER TABLE ... ALGORITHM=INPLACE, REORGANIZE PARTITION在使用MAX_ROWS选项创建的 table 上不起作用。而是使用ALTER TABLE ... ALGORITHM=INPLACE, MAX_ROWS=...重新组织此类 table。

请记住,在 NDB 7.5.4 及更高版本中,不建议使用MAX_ROWS设置每个 table 的分区数,而应改用PARTITION_BALANCE。有关更多信息,请参见第 13.1.18.9 节“设置 NDB_TABLE 选项”

发出语句ALTER TABLE ips ALGORITHM=INPLACE, REORGANIZE PARTITION之后,您可以使用ndb_desc看到该 table 的数据现在使用 4 个分区存储,如下所示(输出的相关部分以粗体显示):

shell> 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

NDBT_ProgramExit: 0 - OK

Note

通常,ALTER TABLE table_name [ALGORITHM = INPLACE,]重新组织分区与分区标识符列 table 和一组分区定义一起使用,以为已被显式分区的 table 创建新的分区方案。在这方面,它的 exception 是将数据重新分配到新的 NDB 群集节点组上。当以这种方式使用时,没有其他关键字或标识符跟随REORGANIZE PARTITION

有关更多信息,请参见第 13.1.8 节“ ALTER TABLE 语句”

此外,对于每个 table,在ALTER TABLE语句后应加上OPTIMIZE TABLE以回收浪费的空间。您可以使用针对INFORMATION_SCHEMA.TABLEStable 的以下查询来获取所有NDBCLUSTERtable 的列 table:

SELECT TABLE_SCHEMA, TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES
    WHERE ENGINE = 'NDBCLUSTER';

Note

NDB 群集 table 的INFORMATION_SCHEMA.TABLES.ENGINE值始终为NDBCLUSTER,无论用于创建 table 的CREATE TABLE语句(或用于从其他存储引擎转换现有 table 的ALTER TABLE语句)在其ENGINE选项中使用NDB还是NDBCLUSTER

所有报告 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)

Note

由于一次只能对NDBCLUSTERtable 执行一个 DDL 操作,因此在发出下一个语句之前,您必须 await 每个ALTER TABLE ...重新组织分区语句完成。

添加新数据节点后*,不必为创建的NDBCLUSTER个 table 发出ALTER TABLE ...重新组织分区语句;添加到此类 table 的数据会自动在所有数据节点之间分配。但是,在添加新节点之前存在的NDBCLUSTER个 table 中,使用新节点既不分发现有数据也不分发新数据,直到使用ALTER TABLE ...重新组织分区重新组织了这些 table。

替代方法,不进行滚动重启. 可以通过在首次启动集群时配置额外的数据节点而不是启动它们来避免进行滚动重启。像以前一样,我们假设您希望从一个节点组中的两个数据节点(节点 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)可以用节点组= 65536进行配置,在这种情况下,节点 1 和 2 可以分别启动,如下所示:

shell> ndbd -c 198.51.100.10 --initial

awaitStartNoNodeGroupTimeout数据节点配置参数的设置确定的一段时间后,Management 服务器将使用节点组= 65536配置的数据节点视为已使用--nowait-nodes=3,4启动了节点 1 和 2.默认情况下,这是 15 秒(15000 毫秒)。

Note

StartNoNodegroupTimeout对于集群中的所有数据节点必须相同;因此,您应该始终在config.ini文件的[ndbd default]部分中进行设置,而不是为单个数据节点进行设置。

准备添加第二个节点组时,只需执行以下附加步骤:

  • 启动数据节点 3 和 4,为每个新节点调用一次数据节点过程:
shell> ndbd -c 198.51.100.10 --initial
ndb_mgm> CREATE NODEGROUP 3,4