MySQL 5.7 组复制配置实践

MySQL组复制的配置实践
第一步是部署三个MySQL Server实例。Group Replication是MySQL Server 5.7.17及更新版本提供的内置MySQL插件。
下面的过程使用一台物理机器,因此每个MySQL服务器实例都需要一个特定的数据目录。在名为mysqldata的目录中创建数据目录,并对每个目录进行初始化。
创建三个数据目录

[mysql@localhost mysqldata]$ mkdir mysql1
[mysql@localhost mysqldata]$ mkdir mysql2
[mysql@localhost mysqldata]$ mkdir mysql3
[mysql@localhost mysqldata]$ ll
total 0
drwxr-xr-x. 2 mysql mysql 6 Jan 16 08:54 mysql1
drwxr-xr-x. 2 mysql mysql 6 Jan 16 08:55 mysql2
drwxr-xr-x. 2 mysql mysql 6 Jan 16 08:55 mysql3

创建三个实例的参数文件

[mysql@localhost mysql]# vi mysql1.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql1
bind-address=0.0.0.0
user=mysql
port=3306
log-error=/mysqldata/mysql1/mysql.err
pid-file=/mysqldata/mysql1/mysqld.pid
socket = /mysqldata/mysql1/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

[mysql@localhost mysql]$ vi mysql2.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql2
bind-address=0.0.0.0
user=mysql
port=3307
log-error=/mysqldata/mysql2/mysql.err
pid-file=/mysqldata/mysql2/mysqld.pid
socket = /mysqldata/mysql2/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB


[mysql@localhost mysql]$ vi mysql3.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql3
bind-address=0.0.0.0
user=mysql
port=3308
log-error=/mysqldata/mysql3/mysql.err
pid-file=/mysqldata/mysql3/mysqld.pid
socket = /mysqldata/mysql3/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

初始化三个实例

[root@localhost ~]# cd /mysqlsoft/mysql/bin
[root@localhost bin]# ./mysqld  --defaults-file=/mysqlsoft/mysql/mysql1.cnf --initialize -basedir=/mysqlsoft/mysql --

datadir=/mysqldata/mysql1 --user=mysql
[root@localhost bin]# ./mysqld  --defaults-file=/mysqlsoft/mysql/mysql2.cnf --initialize -basedir=/mysqlsoft/mysql --

datadir=/mysqldata/mysql2 --user=mysql
[root@localhost bin]# ./mysqld  --defaults-file=/mysqlsoft/mysql/mysql3.cnf --initialize -basedir=/mysqlsoft/mysql --

datadir=/mysqldata/mysql3 --user=mysql

[mysql@localhost mysql1]$ cat mysql.err
2025-01-16T02:45:38.125723Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --

explicit_defaults_for_timestamp server option (see documentation for more details).
2025-01-16T02:45:38.126190Z 0 [ERROR] Can't find error-message file 'asedir=/mysqlsoft/mysql/share/errmsg.sys'. Check error-

message file location and 'lc-messages-dir' configuration directive.
2025-01-16T02:45:38.535031Z 0 [Warning] InnoDB: New log files created, LSN=45790
2025-01-16T02:45:38.597593Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2025-01-16T02:45:38.658289Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this 

