一,什么是多源复制:
multi-source
是不同的。简单的说,多源复制就是将多个主库同步到一个从库上面,从而增加从的利用率,节省了机器。如下图:
多源复制使用场景
- 数据分析部门会需要各个业务部门的部分数据做数据分析,这个时候就可以用到多源复制把各个主数据库的数据复制到统一的数据库中。
- 在从服务器进行数据汇总,如果我们的主服务器进行了分库分表的操作,为了实现后期的一些数据统计功能,往往需要把数据汇总在一起再统计。
- 在从服务器对所有主服务器的数据进行备份,在MySQL 5.7之前每一个主服务器都需要一个从服务器,这样很容易造成资源浪费,同时也加大了DBA的维护成本,但MySQL 5.7引入多源复制,可以把多个主服务器的数据同步到一个从服务器进行备份。
使用多源复制的必要条件
不管是使用基于二进制日志的复制或者基于事务的复制,要开启多源复制功能必须需要在从库上设置 master-info-repository
和 relay-log-info-repository
这两个参数。
这两个参数是用来存储同步信息的,可以设置的值为 FILE
和 TABLE
,默认值是 FILE
。比如 master-info
就保存在 master.info
文件中, relay-log-info
保存在 relay-log.info
文件中,如果服务器意外关闭,正确的 relay-log-info
没有来得及更新到 relay-log.info
文件,这样会造成数据丢失。
为了数据更加安全,通常设为 TABLE
。这些表都是 innodb
类型的,支持事务。相对文件存储安全得多。在 MySQL 库下可以看见这两个表信息,分别是 mysql.slave_master_info
和 mysql.slave_relay_log_info
。
这两个参数也是可以动态调整的。
SET GLOBAL master_info_repository = ‘TABLE’;
SET GLOBAL relay_log_info_repository = ‘TABLE’;
或者直接写到MySQL的配置文件中
如果要启用 enhanced multi-threaded slave
(多线程复制),可以设置以下参数
slave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=8
relay_log_recovery=ON
二,实践
环境准备
在这里为了方便,在一台机器中起了3个MySQL的docker实例,MySQL版本都为8.0.24。
name IP地址 MySQL角色
master01 192.168.0.62:11111 MySQL 主库
master02 192.168.0.62:22222 MySQL 主库
slave-01 192.168.0.62:33333 MySQL 从库
mkdir -p /data/mysql8-master01/{data,conf,mysql-files,log}
mkdir -p /data/mysql8-master02/{data,conf,mysql-files,log}
mkdir -p /data/mysql8-slave01/{data,conf,mysql-files,log}
准备好下面的配置文件并启动MySQL
1)master01
[root@lb_master data]# cat /data/mysql8-master01/conf/my.cnf [client] port = 3306 default-character-set = utf8mb4 [mysql] port = 3306 default-character-set = utf8mb4 [mysqld] ########################## ########################## # log bin ########################## server-id = 1 #必须唯一 log_bin = mysql-bin #开启及设置二进制日志文件名称 binlog_format = ROW binlog_expire_logs_seconds=604800 max_connections=10000 max_connect_errors = 6000 max_allowed_packet = 100M wait_timeout = 28800
docker run \
--restart=always \
-v /etc/localtime:/etc/localtime:ro \
--name mysql8-master01 \
-v /data/mysql8-master01/data:/var/lib/mysql \
-v /data/mysql8-master01/conf:/etc/mysql \
-v /data/mysql8-master01/mysql-files:/var/lib/mysql-files \
-v /data/mysql8-master01/log:/var/log \
-p 11111:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:latest
2)master02
[root@lb_master ~]# cat /data/mysql8-master02/conf/my.cnf [client] port = 3306 default-character-set = utf8mb4 [mysql] port = 3306 default-character-set = utf8mb4 [mysqld] ########################## ########################## # log bin ########################## server-id = 2 #必须唯一 log_bin = mysql-bin #开启及设置二进制日志文件名称 binlog_format = ROW binlog_expire_logs_seconds=604800 max_connections=10000 max_connect_errors = 6000 max_allowed_packet = 100M wait_timeout = 28800
docker run \
--restart=always \
-v /etc/localtime:/etc/localtime:ro \
--name mysql8-master02 \
-v /data/mysql8-master02/data:/var/lib/mysql \
-v /data/mysql8-master02/conf:/etc/mysql \
-v /data/mysql8-master02/mysql-files:/var/lib/mysql-files \
-v /data/mysql8-master02/log:/var/log \
-p 22222:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:latest
3)slave01
[root@lb_master ~]# cat /data/mysql8-slave01/conf/my.cnf [client] port = 3306 default-character-set = utf8mb4 [mysql] port = 3306 default-character-set = utf8mb4 [mysqld] ########################## ########################## # log bin ########################## server-id = 3 #必须唯一 #log_bin = mysql-bin #开启及设置二进制日志文件名称 #binlog_format = ROW #binlog_expire_logs_seconds=604800 master_info_repository = table relay_log_info_repository = table replicate-do-db = nba replicate-do-db = cba replicate_wild_do_table=nba.% replicate_wild_do_table=cba.% slave-parallel-type=LOGICAL_CLOCK slave-parallel-workers=8 relay_log_recovery=ON max_connections=10000 max_connect_errors = 6000 max_allowed_packet = 100M wait_timeout = 28800
docker run \
--restart=always \
-v /etc/localtime:/etc/localtime:ro \
--name mysql8-slave01 \
-v /data/mysql8-slave01/data:/var/lib/mysql \
-v /data/mysql8-slave01/conf:/etc/mysql \
-v /data/mysql8-slave01/mysql-files:/var/lib/mysql-files \
-v /data/mysql8-slave01/log:/var/log \
-p 33333:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:latest
=====================================================
在两台MySQL Master上创建具有复制权限的用户,mysql8和mysql5的版本不一样,具体操作如下:
mysql> use mysql; 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> create user 'rep'@'%' identified by '123456'; Query OK, 0 rows affected (0.03 sec) mysql> alter user 'rep'@'%' identified with mysql_native_password by '123456'; Query OK, 0 rows affected (0.01 sec) mysql> grant replication slave on *.* to 'rep'@'%'; Query OK, 0 rows affected (0.01 sec) mysql> flush privileges; Query OK, 0 rows affected (0.01 sec)
在 MySQL 从服务器上执行
1)设置同步源到 Master01 (在 MySQL 从服务器上执行)
CHANGE MASTER TO
MASTER_HOST='192.168.0.62',
MASTER_PORT=11111,
MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=1155
for channel 'master01';
2)设置同步源到 Master02 (在 MySQL 从服务器上执行)
CHANGE MASTER TO
MASTER_HOST='192.168.0.62',
MASTER_PORT=22222,
MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=1154
for channel 'master02';
3)
启动所有SLAVE
mysql> START SLAVE;
也可以单独启动需要同步的通道。
mysql> START SLAVE FOR CHANNEL 'master01';
mysql> START SLAVE FOR CHANNEL 'master02';
如果要查看单一信道的复制的详细状态,可以使用以下命令:
mysql> SHOW SLAVE STATUS FOR CHANNEL 'master01'\G;
=================================
测试多源复制在主库(master01和master02)实例创建一些数据
master01
create database nba;
CREATE TABLE `Lakers` ( `id` int(4) NOT NULL AUTO_INCREMENT,`name` char(20) NOT NULL,PRIMARY KEY(`id`));
insert into Lakers values(1,'kobe');
master02
create database cba;
CREATE TABLE `beijing` ( `id` int(4) NOT NULL AUTO_INCREMENT,`name` char(20) NOT NULL,PRIMARY KEY(`id`));
insert into beijing values(2,'sun2');
在从库(slave-01)实例检查数据是否成功复制。
参考:
https://www.hi-linux.com/posts/61083.html