一、什么是数据库集群?

数据库集群是指将多台数据库服务器组合在一起,通过网络协同工作,对外提供统一的数据服务。集群的主要目标通常是:

  • 高可用性:当某台服务器故障时,其他节点可以接管服务,减少停机时间。

  • 读写分离与负载均衡:主库处理写操作,从库分担读请求,提升系统整体吞吐量。

  • 数据冗余:数据在多个节点上存在副本,防止数据丢失。

MySQL 最常见的两种集群方案是一主一从双主双从。本文将带你从基础的一主一从搭建,进阶到生产环境常用的双主双从架构,并深度解析核心配置项。

二、一主一从集群搭建

2.1 环境准备

角色 操作系统 IP 地址 MySQL 版本
Master CentOS 7 192.168.10.10 8.0.33
Slave CentOS 7 192.168.10.20 8.0.33

前置要求

  • 两台服务器均已安装相同版本的 MySQL,并已启动服务。

  • 两台服务器之间网络互通,防火墙开放 MySQL 默认端口 3306

  • 主服务器上有可供复制的数据库(例如 test_db)及数据。

2.2 主服务器配置(Master)

1. 修改配置文件 /etc/my.cnf

在 [mysqld] 段落中添加或修改以下内容:

ini

[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
binlog_do_db = test_db
expire_logs_days = 7
sync_binlog = 1

操作文件/etc/my.cnf

保存后重启 MySQL 服务:

bash

systemctl restart mysqld
2. 创建用于复制的账号并授权

sql

CREATE USER 'repl_user'@'%' IDENTIFIED BY 'Repl@Pass123';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;
3. 记录二进制日志坐标

sql

SHOW MASTER STATUS;

记下输出中的 File(如 mysql-bin.000001)和 Position(如 856)。

2.3 从服务器配置(Slave)

1. 修改配置文件 /etc/my.cnf

ini

[mysqld]
server-id = 2
relay_log = mysql-relay-bin
read_only = 1
replicate_do_db = test_db

操作文件/etc/my.cnf

重启从库 MySQL:

bash

systemctl restart mysqld
2. 设置主库信息并启动复制

sql

STOP SLAVE;
CHANGE MASTER TO
    MASTER_HOST='192.168.10.10',
    MASTER_PORT=3306,
    MASTER_USER='repl_user',
    MASTER_PASSWORD='Repl@Pass123',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=856;
START SLAVE;
3. 查看复制状态

sql

SHOW SLAVE STATUS\G;

确认 Slave_IO_Running 和 Slave_SQL_Running 均为 Yes

2.4 验证同步

在主库执行:

sql

CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO t1 VALUES (1, 'hello master-slave');

到从库查询:

sql

SELECT * FROM t1;

若能查到数据,则一主一从搭建成功。


三、双主双从集群搭建

3.1 什么是双主双从?

双主双从是两台服务器互为主从(Master-Master),同时各自带一个从库。这种架构既能实现读写分离,又能在任一主库故障时,由另一主库继续提供写服务,高可用性更强。架构示意:

text

  [Master1]  <---双向复制--->  [Master2]
      |                           |
      v                           v
  [Slave1]                   [Slave2]
  • Master1 和 Master2 互相复制,组成双主,都可接收写入。

  • Slave1 复制 Master1,Slave2 复制 Master2,用于读流量分担。

  • 应用层可通过中间件将写操作分摊到两个主库(注意避免冲突),读操作发送给就近的从库。

3.2 环境准备

角色 IP 地址 说明
Master1 192.168.10.11 主库1
Master2 192.168.10.12 主库2
Slave1 192.168.10.21 Master1的从库
Slave2 192.168.10.22 Master2的从库

为便于演示,四台服务器均安装 MySQL 8.0,已有一个业务库 test_db

3.3 解决自增主键冲突

双主架构中,两个主库都可能插入数据,若使用自增主键极易发生冲突。MySQL 提供 auto_increment_increment 和 auto_increment_offset 参数让不同主库生成互不冲突的自增 ID。

  • 设置步长 auto_increment_increment = 2(节点数)。

  • 设置起始偏移量:Master1 偏移为 1,Master2 偏移为 2

  • 这样 Master1 生成的自增 ID 依次为:1, 3, 5, 7...;Master2 为:2, 4, 6, 8...,完美错开。

3.4 Master1 配置

操作文件/etc/my.cnf

ini

[mysqld]
# 基础配置
server-id = 11
log_bin = mysql-bin
binlog_format = ROW
sync_binlog = 1
expire_logs_days = 7

# 需要复制的数据库
binlog_do_db = test_db

# 自增步长与偏移,解决双主冲突
auto_increment_increment = 2
auto_increment_offset = 1

# 从库更新也要写入 binlog,否则无法级联复制到另一个主库
log_slave_updates = 1

# 避免循环复制(多主时防止复制回路)
replicate_same_server_id = 0

重启 MySQL:

bash

systemctl restart mysqld

创建复制用户并记录日志坐标:

sql

CREATE USER 'repl_user'@'%' IDENTIFIED BY 'Repl@Pass123';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;   -- 假设得到 mysql-bin.000001, pos=1074

3.5 Master2 配置

操作文件/etc/my.cnf

ini

[mysqld]
server-id = 12
log_bin = mysql-bin
binlog_format = ROW
sync_binlog = 1
expire_logs_days = 7
binlog_do_db = test_db

auto_increment_increment = 2
auto_increment_offset = 2      # 注意偏移为2

log_slave_updates = 1
replicate_same_server_id = 0

重启 MySQL,创建相同复制用户并记录 Master 状态:

sql

SHOW MASTER STATUS;   -- 假设得到 mysql-bin.000001, pos=1123

3.6 建立双主互备复制

在 Master1 上配置到 Master2 的同步

sql

STOP SLAVE;
CHANGE MASTER TO
    MASTER_HOST='192.168.10.12',
    MASTER_PORT=3306,
    MASTER_USER='repl_user',
    MASTER_PASSWORD='Repl@Pass123',
    MASTER_LOG_FILE='mysql-bin.000001',   -- Master2 的 File
    MASTER_LOG_POS=1123;                  -- Master2 的 Position
START SLAVE;
在 Master2 上配置到 Master1 的同步

sql

STOP SLAVE;
CHANGE MASTER TO
    MASTER_HOST='192.168.10.11',
    MASTER_PORT=3306,
    MASTER_USER='repl_user',
    MASTER_PASSWORD='Repl@Pass123',
    MASTER_LOG_FILE='mysql-bin.000001',   -- Master1 的 File
    MASTER_LOG_POS=1074;                  -- Master1 的 Position
START SLAVE;

分别在两台主库执行 SHOW SLAVE STATUS\G,确保 IO 和 SQL 线程运行正常。此时双主互备已生效。

3.7 配置两个从库

Slave1(复制 Master1)

操作文件/etc/my.cnf

ini

[mysqld]
server-id = 21
relay_log = mysql-relay-bin
read_only = 1
replicate_do_db = test_db

重启后执行:

sql

CHANGE MASTER TO
    MASTER_HOST='192.168.10.11',
    MASTER_PORT=3306,
    MASTER_USER='repl_user',
    MASTER_PASSWORD='Repl@Pass123',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=1074;
START SLAVE;
Slave2(复制 Master2)

操作文件/etc/my.cnf

ini

[mysqld]
server-id = 22
relay_log = mysql-relay-bin
read_only = 1
replicate_do_db = test_db

重启后执行:

sql

CHANGE MASTER TO
    MASTER_HOST='192.168.10.12',
    MASTER_PORT=3306,
    MASTER_USER='repl_user',
    MASTER_PASSWORD='Repl@Pass123',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=1123;
START SLAVE;

3.8 验证双主双从同步

在 Master1 插入数据:

sql

INSERT INTO test_db.t1 (name) VALUES ('from master1');

此时 Master2 会通过互备同步该记录,Slave1 和 Slave2 也会依次获得数据。在 Master2 插入:

sql

INSERT INTO test_db.t1 (name) VALUES ('from master2');

观察四台服务器上的数据,应全部一致,且自增主键无冲突。

四、核心配置文件关键字深度解析

下面对两种架构中出现的参数统一进行详解:

参数 用途说明
server-id 全局唯一实例标识。主从、双主中每个节点必须不同,MySQL 靠它区分复制事件来源,防止循环复制。
log_bin 开启二进制日志,指定日志文件前缀。所有数据变更都记录在此,是复制的基础。
binlog_format 日志格式。推荐 ROW 行模式,记录每行数据变化,避免主从不一致。
sync_binlog 事务提交时是否同步磁盘。1 最安全但性能略有下降,高可用集群建议设为 1
expire_logs_days 二进制日志保留天数,避免磁盘耗尽。
binlog_do_db 白名单,仅记录指定数据库的二进制日志。
binlog_ignore_db 黑名单,忽略指定库的日志。注意不要与 do 混用导致不可预期行为。
relay_log 从库的中继日志。IO 线程将主库 binlog 拉取后写入中继日志,SQL 线程再执行。
read_only 从库设为 1 后,普通用户不可写,防止误操作破坏数据一致性。
replicate_do_db / replicate_ignore_db 从库级别的复制过滤,控制哪些库的更新被应用。
auto_increment_increment 自增步长,通常设为参与写操作的节点数(双主设为 2)。
auto_increment_offset 自增起始偏移,用于区分不同节点生成的主键范围。
log_slave_updates 从库接收到的更新是否写入自己的 binlog。在双主或级联复制中必须开启,否则变更无法传递给下一级节点。
replicate_same_server_id 是否应用自身 Server ID 产生的事件。默认关闭(0),避免循环复制。

常见扩展参数

  • gtid_mode / enforce_gtid_consistency:开启 GTID 复制,简化故障切换。双主场景强烈建议使用 GTID,可避免繁琐的日志位点对齐。

  • slave_parallel_workers:从库并行复制线程数,提升回放速度。

  • master_info_repository / relay_log_info_repository:设为 TABLE(MySQL 8.0 默认),将复制信息存储在 InnoDB 表中,可靠性更高。

五、常见问题排查

  1. IO 线程异常
    网络不通、防火墙未放行、复制用户密码错误。查看 Last_IO_Error 定位。

  2. SQL 线程异常
    主键冲突、表结构不一致等。查看 Last_SQL_Error,修复后可 START SLAVE 继续。

  3. 双主自增冲突
    检查两台主库 auto_increment_offset 是否正确错开,且所有表的存储引擎使用自增时都会受该参数影响。

  4. 循环复制导致数据翻倍
    确保 replicate_same_server_id = 0 且每台服务器的 server-id 唯一,同时建议使用 GTID。

  5. 从库延迟过大
    可增加 slave_parallel_workers,并优化主库写入的批量操作。

六、总结

本文从一主一从的基础架构讲起,逐步过渡到生产环境更常用的双主双从方案。通过详尽的配置示例和参数解析,帮助你掌握:

  • 基于日志位点的传统主从复制搭建

  • 双主互备架构中自增 ID 冲突的解决思路

  • log_slave_updatesreplicate_same_server_id 等双主特有参数的作用

下一步你可以:

  • 引入 GTID 模式,让主从切换更方便

  • 使用 半同步复制 进一步保障数据一致性

  • 结合 ProxySQL 或 Atlas 实现自动读写分离与高可用

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