server has been started. Generating a new UUID: f81625c0-d3b3-11ef-9c8d-005056a390e6.
2025-01-16T02:45:38.659975Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2025-01-16T02:45:38.661884Z 1 [Note] A temporary password is generated for root@localhost: LplkX((&j1&u

[mysql@localhost mysql2]$ cat mysql.err
2025-01-16T02:45:51.143320Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --

explicit_defaults_for_timestamp server option (see documentation for more details).
2025-01-16T02:45:51.143570Z 0 [ERROR] Can't find error-message file 'asedir=/mysqlsoft/mysql/share/errmsg.sys'. Check error-

message file location and 'lc-messages-dir' configuration directive.
2025-01-16T02:45:51.439385Z 0 [Warning] InnoDB: New log files created, LSN=45790
2025-01-16T02:45:51.502171Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2025-01-16T02:45:51.561336Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this 

server has been started. Generating a new UUID: ffc6ff15-d3b3-11ef-9e2d-005056a390e6.
2025-01-16T02:45:51.562821Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2025-01-16T02:45:51.564054Z 1 [Note] A temporary password is generated for root@localhost: OM,#w?fll2iT


[mysql@localhost mysql3]$ cat mysql.err
2025-01-16T02:46:03.815721Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --

explicit_defaults_for_timestamp server option (see documentation for more details).
2025-01-16T02:46:03.815972Z 0 [ERROR] Can't find error-message file 'asedir=/mysqlsoft/mysql/share/errmsg.sys'. Check error-

message file location and 'lc-messages-dir' configuration directive.
2025-01-16T02:46:04.113214Z 0 [Warning] InnoDB: New log files created, LSN=45790
2025-01-16T02:46:04.171088Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2025-01-16T02:46:04.230517Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this 

server has been started. Generating a new UUID: 07542900-d3b4-11ef-a088-005056a390e6.
2025-01-16T02:46:04.232171Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2025-01-16T02:46:04.233327Z 1 [Note] A temporary password is generated for root@localhost: wlh%+FHw(7Sk

如果想服务能够部署自动支持安全连接,使用mysql_ssl_rsa_setup工具来创建缺省SSL与RSA文件

[root@localhost bin]# ./mysql_ssl_rsa_setup --datadir=/mysqldata/mysql1
Generating a 2048 bit RSA private key
...........+++
................................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
.+++
.......................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
...............................+++
........................+++
writing new private key to 'client-key.pem'
-----
[root@localhost bin]# ./mysql_ssl_rsa_setup --datadir=/mysqldata/mysql2
Generating a 2048 bit RSA private key
........................+++
........................................................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
................................+++
......................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
........................+++
......................................................................+++
writing new private key to 'client-key.pem'
-----
[root@localhost bin]# ./mysql_ssl_rsa_setup --datadir=/mysqldata/mysql3
Generating a 2048 bit RSA private key
........................................................................................................+++
...................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
..................................+++
.......................................................................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
..............................................+++
........................+++
writing new private key to 'client-key.pem'
-----

配置启动脚本

[mysql@localhost mysql]$ cat my.cnf
[mysqld_multi]
mysqld=/mysqlsoft/mysql/bin/mysqld_safe
mysqladmin =/mysqlsoft/mysql/bin/mysqladmin
log =/mysqlsoft/mysql/mysqld_multi.log

[mysqld1]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql1
bind-address=0.0.0.0
user=mysql
port=3306
log-error=/mysqldata/mysql1/mysql.err
pid-file=/mysqldata/mysql1/mysqld.pid
socket = /mysqldata/mysql1/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB
explicit_defaults_for_timestamp = true


[mysqld2]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql2
bind-address=0.0.0.0
user=mysql
port=3307
log-error=/mysqldata/mysql2/mysql.err
pid-file=/mysqldata/mysql2/mysqld.pid
socket = /mysqldata/mysql2/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB
explicit_defaults_for_timestamp = true


[mysqld3]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql3
bind-address=0.0.0.0
user=mysql
port=3308
log-error=/mysqldata/mysql3/mysql.err
pid-file=/mysqldata/mysql3/mysqld.pid
socket = /mysqldata/mysql3/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB
explicit_defaults_for_timestamp = true

[mysql@localhost mysql]$ mysqld_multi start 1,2,3


[mysql@localhost mysql]$ tail -f mysqld_multi.log 
mysqld_multi log file version 2.16; run: Thu Jan 16 11:12:08 2025



Starting MySQL servers

2025-01-16T03:17:42.956897Z mysqld_safe Logging to '/mysqldata/mysql1/mysql.err'.
2025-01-16T03:17:42.968830Z mysqld_safe Logging to '/mysqldata/mysql3/mysql.err'.
2025-01-16T03:17:42.971621Z mysqld_safe Logging to '/mysqldata/mysql2/mysql.err'.
2025-01-16T03:17:42.978298Z mysqld_safe Logging to '/mysqldata/mysql1/mysql.err'.
2025-01-16T03:17:42.984997Z mysqld_safe Logging to '/mysqldata/mysql2/mysql.err'.
2025-01-16T03:17:42.999744Z mysqld_safe Logging to '/mysqldata/mysql3/mysql.err'.
2025-01-16T03:17:43.014252Z mysqld_safe A mysqld process already exists
2025-01-16T03:17:43.026350Z mysqld_safe Starting mysqld daemon with databases from /mysqldata/mysql3
2025-01-16T03:17:43.026973Z mysqld_safe Starting mysqld daemon with databases from /mysqldata/mysql2
2025-01-16T03:17:43.032460Z mysqld_safe A mysqld process already exists
2025-01-16T03:17:43.042893Z mysqld_safe Starting mysqld daemon with databases from /mysqldata/mysql2
2025-01-16T03:17:43.058374Z mysqld_safe Starting mysqld daemon with databases from /mysqldata/mysql3

组复制服务器设置
要安装和使用组复制插件,您必须正确配置MySQL服务器实例。建议将配置存储在实例的配置文件中。下面为mysql1服务器配置。

[mysql@localhost mysql]$ cat mysql1.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql1
bind-address=0.0.0.0
user=mysql
port=3306
log-error=/mysqldata/mysql1/mysql.err
pid-file=/mysqldata/mysql1/mysqld.pid
socket = /mysqldata/mysql1/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

这些设置将MySQL服务器配置为使用前面创建的数据目录,以及服务器应该打开哪个端口并开始侦听传入的连接。

复制框架
以下设置根据“MySQL Group replication”的要求配置复制。

server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

这些设置将服务器配置为使用唯一标识符1,以启用全局事务标识符,并将复制元数据存储在系统表而不是文件中。此外,它指示服务器打开二进制日志记录,使用基于行的格式并禁用二进制日志事件校验和。

组复制设置
此时,mysql1.cnf文件确保配置了服务器,并指示在给定配置下实例化复制基础结构。以下部分为服务器配置组复制设置。

transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="2366d798-4dc1-421a-a9de-3c825bfada7d"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "127.0.0.1:24901"
loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
loose-group_replication_bootstrap_group= off

上面用于group_replication变量的loose前缀指示,如果在服务器启动时没有加载Group Replication插件,则服务器继续启动。
.第1行指示服务器,对于每个事务,它必须收集写集,并使用XXHASH64散列算法将其编码为散列。

.第2行告诉插件它要加入或创建的组的名称为“2366d798-4dc1-421a-a9de-3c825bfada7d”。

.第3行指示插件在服务器启动时不要自动启动操作。

.第4行告诉插件使用IP地址127.0.0.1或localhost和端口24901来处理来自组中其他成员的传入连接。
服务器在这个端口上监听成员到成员的连接。此端口绝对不能用于用户应用程序,必须在运行组复制时为组的不同成员之间的通信保留该端口。

group_replication_local_address配置的本地地址必须对所有组成员都可访问。例如,如果每个服务器实例都在不同的机器上,则使用该机器的IP和端口,例如10.0.0.1:33061。group_replication_local_address的推荐端口是33061,但是在本教程中,我们使用在一台机器上运行的三个服务器实例,因此使用端口24901到24903。

.第5行告诉插件,如果需要加入组,应该联系这些主机和端口上的以下成员。这些是种子成员,当该成员想要连接到组时使用。在加入时,服务器首先与其中一个(种子)联系,然后要求组重新配置以允许加入服务器被组接受。请注意,此选项不需要列出组中的所有成员,而是在此服务器希望加入组时应该联系的服务器列表。

启动组的服务器不使用此选项,因为它是初始服务器,因此它负责引导组。第二个服务器加入要求组中唯一的成员加入,然后扩展组。第三个服务器加入可以请求这两个服务器中的任何一个加入,然后这个群组再次扩展。后续服务器在加入时重复此过程。

当同时加入多个服务器时,确保它们指向已经在组中的种子成员。不要使用正在加入组的成员作为种子,因为他们在联系时可能还不在组中。

最好的做法是先启动bootstrap成员,然后让它创建组。然后将其作为其他加入的成员的种子成员。这确保在加入其他成员时形成一个组。

不支持创建群组并同时加入多个成员。它可能会起作用,但很可能是操作竞争,然后加入组的行为以错误或超时告终。

.第6行指示插件是否启动组
此选项在任何时候都只能在一个服务器实例上使用,通常是在您第一次引导组时(或者在整个组被关闭并重新启动的情况下)。如果您多次引导组,例如当多个服务器实例设置了此选项时,那么它们可能会创建一个人工分裂的大脑场景,其中存在两个具有相同名称的不同组。在第一个服务器实例联机后禁用此选项。

组中所有服务器的配置非常相似。需要修改每个服务器的具体信息(例如server_id、datadir、group_replication_local_address)。

用户凭证
“组复制”通过异步复制协议实现分布式恢复,在组成员加入组之前先同步组成员。分布式恢复进程依赖于一个名为group_replication_recovery的复制区域通道,该区域通道用于在组成员之间传输事务。因此,需要设置具有相应权限的复制用户,以便Group replication建立成员间直接恢复复制通道。

[mysql@localhost mysql]$ mysqld --defaults-file=/mysqlsoft/mysql/mysql1.cnf &

创建一个具有REPLICATION-SLAVE权限的MySQL用户。不应该在二进制日志中捕获此过程,以避免将更改传播到其他服务器实例。在下面的示例中,显示了用户rpl_user和密码password。在配置服务器时,请使用合适的用户名和密码。连接到服务器mysql1,发出以下语句:

[root@localhost bin]# mysql -h 10.138.130.250 -P 3306 -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)

按照上述方式配置用户后,使用CHANGE MASTER TO语句配置服务器,以便在下一次需要从另一个成员恢复其状态时,为group_replication_recovery复制通道使用给定的凭据。执行以下命令,将rpl_user和password替换为创建用户时使用的值。

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.03 sec)

分布式恢复是加入组的服务器所采取的第一步。如果这些凭据设置不正确,服务器将无法运行恢复过程并获得与其他组成员的同步,因此最终无法加入组成员。类似地,如果成员不能通过服务器的主机名正确识别其他成员,则恢复过程可能会失败。建议运行MySQL的操作系统使用正确配置的唯一主机名,可以使用DNS或本地设置。这个主机名可以在performance_schema.replication_group_members表的Member_host列中进行验证。如果多个组成员外部化操作系统设置的默认主机名,则成员有可能无法解析到正确的成员地址,从而无法加入组。在这种情况下,使用report_host配置一个唯一的主机名,由每个服务器外部化。

启动组复制
配置并启动服务mysql1后,安装Group Replication插件。连接到服务器并发出以下命令:

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.06 sec)

重点:
mysql.session在加载组复制之前必须已经存在。mysql.ession在MySQL 5.7.19版本中被添加。如果您的数据字典是使用较早版本初始化的,则必须运行mysql_upgrade过程。如果不执行升级,则启动“组复制”失败,并提示错误信息

There was an error when trying to access the server with
user: mysql.session@localhost. Make sure the user is present
in the server and that mysql_upgrade was ran after a server
update..

要检查插件是否已成功安装,请执行SHOW PLUGINS;然后检查输出。它应该显示如下内容:

mysql> SHOW PLUGINS;
+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ngram                      | ACTIVE   | FTPARSER           | NULL                 | GPL     |
| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+
45 rows in set (0.01 sec)

要启动组,请指示服务器mysql1引导组,然后启动组复制。这个引导应该只由单个服务器完成,即启动组的服务器,并且只能一次。这就是为什么引导配置选项的值没有保存在配置文件中。如果将其保存在配置文件中,则重启后服务器将自动引导具有相同名称的第二个组。这将导致两个具有相同名称的不同组。同样的道理也适用于将此选项设置为ON时停止和重新启动插件。

mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (2.09 sec)

mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)

