MySQL Replication
MySQL提供了Replication功能,可以实现将一个数据库的数据同步到多台其他数据库。前者通常称之为主库(master),后者则被称从库(slave)。MySQL复制过程采用异步方式,但延时非常小,秒级同步。
同步复制数据基本原理
1.在主库上发生的数据变化记录到二进制日志Binlog
2.从库的IO线程将主库的Binlog复制到自己的中继日志Relay log
3.从库的SQL线程通过读取、重放中继日志实现数据复制
MySQL的复制有三种模式:Statement Level、Row Level、Mixed Level。复制级别的不同,会导致Master端二进制日志文件的生成形式的不同。
环境
环境 | 版本 |
Docker | 26.1.4 |
CentOS | 7 |
Mysql | 5.7 |
步骤
一、创建容器
docker run -p 3307:3306 --name mysql-master \
-v /mydata/mysql-cluster/mysql-master1/log:/var/log/mysql \
-v /mydata/mysql-cluster/mysql-master1/data:/var/lib/mysql \
-v /mydata/mysql-cluster/mysql-master1/conf:/etc/mysql \
-v /mydata/mysql-cluster/mysql-master1/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7docker run -p 3317:3306 --name mysql-master2 \
-v /mydata/mysql-cluster/mysql-master2/log:/var/log/mysql \
-v /mydata/mysql-cluster/mysql-master2/data:/var/lib/mysql \
-v /mydata/mysql-cluster/mysql-master2/conf:/etc/mysql \
-v /mydata/mysql-cluster/mysql-master2/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7docker run -p 3327:3306 --name mysql-slave1 \
-v /mydata/mysql-cluster/mysql-slave1/log:/var/log/mysql \
-v /mydata/mysql-cluster/mysql-slave1/data:/var/lib/mysql \
-v /mydata/mysql-cluster/mysql-slave1/conf:/etc/mysql \
-v /mydata/mysql-cluster/mysql-slave1/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7docker run -p 3337:3306 --name mysql-slave2 \
-v /mydata/mysql-cluster/mysql-slave2/log:/var/log/mysql \
-v /mydata/mysql-cluster/mysql-slave2/data:/var/lib/mysql \
-v /mydata/mysql-cluster/mysql-slave2/conf:/etc/mysql \
-v /mydata/mysql-cluster/mysql-slave2/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
二、创建配置文件
分别创建配置文件并写入对应的配置:
master配置
修改mydata/mysql-cluster/mysql-master1/conf/my.cnf,把以下配置写入到my.cnf中
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
[mysqld]
server_id=1
log-bin=mysql-bin
read-only=0binlog-do-db=adminreplicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schemabinlog_cache_size=1M
binlog_format=mixed
log-slave-updates
expire_logs_days=7
slave_skip_errors=1062
slave配置
修改mydata/mysql-cluster/mysql-slave1/conf/my.cnf,把以下配置写入到my.cnf中
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolveserver_id=4
log-bin=mysql-bin
read-only=1
binlog-do-db=adminreplicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
*注意
每个配置文件server_id必须唯一
若不配置读写分离read-only无需设置
log-bin=mysql-bin:mysql5.7默认不开启bin_log日志,需要此配置开启
binlog-do-db:指定同步的数据库名
replicate-ignore-db:指定不同步的数据库名
三、启动容器
docker start mysql-master mysql-master2 mysql-slave1 mysql-slave2
四、主从关联
配置master
1.进入容器
docker exec -it mysql-master /bin/bash
2.登录
mysql -uroot -proot
3.查看是否开启远程访问(可选)
mysql> select user,host from mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| root | % |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
4 rows in set (0.01 sec)
如果没有'root'@'%'记录就执行
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;
4.配置权限
grant replication slave on *.* to 'backup'@'%' identified by 'root';
5.查看状态
File和Position这两个参数后面会用到
mysql> show master status\G;
*************************** 1. row ***************************File: mysql-bin.000001Position: 439Binlog_Do_DB: adminBinlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
配置Slave
重复配置master的1、2、3(可选)步骤
4.配置主从复制
change master to master_host='192.168.56.11',master_user='backup',master_password='root',master_log_file='mysql-bin.000001',master_log_pos=439,master_port=3307;
change master命令用于配置和改变Slave服务器用于连接Master服务器的参数,以便Slave服务器读取Master服务器的binlog及Slave服务器的relay log。 这个命令同时更新master.info及relay-log.info信息。在执行该命令之前,如果Slave服务器上的IO线程和SQL线程已经启动,需要先停止这些线程(执行stop slave命令)。
change master命令的参数包括但不限于:
- MASTER_HOST 和 MASTER_PORT:指定Master服务器的IP地址和端口号。
- MASTER_USER 和 MASTER_PASSWORD:用于认证的Master服务器用户名和密码。
- MASTER_LOG_FILE 和 MASTER_LOG_POS:指定从哪个binlog文件以及从该文件的哪个位置开始复制数据。
- MASTER_CONNECT_RETRY、MASTER_RETRY_COUNT、MASTER_DELAY、MASTER_HEARTBEAT_PERIOD 等:这些参数用于控制连接重试、延迟和心跳等行为。
- MASTER_AUTO_POSITION:设置为1时,Slave服务器可以自动确定应该从Master服务器的哪个binlog文件和位置开始复制数据。
- RELAY_LOG_FILE 和 RELAY_LOG_POS:如果设置了,这些参数用于指定中继日志的文件名和位置。
- MASTER_SSL 和相关SSL参数:用于配置SSL加密连接。
5.开启同步
start slave;
如果Slave_IO_Running和Slave_SQL_Running显示为Yes,开启成功,如果为Connecting说明出现错误,排查网络是否畅通、mysql配置文件、防火墙、master账号的连接权限、change master参数
master执行记录
[root@10 conf]# docker exec -it mysql-master /bin/bash
root@1275b7c6c4d6:/# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36-log MySQL Community Server (GPL)Copyright (c) 2000, 2021, Oracle and/or its affiliates.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> select user,host from mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| root | % |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
4 rows in set (0.01 sec)mysql> grant replication slave on *.* to 'backup'@'%' identified by 'root';
Query OK, 0 rows affected, 1 warning (0.02 sec)mysql> show master status\G;
*************************** 1. row ***************************File: mysql-bin.000001Position: 439Binlog_Do_DB: adminBinlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
slave执行记录
mysql> change master to master_host='192.168.56.11',master_user='backup',master_password='root',master_log_file='mysql-bin.000001',master_log_pos=439,master_port=3307;
Query OK, 0 rows affected, 2 warnings (0.11 sec)mysql> start slave;
Query OK, 0 rows affected (0.01 sec)mysql> show slave status\G;
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.56.11Master_User: backupMaster_Port: 3307Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 439Relay_Log_File: 9cd2f3cd957f-relay-bin.000002Relay_Log_Pos: 320Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: mysql,sys,information_schema,performance_schemaReplicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 439Relay_Log_Space: 534Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_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: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 2Master_UUID: 534ec559-61e3-11ef-a009-0242ac110009Master_Info_File: /var/lib/mysql/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for more updatesMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version:
1 row in set (0.00 sec)
五、双主关联
两个master互为主从
master1
mysql> change master to master_host='192.168.56.11',master_user='backup',master_password='root',master_log_file='mysql-bin.000001',master_log_pos=439,master_port=3317;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
master2
mysql> change master to master_host='192.168.56.11',master_user='backup',master_password='root',master_log_file='mysql-bin.000001',master_log_pos=369,master_port=3307;
Query OK, 0 rows affected, 2 warnings (0.12 sec)
至此,Msql集群搭建完成