强烈要求先看【基于二进制日志文件位置的复制】再看这个
为了方便测试,这里使用docker运行测试
参考文档
环境版本说明
Ubuntu 20.04
Docker 19.03.13
MySQL: 8.0.26
db1: 主服务master
db2: 从服务slave
MySQL复制
- 数据库复制本质上就是数据同步。MySQL 数据库是基于二进制日志(binary log)进行数据增量同步,而二进制日志记录了所有对于 MySQL 数据库的修改操作。
MySQL复制类型
异步复制
- GTID复制是异步复制,Master不关心Slave是否接收到二进制日志,所以Master与Slave没有任何的依赖关系。异步复制的性能最好,如果业务对于数据一致性要求不高,当发生故障时,能容忍数据的丢失,甚至大量的丢失,推荐用异步复制
安装
拉取MySQL Docker Image
docker pull mysql:8.0.26
获取默认的my.cnf
- 启动mysql
docker run -d -p 3306:3306 --name mysql-get-conf -e MYSQL_ROOT_PASSWORD="root" mysql:8.0.26
- 复制配置文件到本机
docker cp mysql-get-conf:/etc/mysql/my.cnf ./
- 删除获取配置的容器
docker rm -f mysql-get-conf
- 复制配置文件
# 根据个人实际情况放置配置文件
mkdir /home/dong/db1 /home/dong/db2
cp my.cnf /home/dong/db1
cp my.cnf /home/dong/db2
启动MySQL容器
- docker网络配置
# 查看
docker network ls
# 创建
docker network create db-net
- 启动
docker run --name db1 -v /home/dong/db1/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=root -d --network db-net mysql:8.0.26
docker run --name db2 -v /home/dong/db2/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=root -d --network db-net mysql:8.0.26
- 查看运行状态
dong@DESKTOP:~$ docker ps | grep mysql
84e7e0887bc6 mysql:8.0.26 "docker-entrypoint.s…" 28 seconds ago Up 27 seconds 3306/tcp, 33060/tcp db2
c6989e437e61 mysql:8.0.26 "docker-entrypoint.s…" 34 seconds ago Up 33 seconds 3306/tcp, 33060/tcp db1
- 其他命令
# 连接容器数据库
docker exec -it db1 mysql -uroot -proot
# 查看容器目录
docker exec -it db1 ls
修改配置
主服务配置
# vim /home/dong/db1/my.cnf
# 添加下面的配置
server_id = 1 # 在二进制日志时复制模式下要唯一
gtid_mode = ON # 开启GTID模式
enforce_gtid_consistency = ON # 强制执行 GTID 一致性
binlog_gtid_simple_recovery = ON # 控制MySQL启动或重新启动时在搜索GTID期间二进制日志文件的重复方式
relay_log_recovery = ON # 启动时使用中继日志恢复
- server_id说明:dev.mysql.com/doc/refman/…
- gtid_mode说明:dev.mysql.com/doc/refman/…
- enforce_gtid_consistency说明: dev.mysql.com/doc/refman/…
- binlog_gtid_simple_recovery说明: dev.mysql.com/doc/refman/…
- relay_log_recovery说明: dev.mysql.com/doc/refman/…
重启服务
# 重启
docker restart db1
# 查看
docker ps | grep mysql
创建用户,用于同步复制数据
# 登录数据
docker exec -it db1 mysql -uroot -proot
# 注意:这里使用mysql_native_password认证, MySQL8默认认证需要使用SSL, 这里为了方便所以使用mysql_native_password认证
# 创建用户
CREATE USER repl_user@'%' IDENTIFIED WITH mysql_native_password BY 'repl*User123';
# 设置权限
Grant replication slave on *.* to 'repl_user'@'%';
# 刷新
flush privileges;
创建测试数据
# 创建数据
CREATE DATABASE `blog` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 使用表
use blog;
# 创建表
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# 插入数据
insert into user (username) values("test1");
insert into user (username) values("test2");
# 查看数据
select * from user;
查看master status
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------------------------------+
| binlog.000003 | 2955 | | | 81e99d09-f5f5-11eb-8a5a-0242ac120002:1-11 |
+---------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec)
备份主服务器数据
# 登录容器
docker exec -it db1 bash
# 执行导出
mysqldump -uroot -proot --single-transaction --databases blog > /tmp/db.sql
# 复制到本地
docker cp db1:/tmp/db.sql ./
# db.sql说明; 数据库当前gtid是 xxx0002:1-11, 新增的会基本这个后面写入, 保证数据不重复和不丢失, 和上面master status Gtid对应(Gtid操作数据库会变)
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '81e99d09-f5f5-11eb-8a5a-0242ac120002:1-11';
从服务器配置
配置
# vim /home/dong/db2/my.cnf
[mysqld]
server_id = 2 # 在二进制日志时复制模式下要唯一
gtid_mode = ON # 开启GTID模式
enforce_gtid_consistency = ON # 强制执行 GTID 一致性
binlog_gtid_simple_recovery = ON # 控制MySQL启动或重新启动时在搜索GTID期间二进制日志文件的重复方式
relay_log_recovery = ON # 启动时使用中继日志恢复
重启
docker restart db2
导入数据
复制数据到容器
docker cp db.sql db2:/tmp
# 登录MySQL
docker exec -it db2 mysql -uroot -proot
# 导入
source /tmp/db.sql
设置同步
- CHANGE MASTER TO说明: dev.mysql.com/doc/refman/…
# 登录
docker exec -it db2 mysql -uroot -proot
# 设置
mysql> CHANGE MASTER TO MASTER_HOST = 'db1', MASTER_PORT = 3306, MASTER_USER = 'repl_user', MASTER_PASSWORD = 'repl*User123', MASTER_AUTO_POSITION = 1;
Query OK, 0 rows affected, 8 warnings (0.07 sec)
# 启动
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)
# 查看状态
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: db1
Master_User: repl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 196
Relay_Log_File: d8a9b6ad089b-relay-bin.000002
Relay_Log_Pos: 365
Relay_Master_Log_File: binlog.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 196
Relay_Log_Space: 581
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 81e99d09-f5f5-11eb-8a5a-0242ac120002
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set: 81e99d09-f5f5-11eb-8a5a-0242ac120002:1-11
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
测试
# 登录master
docker exec -it db1 mysql -uroot -proot
# 写入数据
mysql> insert into blog.user (username) values("test3");
Query OK, 1 row affected (0.02 sec)
# 登录slave
docker exec -it db2 mysql -uroot -proot
# 查看数据
mysql> select * from blog.user;
+----+----------+
| id | username |
+----+----------+
| 1 | test1 |
| 2 | test2 |
| 3 | test3 |
+----+----------+
5 rows in set (0.00 sec)
其他常用命令
# 停止slave
stop slave;
# 重设slave
reset slave;
# 重设master
reset master;
# 主服务查看salve
show slave hosts;
# 查点当前连接
show processlist;
# 查看用户信息
select Host, User, plugin from user;
# 查看权限
show grants for repl_user@'%';