一旦START GROUP_REPLICATION语句返回,这个组就已经启动了。你可以检查组现在已经创建,并且里面有一个成员:

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | f81625c0-d3b3-11ef-9c8d-005056a390e6 | mysqlcs     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.01 sec)

该表中的信息确认组中有一个具有唯一标识符f81625c0-d3b3-11ef-9c8d-005056a390e6的成员,它是ONLINE的,并且在mysqlcs上监听端口3306上的客户端连接。
为了演示服务器确实在一个组中,并且它能够处理负载,创建一个表并向其中添加一些内容。

mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.01 sec)

mysql> USE test;
Database changed
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0.04 sec)

检查表t1和二进制日志的内容。

mysql> SELECT * FROM t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)


mysql> SHOW BINLOG EVENTS;
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.26-log, Binlog ver: 4                              |
| binlog.000001 | 123 | Previous_gtids |         1 |         150 |                                                                    |
| binlog.000001 | 150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:1'  |
| binlog.000001 | 211 | Query          |         1 |         301 | CREATE DATABASE test                                               |
| binlog.000001 | 301 | Gtid           |         1 |         362 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:2'  |
| binlog.000001 | 362 | Query          |         1 |         486 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 | 486 | Gtid           |         1 |         547 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:3'  |
| binlog.000001 | 547 | Query          |         1 |         615 | BEGIN                                                              |
| binlog.000001 | 615 | Table_map      |         1 |         658 | table_id: 108 (test.t1)                                            |
| binlog.000001 | 658 | Write_rows     |         1 |         700 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 | 700 | Xid            |         1 |         727 | COMMIT /* xid=23 */                                                |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
11 rows in set (0.00 sec)

