组复制是一种可用于实现容错系统的技术。复制组是一个通过消息传递相互交互的服务器组。通信层提供了很多保证,例如原子消息和总消息序号的传递。通过这些强大的特性,我们可以构建更高级的数据库复制解决方案。 MySQL组复制构建在这些属性和抽象之上,并实现多主复制协议的更新。实质上,复制组由多个数据库实例组成,并且组中的每个实例都可以独立地执行事务。但是所有读写(RW)事务只有在被组批准后才会提交。只读(RO)事务不需要在组内协调,因此立即提交。换句话说,对于任何RW事务,组需要决定是否提交,因此提交操作不是来自始发服务器的单向决定。准确地说,当事务准备好在始发服务器上提交时,该始发服务器原子地广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后为该事务建立一个全局总序号。最终,这意味着所有服务器以相同的顺序接收同一组事务。因此,所有服务器以相同的顺序应用相同的一组更改,因此它们在组内保持一致。
组复制原理图:
实验环境: Server1:172.25.254.1
Server2:172.25.254.2
Server3:172.25.254.3
Server1:
[root@server1 ~]# /etc/init.d/mysqld stop
Stopping mysqld: [ OK ]
[root@server1 ~]#
[root@server1 ~]# cd /var/lib/mysql
[root@server1 mysql]# ls
auto.cnf ibdata1 mysql-bin.000003 public_key.pem
ca-key.pem ib_logfile0 mysql-bin.000004 server-cert.pem
ca.pem ib_logfile1 mysql-bin.000005 server-key.pem
client-cert.pem mysql mysql-bin.index sys
client-key.pem mysql-bin.000001 performance_schema test
ib_buffer_pool mysql-bin.000002 private_key.pem
[root@server1 mysql]# rm -fr *
[root@server1 mysql]# ls
[root@server1 mysql]# vim /etc/my.cnf
#########################################################################
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
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
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="caa095c2-9c39-11e8-9b6d-52540082b956"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.1:24901"
loose-group_replication_group_seeds="172.25.254.1:24901,172.25.254.2:24901,172.25.254.3:24901"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=off
loose-group_replication_enforce_update_everwhere_checks=on
loose-group_replication_ip_whitelist="172.25.254.0/24,127.0.0.1/8"
###########################################################################################
[root@server1 ~]# /etc/init.d/mysqld start
Initializing MySQL database: [ OK ]
Installing validate password plugin: [ OK ]
Starting mysqld: [ OK ]
[root@server1 ~]# grep password /var/log/mysqld.log
2018-08-10T14:25:30.087177Z 1 [Note] A temporary password is generated for root@localhost: aBAhLl!Ju9*k
[root@server1 ~]# mysql -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.17-log
Copyright (c) 2000, 2016, 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> alter user root@localhost identified by 'XDwestos+007';
Query OK, 0 rows affected (0.15 sec)
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* to rpl_user@'%' identified by 'XDwestos+007';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> reset master;
Query OK, 0 rows affected (0.68 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='XDwestos+007' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (1.17 sec)
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.51 sec)
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 (4.01 sec)
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 3b6cc83f-9ca9-11e8-b726-525400ce4b2a | server1 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.08 sec)
Server2:
[root@server2 mysql]# rm -fr *
[root@server2 mysql]# ls
[root@server2 mysql]# vim /etc/my.cnf
#################################################################################################
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="caa095c2-9c39-11e8-9b6d-52540082b956"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.2:24901"
loose-group_replication_group_seeds="172.25.254.1:24901,172.25.254.2:24901,172.25.254.3:24901"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=off
loose-group_replication_enforce_update_everwhere_checks=on
loose-group_replication_ip_whitelist="172.25.254.0/24,127.0.0.1/8"
###################################################################################################
[root@server2 ~]# /etc/init.d/mysqld start
Starting mysqld: [ OK ]
[root@server2 ~]# grep password /var/log/mysqld.log
2018-08-10T14:43:12.022235Z 1 [Note] A temporary password is generated for root@localhost: aVj,KAs&Z94g
[root@server2 ~]# mysql -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.17-log
Copyright (c) 2000, 2016, 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> alter user root@localhost identified by 'XDwestos+007';
Query OK, 0 rows affected (0.19 sec)
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* to rpl_user@'%' identified by 'XDwestos+007';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> reset master;
Query OK, 0 rows affected (0.51 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='XDwestos+007' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (1.26 sec)
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.37 sec)
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (7.17 sec)
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 3b6cc83f-9ca9-11e8-b726-525400ce4b2a | server1 | 3306 | ONLINE |
| group_replication_applier | b49eda52-9cab-11e8-8c52-525400cb8faf | server2 | 3306 | ONLINE |
Server3:
[root@server3 mysql]# rm -fr *
[root@server3 mysql]# ls
[root@server3 mysql]# vim /etc/my.cnf
###########################################################################################
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="caa095c2-9c39-11e8-9b6d-52540082b956"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.3:24901"
loose-group_replication_group_seeds="172.25.254.1:24901,172.25.254.2:24901,172.25.254.3:24901"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=off
loose-group_replication_enforce_update_everwhere_checks=on
loose-group_replication_ip_whitelist="172.25.254.0/24,127.0.0.1/8"
################################################################################################
[root@server3 ~]# /etc/init.d/mysqld start
Starting mysqld: [ OK ]
[root@server3 ~]# grep password /var/log/mysqld.log
2018-08-10T14:54:43.495899Z 1 [Note] A temporary password is generated for root@localhost: okipri9&8iiI
[root@server3 ~]# mysql -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.17-log
Copyright (c) 2000, 2016, 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> alter user root@localhost identified by 'XDwestos+007';
Query OK, 0 rows affected (0.16 sec)
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* to rpl_user@'%' identified by 'XDwestos+007';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> reset master;
Query OK, 0 rows affected (0.54 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='XDwestos+007' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (1.52 sec)
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.31 sec)
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (4.35 sec)
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 3b6cc83f-9ca9-11e8-b726-525400ce4b2a | server1 | 3306 | ONLINE |
| group_replication_applier | 50c1a66e-9cad-11e8-9b32-525400b0e319 | server3 | 3306 | ONLINE |
| group_replication_applier | b49eda52-9cab-11e8-8c52-525400cb8faf | server2 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
测试:(1)当对Server1进行操作时:(server2和server3同步复制)
mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.11 sec)
mysql> USE test;
Database changed
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
Query OK, 0 rows affected (0.95 sec)
mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0.46 sec)
mysql> SELECT * FROM t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
+----+------+
1 row in set (0.00 sec)
Server2:
mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1 |
+----------------+
1 row in set (0.00 sec)
mysql> select * from t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
+----+------+
1 row in set (0.00 sec)
Server3:
mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from test.t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
+----+------+
1 row in set (0.00 sec)
(2)当对Server3进行操作时(server1和server2同步复制)
mysql> INSERT INTO test. t1 VALUES (2, 'xixi');
Query OK, 1 row affected (0.67 sec)
Server1:
mysql> SELECT * FROM t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
| 2 | xixi |
+----+------+
Server2:
mysql> select * from t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
| 2 | xixi |
+----+------+
(3)当对Server2进行操作时(server1和server3同步复制)
mysql> INSERT INTO test. t1 VALUES (6, 'haha');
Query OK, 1 row affected (0.48 sec)
Server1:
mysql> SELECT * FROM t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
| 2 | xixi |
| 6 | haha |
+----+------+
Server3:
mysql> select * from test.t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
| 2 | xixi |
| 6 | haha |
+----+------+
3 rows in set (0.00 sec)