一、主从复制
1、一主多从搭建
1.1、启动 mysql docker-compose.yml
version: "3"
services:
mysql_master:
container_name: mysql_master
image: 'mysql:8.0'
volumes:
- ./data/master:/var/lib/mysql
- ./conf/master/master.cnf:/etc/mysql/master.cnf
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_MASTER_ROOT_PASSWORD}
ports:
- "3306:3306"
restart: always
networks:
- mysql-replicanet
mysql_slave_1:
image: 'mysql:8.0'
container_name: mysql_slave_1
volumes:
- ./data/slave1:/var/lib/mysql
- ./conf/slave1/master.cnf:/etc/mysql/slave.cnf
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_SLAVE_ROOT_PASSWORD}
ports:
- "4401:3306"
restart: always
networks:
- mysql-replicanet
mysql_slave_2:
image: 'mysql:8.0'
container_name: mysql_slave_2
volumes:
- ./data/slave2:/var/lib/mysql
- ./conf/slave2/master.cnf:/etc/mysql/slave.cnf
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_SLAVE_ROOT_PASSWORD}
ports:
- "4402:3306"
restart: always
networks:
- mysql-replicanet
networks:
mysql-replicanet:
driver: bridge
1.2、master.cnf 配置
[mysqld]
# ###################################################
# 主主复制配置
#
# 如果当前实例既做主库又做从库次选线必须开启
# log-slave-updates = true
# 自增长ID
# 特殊说明 当该实例为双主的架构时要特殊配置 以避免自增id冲突的问题
# auto_increment_offset = 1
# auto_increment_increment = 2
# ####################################################
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
# [必须]服务器唯一ID,默认是1,一般取IP最后一段
server-id=1
# [必须]启用二进制日志
log-bin=mysql-bin
# 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
1.3、slave.cnf 配置
[mysqld]
# ###################################################
# 主主复制配置
#
# 如果当前实例既做主库又做从库次选线必须开启
# log-slave-updates = true
# 自增长ID
# 特殊说明 当该实例为双主的架构时要特殊配置 以避免自增id冲突的问题
# auto_increment_offset = 2
# auto_increment_increment = 2
# ####################################################
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
# [必须]服务器唯一ID,默认是1,一般取IP最后一段
server-id=2
# [必须]启用二进制日志
log-bin=mysql-bin
# 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql
#只读
read-only=1
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
1.4、进入master配置同步账号和权限
# 进入docker 容器
docker exec -it mysql_master bash
# 进入mysql
mysql -uroot -p${MYSQL_ROOT_PASSWORD}
# 修改远程访问(可选)
use mysql;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
FLUSH PRIVILEGES;
# 添加同步账号和权限
CREATE USER 'slave'@'%' identified WITH mysql_native_password BY '123456';
grant replication slave,replication client on *.* to 'slave'@'%';
flush privileges;
1.5、获取主数据库 binlog 日志状态
show master status;
File |Position|Binlog_Do_DB|Binlog_Ignore_DB |Executed_Gtid_Set|
----------------|--------|------------|------------------------|-----------------|
mysql-bin.000004| 156| |mysql,information_schema| |
1.6、在 slave 中配置主机信息
- master_port:Master的端口号,指的是容器的端口号
- master_user:用于数据同步的用户
- master_password:用于同步的用户的密码
- master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
- master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
- master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
```shell
进入MySQL后执行
首先停止数据同步相关的线程: slave I/O 线程和 slave SQL 线程
STOP SLAVE ;
为了避免可能发生的错误,直接重置客户端
RESET SLAVE ;
CHANGE MASTER TO MASTER_HOST=’mysql_master’, MASTER_USER=’slave’, MASTER_PASSWORD=’123456’, MASTER_LOG_FILE=’mysql-bin.000004’, MASTER_LOG_POS=156;
启动slaver 服务
START SLAVE ;
查看从数据库的状态
SHOW SLAVE STATUS ;
看到以下两列 为Yes ,证明连接成功
Slave_IO_Running |Yes
Slave_SQL_Running |Yes
<a name="vwVMy"></a>
### 2、双主复制搭建
<a name="UKR4F"></a>
#### 2.1、配置
- 在一主多从的配置中,添加配置
```shell
# ###################################################
# 主主复制配置
#
# 如果当前实例既做主库又做从库次选线必须开启
log-slave-updates = true
# 自增长ID
# 特殊说明 当该实例为双主的架构时要特殊配置 以避免自增id冲突的问题
auto_increment_offset = 2
auto_increment_increment = 2
# ####################################################
2.2、配置复制账号
CREATE USER 'slave'@'%' identified WITH mysql_native_password BY '123456';
grant replication slave,replication client on *.* to 'slave'@'%';
flush privileges;
2.3、两台主 mysql 都配置各自主 mysql 信息
# 首先停止数据同步相关的线程: slave I/O 线程和 slave SQL 线程
STOP SLAVE ;
# 为了避免可能发生的错误,直接重置客户端
RESET SLAVE ;
CHANGE MASTER TO
MASTER_HOST='mysql_master',
MASTER_USER='slave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=156;
#启动slaver 服务
START SLAVE ;
# 查看从数据库的状态
SHOW SLAVE STATUS ;
3、主从复制:GTID 复制模式
4、主从复制原理
4.1、MySQL 主从复制主流架构模型
- 一主一从 / 一主多从
- 当 Slave 增加到一定数量时,Slave 对 Master 的负载以及网络带宽都会成为一个严重的问题
- 多主一从
- 双主适用于写压力比较大的业务场景,或者 DBA 做维护需要主从切换的场景,通过双主架构避免了重复搭建从库的麻烦
- 双主复制
- 级联复制
- 部分 slave 节点连接到它上一级的从节点上,用于减轻主库的压力。
- 级联复制解决了一主多从场景下多个从库复制对主库的压力,带来的弊端就是数据同步延迟比较大。
4.2、涉及到三个线程
- 一个在主节点的线程:log dump thread
- 从库会生成两个线程:一个 I/O 线程,一个 SQL 线程
- 主节点
- 1、当主节点上进行 insert、update、delete 操作时,会按照时间先后顺序写入到 binlog 中;
- 2、当从节点连接到主节点时,主节点会创建一个叫做 binlog dump 的线程;
- 3、一个主节点有多少个从节点,就会创建多少个 binlog dump 线程;
- 4、当主节点的 binlog 发生变化的时候,也就是进行了更改操作,binlog dump 线程就会通知从节点 (Push模式),并将相应的 binlog 内容发送给从节点;
从节点
使用percona-toolkit工具辅助。
手动重建不一致的表。
(Master-Master replication manager for MySQL)
MHA 数据库高可用架构
(MySQL Master High Availability)
keepalive 故障转移
Mysql Group Replication
Mysql InnoDB Cluster
参考
- https://www.modb.pro/db/29214
- https://dev.mysql.com/blog-archive/docker-compose-setup-for-innodb-cluster/
- https://dev.mysql.com/doc/refman/8.0/en/replication.html
- https://dev.mysql.com/doc/refman/8.0/en/replication-options-reference.html
- https://gitee.com/daitougege/mysql-master-slave-docker-compose
- https://piaohua.github.io/post/mysql/20210523-mysql-master-slaves/
- https://www.cnblogs.com/rickiyang/p/13856388.html
- https://tech.meituan.com/2017/06/29/database-availability-architecture.html
- MHA
- https://www.cnblogs.com/fengzheng/p/13401783.html
- 不一致问题