如上所述,创建了数据库和表对象,并将它们对应的DDL语句写入二进制日志。此外,还将数据插入表并写入二进制日志。下一节将说明二进制日志条目的重要性,当组增长时,当新成员试图赶上并联机时,将执行分布式恢复。
向组中添加实例
此时,组中有一个成员服务器mysql1,其中包含一些数据。现在是时候通过添加前面配置的另外两个服务器来扩展组了。
添加第二个实例
为了添加第二个实例,服务器mysql2,首先为它创建配置文件。该配置类似于服务器mysql1所使用的配置,除了数据目录的位置、mysql2将要侦听的端口或其server_id等内容。这些不同的行在下面的清单中突出显示。
[mysql@localhost mysql]$ vi mysql2.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql2
bind-address=0.0.0.0
user=mysql
port=3307
log-error=/mysqldata/mysql2/mysql.err
pid-file=/mysqldata/mysql2/mysqld.pid
socket = /mysqldata/mysql2/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="2366d798-4dc1-421a-a9de-3c825bfada7d"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "127.0.0.1:24902"
loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
loose-group_replication_bootstrap_group= off

与服务器mysql1的过程类似,配置文件就绪后启动服务器

[mysql@localhost mysql]$ mysqld --defaults-file=/mysqlsoft/mysql/mysql2.cnf &

