双主配置需要注意什么?
- log-slave-updates 需要打开
- auto_increment_offset 和 auto_increment_increment 需要配置不同的起点和步长。
修改mysql目录下的my.cnf
# The MySQL Client configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
[mysql]
[mysqld]
sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
character-set-server=utf8
## 主库配置
## 设置server_id,一般设置为IP,保证唯一就好
server_id=100
# 开启binlog,名字可以随意取
log-bin=mysql-bin
## binlog日志格式,(mixed,statement,row,默认格式是statement)
binlog_format=row
## 日志自动删除日期,默认值为0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql
#控制binlog的写入频率。每执行多少次事务写入一次(这个参数性能消耗很大,但可减小MySQL崩溃造成的损失)
sync_binlog = 1
#这个参数一般用在主主同步中,用来错开自增值, 防止键值冲突
auto_increment_offset = 1
#这个参数一般用在主主同步中,用来错开自增值, 防止键值冲突
auto_increment_increment = 2
#通过同步产生的变化将记录在自己的binlog中
log-slave-updates=ON
- log-slave-updates:另一台数据库通过同步产生过来的变化将同时记录在自己的binlog中。
- auto_increment_increment : 自增步长设置为2,那么这台服务器产生的自增id ,为1,3,5,7。
复制mysql 目录生成mysql_master_second
结构如图:

修改mysql_master_second 目录下的my.cnf
# The MySQL Client configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
[mysql]
[mysqld]
sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
character-set-server=utf8
## 主库配置
## 设置server_id,一般设置为IP,保证唯一就好
server_id=103
# 开启binlog,名字可以随意取
log-bin=mysql-bin
## binlog日志格式,(mixed,statement,row,默认格式是statement)
binlog_format=row
## 日志自动删除日期,默认值为0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql
#控制binlog的写入频率。每执行多少次事务写入一次(这个参数性能消耗很大,但可减小MySQL崩溃造成的损失)
sync_binlog = 1
#这个参数一般用在主主同步中,用来错开自增值, 防止键值冲突
auto_increment_offset = 2
#这个参数一般用在主主同步中,用来错开自增值, 防止键值冲突
auto_increment_increment = 2
#通过同步产生的变化将记录在自己的binlog中
log-slave-updates=ON
- server_id : 设置为另一个值。
auto_increment_offset 和 auto_increment_increment修改保证自增id值不会重复。这台服务器产生的id 为2,4,6,8
修改docker-compose.yml
version: '3'
networks: #定义网路
backend:
driver: ${NETWORKS_DRIVER}
services:
mysql-master: # Master 节点
build:
context: ./mysql #自定义镜像
args:
- MYSQL_VERSION=${MYSQL_VERSION}
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE} #默认创建数据库
- MYSQL_USER=${MYSQL_USER} #创建用户
- MYSQL_PASSWORD=${MYSQL_PASSWORD} #用户密码
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} #root 用户秘密
- TZ=${WORKSPACE_TIMEZONE}
volumes:
- ${DATA_PATH_HOST}/mysql:/var/lib/mysql
- ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d
ports:
- "3308:3306"
networks:
- backend
mysql-slave: #Slave 节点
build:
context: ./mysql_slave #自定义镜像
args:
- MYSQL_VERSION=${MYSQL_VERSION}
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE} #默认创建数据库
- MYSQL_USER=${MYSQL_USER} #创建用户
- MYSQL_PASSWORD=${MYSQL_PASSWORD} #用户密码
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} #root 用户秘密
- TZ=${WORKSPACE_TIMEZONE}
volumes:
- ${DATA_PATH_HOST}/mysql_slave:/var/lib/mysql
- ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d
ports:
- "3309:3306"
networks:
- backend
mysql-master-second: # 第二个 Master 节点
build:
context: ./mysql_master_second #自定义镜像
args:
- MYSQL_VERSION=${MYSQL_VERSION}
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE} #默认创建数据库
- MYSQL_USER=${MYSQL_USER} #创建用户
- MYSQL_PASSWORD=${MYSQL_PASSWORD} #用户密码
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} #root 用户秘密
- TZ=${WORKSPACE_TIMEZONE}
volumes:
- ${DATA_PATH_HOST}/mysql:/var/lib/mysql
- ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d
ports:
- "3310:3306"
networks:
- backend
启动服务
docker-compose up -d --build mysql-master
docker-compose up -d --build mysql-master-second
现在两台Master 服务器已经启动,分别在mysql-master,和 mysql-master-second 创建账号。
grant file,select,replication slave on *.* to 'slave'@'%' identified by '123456';
查看 mysql-master状态:
show master status;

查看mysql-master-second 状态:

设置互为主从关系
- 将
mysql-master-second设置为mysql-master 的从库:
change master to master_host='mysql-master',master_user='slave',master_password='123456',master_log_file='mysql-bin.000004',master_log_pos=448;
start slave;
show slave status;
- 将
mysql-master设置为mysql-master-second的从库:
change master to master_host='mysql-master-second',master_user='slave',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=453;
start slave;
show slave status;
这样双主结构就完成了。
动手
也许还有小伙伴对log-slave-updates 的作用还不是特别明白。 亲自动手做下下面的实验吧。
- 搭建两台Master 服务器
master_first和master_second,形成双主配置,log-slave-updates 配置为OFF。 - 搭建一台Slave 服务器,将Slave 服务器设置为
master_first的从库。 - 在master_first 创建一个student 表格,字段自拟。观察master_second 和 slave 节点情况。
- 在master_second 节点插入一条student数据,观察master_first 和 slave 节点情况。
将log-slave-updates 配置为ON重复上述实验。
