MySQL 基于 Binlog 的主从复制(Master-Slave Replication)是 MySQL 数据库中实现数据复制的一种机制。在这种复制模式下,主库(Master)记录所有对数据库的修改操作(如 INSERT、UPDATE、DELETE 等)到 二进制日志(Binlog),从库(Slave)则读取这些日志并执行相同的操作,从而保持与主库的数据一致性。
Binlog 是 MySQL 用来记录所有修改数据库的事件的日志文件,包括:
Binlog 存储的是操作日志而非数据本身,因此从库需要根据这些操作来更新自己的数据。
基于 Binlog 的复制模式大致可以分为以下几个步骤:
基于 Binlog 的主从复制可以分为不同的复制模式,主要有以下几种:
异步复制:
半同步复制(Semi-Synchronous Replication):
全同步复制(Synchronous Replication):
复制延迟:由于主库和从库是异步同步的,因此在高并发的场景中,从库可能会出现延迟,导致主库和从库的数据不一致。这种延迟通常是由于从库处理速度较慢,或者网络问题等原因导致。
容错性:基于 Binlog 的主从复制,主库发生故障时,需要手动或自动切换到从库。虽然从库可以保持主库的副本,但在主库故障时可能会丢失一定的事务,因此对高可用性的需求需要结合其他技术(如 MHA、ProxySQL、Group Replication 等)来提高容错性。
基于 Binlog 的主从复制是 MySQL 中实现数据复制的常见方式,它通过记录主库的二进制日志,并将日志同步到从库,从而保持数据一致性。这种方式在大多数应用中运行稳定、性能良好,但需要注意故障恢复、复制延迟等问题,适用于高可用架构中进行读写分离、负载均衡等场景。
binlog二进制日志文件记录了主服务器上所有数据库的更改操作
参考:
https://blog.csdn.net/2401_85648342/article/details/139765433
https://blog.csdn.net/qq_40942490/article/details/109158285
https://www.cnblogs.com/zwh0910/p/17247296.html
https://www.cnblogs.com/huanyue9987/p/15844103.html
.
├── docker-compose.yml
├── master1
│ ├── conf
│ ├── data
│ └── logs
├── slave1
│ ├── conf
│ ├── data
│ └── logs
└── slave2
├── conf
├── data
└── logs
创建相关文件夹
# 创建持久化目录
mkdir -p /opt/mysql-compose/{master1/{data,logs,conf},slave1/{data,logs,conf},slave2/{data,logs,conf}}
# 修改权限
chmod -R 777 /opt/mysql-compose/{master1/{data,logs},slave1/{data,logs},slave2/{data,logs}}
# 临时测试-删除持久化的数据
rm -rf /opt/mysql-compose/{master1/{data/*,logs/*},slave1/{data/*,logs/*},slave2/{data/*,logs/*}}
#rm -rf /opt/mysql-compose/{master1/data/*,slave1/data/*,slave2/data/*}
分别上传配置文件(my.cnf)至 conf 目录下
[mysqld]
#==================== Binlog主从同步配置=========================
# 同一局域网内服务器唯一id,默认值1
server-id=11
# 设置日志格式,二级制日志格式,有三种 row,statement,mixed,默认值mixed
binlog_format=mixed
# 二进制日志名,默认binlog
# log-bin=binlog
# 设置需要复制的数据库,默认复制全部数据库
binlog-do-db=testdb
# 设置不需要复制的数据库
#binlog-ignore-db=mysql
#binlog-ignore-db=infomation_schema
#binlog-ignore-db=sys
#binlog-ignore-db=performance_schema
#==================== Binlog主从同步配置=========================
# 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
server-id=12
# 中继日志名,默认xxxxxxxxxxxx-relay-bin
#relay-log=relay-bin
# 设置为只读,该项如果不设置,表示slave可读可写
#read_only=1
# 设置需要复制的数据库,默认复制全部数据库,如果不指明同步哪些库,就去掉这行,表示所有库的同步(除了ignore忽略的库)
#replicate-do-db=testdb
# 设置不需要复制的数据库,
#replicate-ignore-db=mysql
# 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
server-id=13
# 中继日志名,默认xxxxxxxxxxxx-relay-bin
#relay-log=relay-bin
# 设置为只读,该项如果不设置,表示slave可读可写
#read_only=1
#version: "3.5"
services:
#mysql:
# image: registry.cn-shenzhen.aliyuncs.com/multiway/mysql:8.0.29
# container_name: mysql8
# ports:
# - "13306:3306"
# restart: always
# environment:
# - MYSQL_ROOT_PASSWORD=123456
# - TZ=Asia/Shanghai
# volumes:
# - /opt/mysql-compose/master1/conf:/etc/mysql/conf.d
# - /opt/mysql-compose/master1/logs:/var/log/mysql
# - /opt/mysql-compose/master1/data:/var/lib/mysql
mysql_master1:
image: registry.cn-shenzhen.aliyuncs.com/multiway/mysql:8.0.29
container_name: mysql_master1
ports:
- "13306:3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=123456
- TZ=Asia/Shanghai
volumes:
- ./master1/conf:/etc/mysql/conf.d
- ./master1/logs:/var/log/mysql
- ./master1/data:/var/lib/mysql
mysql_slave1:
image: registry.cn-shenzhen.aliyuncs.com/multiway/mysql:8.0.29
container_name: mysql_slave1
ports:
- "13307:3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=123456
- TZ=Asia/Shanghai
volumes:
- ./slave1/conf:/etc/mysql/conf.d
- ./slave1/logs:/var/log/mysql
- ./slave1/data:/var/lib/mysql
mysql_slave2:
image: registry.cn-shenzhen.aliyuncs.com/multiway/mysql:8.0.29
container_name: mysql_slave2
ports:
- "13308:3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=123456
- TZ=Asia/Shanghai
volumes:
- ./slave2/conf:/etc/mysql/conf.d
- ./slave2/logs:/var/log/mysql
- ./slave2/data:/var/lib/mysql
注意:/var/lib/mysql/auto.cnf文件中的server-uuid是 MySQL 数据库服务器的唯一标识符(UUID)。这个标识符用于标识 MySQL 实例,尤其在复制(Replication)设置中,它可以帮助区分不同的数据库实例。在 MySQL 中,/var/lib/mysql/auto.cnf 是一个自动生成的配置文件,通常包含 MySQL 实例的 UUID 信息。你可以通过这个文件来查看 MySQL 服务器的 UUID。它是在 MySQL 启动时自动生成的,并且通常不需要手动修改。如果docker-compose挂载本地目录已有挂载数据请检查,如果有重复的修改server-uuid或者删除这个auto.cnf文件之后重启mysql服务
[auto]
server-uuid=bc8c658e-ce63-11ef-89ae-0242ac130004
# 进入docker-compose.yml的所在层级文件夹
cd /opt/mysql-compose
# 运行docker compose 容器服务
docker compose up -d
#停止docker compose 容器服务
docker compose down
#查看docker compose 容器服务状态
docker compose ps
主库实例创建主从同步账号(使用root账户跳过)
# 创建用户
create user 'repl_master1'@'%' identified by '@mw123';
# 授权(主从同步权限即可)
# replication slave权限:拥有此权限可以查看从服务器,从主服务器读取二进制日志。
# super权限:允许用户使用修改全局变量的SET语句以及CHANGE(属于MASTER语句)
# reload权限:必须拥有reload权限,才可以执行flush [tables | logs | privileges]
grant replication slave,reload,super on *.* to 'repl_master1'@'%' with grant option;
# 刷新授权
flush privileges;
#查找用户
select * from mysql.user;
SQL参考
#查看只读相关配置
show VARIABLES like '%read_only%';
#开启全局只读(包括普通用户、超级管理员root也都不能写)
set global super_read_only='on';
#开启全局只读(普通用户不能写),理论来说开启了super_read_only后,就无需设置当前参数
set global read_only='on';
#关闭全局只读(让超级管理员root能进行写操作)
set global super_read_only='off';
#关闭全局只读(让普通用户也能写操作)
set global read_only='off';
#查看只读相关配置
show VARIABLES like '%read_only%';
查看主库状态,连接master1数据库执行下面sql语句
# 创建持久化目录
mkdir -p /opt/mysql-compose/{master1/{data,logs,conf},slave1/{data,logs,conf},slave2/{data,logs,conf}}
# 修改权限
chmod -R 777 /opt/mysql-compose/{master1/{data,logs},slave1/{data,logs},slave2/{data,logs}}
# 临时测试-删除持久化的数据
rm -rf /opt/mysql-compose/{master1/{data/*,logs/*},slave1/{data/*,logs/*},slave2/{data/*,logs/*}}
#rm -rf /opt/mysql-compose/{master1/data/*,slave1/data/*,slave2/data/*}
0
查看结果
File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
---|---|---|---|---|
binlog.000005 | 157 | testdb |
注意:如果是指定的数据库比如testdb的话,先在主数据库master1创建数据库,并创建表添加数据后,导出脚本,然后从库slave1和slave2也要创建数据库testdb导入执行sql脚本,使主从库数据一致,执行主从复制操作之前停止其他服务对主库的读写操作,不然会造成数据丢失等问题;简单来说在主从复制操作开始之前保证主从数据库数据一致
分别连接slave1和slave2数据库执行下面sql语句,设置或修复 MySQL 的主从复制关系
# 创建持久化目录
mkdir -p /opt/mysql-compose/{master1/{data,logs,conf},slave1/{data,logs,conf},slave2/{data,logs,conf}}
# 修改权限
chmod -R 777 /opt/mysql-compose/{master1/{data,logs},slave1/{data,logs},slave2/{data,logs}}
# 临时测试-删除持久化的数据
rm -rf /opt/mysql-compose/{master1/{data/*,logs/*},slave1/{data/*,logs/*},slave2/{data/*,logs/*}}
#rm -rf /opt/mysql-compose/{master1/data/*,slave1/data/*,slave2/data/*}
1
关闭主库只读状态
# 创建持久化目录
mkdir -p /opt/mysql-compose/{master1/{data,logs,conf},slave1/{data,logs,conf},slave2/{data,logs,conf}}
# 修改权限
chmod -R 777 /opt/mysql-compose/{master1/{data,logs},slave1/{data,logs},slave2/{data,logs}}
# 临时测试-删除持久化的数据
rm -rf /opt/mysql-compose/{master1/{data/*,logs/*},slave1/{data/*,logs/*},slave2/{data/*,logs/*}}
#rm -rf /opt/mysql-compose/{master1/data/*,slave1/data/*,slave2/data/*}
2