然后配置恢复凭据,如下所示。这些命令与将服务器mysql1设置为用户在组内共享时使用的命令相同。在mysql2上发表以下声明。

[root@localhost /]#  mysql -h 10.138.130.250 -P 3307 -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

安装Group Replication插件并启动将服务器加入组的过程。下面的示例以与部署服务器mysql1时相同的方式安装插件。

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW PLUGINS;
+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ngram                      | ACTIVE   | FTPARSER           | NULL                 | GPL     |
| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+
45 rows in set (0.01 sec)

将服务器mysql2加入组。

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (5.85 sec)

与之前在mysql1在执行的步骤不相同,差异在于没有执行SET GLOBAL group_replication_bootstrap_group=ON;在启动组复制之前,因为组已经创建并且由服务器mysql1启动。所以这时服务器mysql2只需要被加入到现有的组中。

当组复制成功启动并且服务器加入组时,它会检查super_read_only变量。通过在成员的配置文件中将super_read_only设置为ON,可以确保在启动Group Replication时由于任何原因而失败的服务器不接受事务。如果服务器应该作为读写实例加入组,例如作为单主组中的主实例或作为多主组的成员,当super_read_only变量设置为ON时,则在加入组时将其设置为OFF。

检查performance_schema.replication_group_members表再次显示,现在组中有两个ONLINE服务器。

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | f81625c0-d3b3-11ef-9c8d-005056a390e6 | mysqlcs     |        3306 | ONLINE       |
| group_replication_applier | ffc6ff15-d3b3-11ef-9e2d-005056a390e6 | mysqlcs     |        3307 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
2 rows in set (0.00 sec)

由于服务器mysql2也被标记为ONLINE,它一定已经自动赶上了服务器mysql1。验证它确实已与服务器mysql1同步,如下所示。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> select * from test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)

mysql> SHOW BINLOG EVENTS;
+---------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+---------------+-----+----------------+-----------+-------------+---------------------------------------+
| binlog.000001 |   4 | Format_desc    |         2 |         123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| binlog.000001 | 123 | Previous_gtids |         2 |         150 |                                       |
+---------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)

如上所述,第二台服务器已添加到组中,并且它自动复制了服务器mysql1的更改。根据分布式恢复过程,这意味着在加入组之后,在被声明为在线之前,服务器mysql2已经自动连接到服务器mysql1,并从中获取丢失的数据。换句话说,它从它缺失的二进制日志mysql1中复制事务,直到它加入组的时间点。

添加其他实例
向组中添加更多实例的步骤基本上与添加第二台服务器时相同,只是配置需要像为服务器mysql2 操作那样进行更改。要总结所需的命令:
1.修改配置文件

