MySQL双主架构是生产环境中提升数据库高可用和读写扩展能力的常用方案,两个MySQL实例互为主从角色,既可以作为写节点接收业务写入,也能同步对方的增量数据,实现数据的双向一致。

双主架构的基础环境准备
搭建双主架构前需要准备两台独立的MySQL实例,假设实例A的IP为192.168.0.1,端口3306;实例B的IP为192.168.0.2,端口3306,两个实例的MySQL版本建议保持一致,避免版本差异导致同步异常。首先需要确认两个实例都开启了二进制日志功能,这是主从复制的基础。
开启二进制日志配置
修改两个实例的my.cnf配置文件,添加如下配置项后重启MySQL服务:
# 实例A配置 [mysqld] server-id=1 log-bin=mysql-bin binlog_format=row # 实例B配置 [mysqld] server-id=2 log-bin=mysql-bin binlog_format=row
其中server-id是每个MySQL实例的唯一标识,两个实例的server-id不能相同,否则同步会出现异常。log-bin开启二进制日志,binlog_format设置为row模式可以保证同步数据的准确性。
双向同步配置步骤
第一步:创建同步专用账号
在两个实例上分别创建用于主从复制的账号,授权复制权限:
-- 在实例A和实例B都执行,创建复制账号 CREATE USER 'repl'@'192.168.0.%' IDENTIFIED BY 'repl_password'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'192.168.0.%'; FLUSH PRIVILEGES;
第二步:获取实例的二进制日志位点
分别在两个实例上执行如下命令,记录当前的二进制日志文件名和位点:
-- 实例A执行,记录File和Position值 SHOW MASTER STATUS; -- 实例B执行,记录File和Position值 SHOW MASTER STATUS;
第三步:配置互为主从的同步链路
在实例A上配置同步实例B的数据,填入实例B的二进制日志信息:
-- 实例A执行,指向实例B为主库 CHANGE MASTER TO MASTER_HOST='192.168.0.2', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='repl_password', MASTER_LOG_FILE='mysql-bin.000001', -- 替换为实例B的File值 MASTER_LOG_POS=154; -- 替换为实例B的Position值 -- 启动同步 START SLAVE;
在实例B上配置同步实例A的数据,填入实例A的二进制日志信息:
-- 实例B执行,指向实例A为主库 CHANGE MASTER TO MASTER_HOST='192.168.0.1', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='repl_password', MASTER_LOG_FILE='mysql-bin.000001', -- 替换为实例A的File值 MASTER_LOG_POS=154; -- 替换为实例A的Position值 -- 启动同步 START SLAVE;
第四步:验证双向同步状态
在两个实例上执行如下命令,查看同步状态:
SHOW SLAVE STATUSG
确认Slave_IO_Running和Slave_SQL_Running两个字段的值都为Yes,说明同步链路正常。可以在实例A创建测试表并插入数据,验证实例B是否能同步到该数据,再在实例B插入数据,验证实例A是否能同步到,确认双向同步生效。
auto_increment_offset防冲突配置
双向同步场景下,如果两个实例都使用默认的自增主键生成规则,很容易出现主键冲突,比如两个实例同时生成id=1的记录,同步到对方时就会报主键重复错误。此时需要配置auto_increment_offset和auto_increment_increment两个参数来规避冲突。
参数作用说明
auto_increment_increment表示自增步长,auto_increment_offset表示自增起始偏移量。通过两个参数的组合,可以让两个实例生成的自增主键值完全不重叠。
假设设置auto_increment_increment=2,那么:
- 实例A设置
auto_increment_offset=1,生成的自增id序列为1、3、5、7... - 实例B设置
auto_increment_offset=2,生成的自增id序列为2、4、6、8...
这样两个实例生成的主键永远不会重复,双向同步时就不会出现主键冲突问题。
参数配置方法
修改两个实例的my.cnf配置文件,添加如下配置后重启服务:
# 实例A配置 [mysqld] auto_increment_increment=2 auto_increment_offset=1 # 实例B配置 [mysqld] auto_increment_increment=2 auto_increment_offset=2
也可以动态修改参数,不需要重启服务,但是重启后会失效,建议同时写入配置文件:
-- 实例A执行 SET GLOBAL auto_increment_increment=2; SET GLOBAL auto_increment_offset=1; -- 实例B执行 SET GLOBAL auto_increment_increment=2; SET GLOBAL auto_increment_offset=2;
验证防冲突效果
分别在两个实例上创建带自增主键的测试表,插入数据验证生成的id是否符合预期:
-- 两个实例都创建测试表
CREATE TABLE test_auto_inc (
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(50)
);
-- 实例A插入数据
INSERT INTO test_auto_inc(content) VALUES('a1'),('a2');
-- 实例B插入数据
INSERT INTO test_auto_inc(content) VALUES('b1'),('b2');
-- 分别查询两个实例的表数据,确认id不重复
SELECT * FROM test_auto_inc;
双主架构的注意事项
1. 双主架构不适合有强一致要求的业务场景,因为双向同步存在延迟,可能出现数据短暂不一致的情况。
2. 要避免两个实例同时修改同一条数据,否则会出现数据冲突,需要业务层做好数据分片,比如不同实例负责不同范围的业务数据写入。
3. 定期监控同步状态,当Slave_IO_Running或Slave_SQL_Running变为No时,需要及时排查错误,比如主键冲突、binlog位点过期等问题。
4. 如果后续需要扩展更多节点,不建议在双主基础上直接添加从节点,建议重新规划集群架构,避免同步链路过于复杂导致维护困难。
MySQL双主架构双向同步auto_increment_offset修改时间:2026-06-26 06:00:33