[mysql@localhost mysql]$ vi mysql3.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql3
bind-address=0.0.0.0
user=mysql
port=3308
log-error=/mysqldata/mysql3/mysql.err
pid-file=/mysqldata/mysql3/mysqld.pid
socket = /mysqldata/mysql3/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="2366d798-4dc1-421a-a9de-3c825bfada7d"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "127.0.0.1:24903"
loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
loose-group_replication_bootstrap_group= off

2.启动服务器

[mysql@localhost mysql]$ mysqld --defaults-file=/mysqlsoft/mysql/mysql3.cnf &

3.配置group_replication_recovery通道的恢复凭据。

[root@mysqlcs ~]# mysql -h 10.138.130.250 -P 3308 -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%';
ERROR 1396 (HY000): Operation CREATE USER failed for 'rpl_user'@'%'
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

4.安装Group Replication插件并启动它。

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.02 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (3.29 sec)

此时,服务器mysql3已经启动并运行,加入了组,并赶上了组中的其他服务器。查询performance_schema。Replication_group_members表再次

证实了这一点。

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 07542900-d3b4-11ef-a088-005056a390e6 | mysqlcs     |        3308 | ONLINE       |
| group_replication_applier | f81625c0-d3b3-11ef-9c8d-005056a390e6 | mysqlcs     |        3306 | ONLINE       |
| group_replication_applier | ffc6ff15-d3b3-11ef-9e2d-005056a390e6 | mysqlcs     |        3307 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)

在服务器mysql2或服务器mysql1上执行相同的查询会产生相同的结果。此外,您可以验证服务器mysql3也赶上了:

mysql> SHOW DATABASES LIKE 'test';
+-----------------+
| Database (test) |
+-----------------+
| test            |
+-----------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)

mysql> SHOW BINLOG EVENTS;
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos  | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |    4 | Format_desc    |         3 |         123 | Server ver: 5.7.26-log, Binlog ver: 4                              |
| binlog.000001 |  123 | Previous_gtids |         3 |         150 |                                                                    |
| binlog.000001 |  150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:1'  |
| binlog.000001 |  211 | Query          |         1 |         301 | CREATE DATABASE test                                               |
| binlog.000001 |  301 | Gtid           |         1 |         362 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:2'  |
| binlog.000001 |  362 | Query          |         1 |         486 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 |  486 | Gtid           |         1 |         547 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:3'  |
| binlog.000001 |  547 | Query          |         1 |         606 | BEGIN                                                              |
| binlog.000001 |  606 | Table_map      |         1 |         649 | table_id: 108 (test.t1)                                            |
| binlog.000001 |  649 | Write_rows     |         1 |         691 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 |  691 | Xid            |         1 |         718 | COMMIT /* xid=26 */                                                |
| binlog.000001 |  718 | Gtid           |         1 |         779 | SET @@SESSION.GTID_NEXT= '2366d798-4dc1-421a-a9de-3c825bfada7d:1'  |
| binlog.000001 |  779 | Query          |         1 |         838 | BEGIN                                                              |
| binlog.000001 |  838 | View_change    |         1 |         977 | view_id=17375148526840614:1                                        |
| binlog.000001 |  977 | Query          |         1 |        1042 | COMMIT                                                             |
| binlog.000001 | 1042 | Gtid           |         1 |        1103 | SET @@SESSION.GTID_NEXT= '2366d798-4dc1-421a-a9de-3c825bfada7d:2'  |
| binlog.000001 | 1103 | Query          |         1 |        1162 | BEGIN                                                              |
| binlog.000001 | 1162 | View_change    |         1 |        1341 | view_id=17375148526840614:2                                        |
| binlog.000001 | 1341 | Query          |         1 |        1406 | COMMIT                                                             |
| binlog.000001 | 1406 | Gtid           |         1 |        1467 | SET @@SESSION.GTID_NEXT= '2366d798-4dc1-421a-a9de-3c825bfada7d:3'  |
| binlog.000001 | 1467 | Query          |         1 |        1526 | BEGIN                                                              |
| binlog.000001 | 1526 | View_change    |         1 |        1705 | view_id=17375148526840614:3                                        |
| binlog.000001 | 1705 | Query          |         1 |        1770 | COMMIT                                                             |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
23 rows in set (0.00 sec)

发表评论

电子邮件地址不会被公开。