主从同步配置的步骤

  1. MySQL主从同步配置

主从同步是在数据库服务器层面配置的,不是在应用代码中实现:

步骤1:docker-compose配置

services:

mysql-master:

image: mysql:8.0

environment:

MYSQL_ROOT_PASSWORD: masterpass

MYSQL_REPLICATION_USER: repl_user

MYSQL_REPLICATION_PASSWORD: repl_pass

volumes:

  • ./mysql/master:/var/lib/mysql

  • ./mysql/master.cnf:/etc/mysql/conf.d/master.cnf

ports:

  • "3306:3306"

mysql-slave1:

image: mysql:8.0

environment:

MYSQL_ROOT_PASSWORD: slavepass

MYSQL_REPLICATION_USER: repl_user

MYSQL_REPLICATION_PASSWORD: repl_pass

volumes:

  • ./mysql/slave1:/var/lib/mysql

  • ./mysql/slave1.cnf:/etc/mysql/conf.d/slave.cnf

depends_on:

  • mysql-master

步骤2:主库配置文件 (master.cnf)

mysqld

server-id = 1

log-bin = mysql-bin

binlog_format = ROW

binlog_do_db = chatdb # 指定要同步的数据库

sync_binlog = 1

步骤3:从库配置文件 (slave.cnf)

mysqld

server-id = 2 # 每个从库需要唯一ID

relay-log = mysql-relay-bin

read_only = 1 # 确保从库只读

步骤4:初始化主从同步

在主库创建复制用户

docker exec -it mysql-master mysql -uroot -pmasterpass -e \

"CREATE USER 'repl_user'@'%' IDENTIFIED BY 'repl_pass'; \

GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; \

FLUSH PRIVILEGES;"

查看主库状态

docker exec -it mysql-master mysql -uroot -pmasterpass -e "SHOW MASTER STATUS;"

在从库配置主库信息

docker exec -it mysql-slave1 mysql -uroot -pslavepass -e \

"CHANGE MASTER TO \

MASTER_HOST='mysql-master', \

MASTER_USER='repl_user', \

MASTER_PASSWORD='repl_pass', \

MASTER_LOG_FILE='mysql-bin.000003', \ # 来自SHOW MASTER STATUS

MASTER_LOG_POS=107; \

START SLAVE;"

  1. 解决主从同步延迟问题

针对主从同步延迟导致的数据不一致,我们采用"缓存屏障"策略:

// user_service.cpp

void updateUserStatus(int userId, string status) {

// 1. 更新主库

mysql_query(MasterDB, "UPDATE users SET status = ...");

// 2. 立即更新缓存

redisClient.set("user_status:" + to_string(userId), status);

// 3. 设置缓存过期时间(略长于主从同步最大延迟)

redisClient.expire("user_status:" + to_string(userId), 5);

}

string getUserStatus(int userId) {

// 1. 先尝试从缓存读取

string cachedStatus = redisClient.get("user_status:" + to_string(userId));

if (!cachedStatus.empty()) {

return cachedStatus;

}

// 2. 缓存不存在,查询数据库

// 注意:这里可能路由到从库,但此时数据应该已经同步

string dbStatus = queryStatusFromDB(userId);

// 3. 将结果写入缓存

redisClient.setex("user_status:" + to_string(userId), 300, dbStatus);

return dbStatus;

}

关键策略:

  1. 写后立即更新缓存:
  • 写操作完成后立即更新缓存

  • 确保后续读取可以直接从缓存获取最新数据

  1. 缓存过期时间:
  • 设置略大于主从同步最大延迟时间(如5秒)

  • 保证在过期前主从同步完成

  1. 重要数据强制读主:

string getCriticalData(int id) {

// 金融类数据直接读主库

return queryFromMasterDB("SELECT * FROM critical_data WHERE id = ...");

}

  1. Binlog监听更新缓存:

使用Canal等工具监听主库Binlog,实时更新缓存:

// Canal客户端伪代码

void updateCacheFromBinlog() {

while (true) {

Message message = canalConnector.get();

for (Entry entry : message.getEntries()) {

if (entry.getEntryType() == ROWDATA) {

redisClient.set(entry.getKey(), entry.getValue());

}

}

}

}

MySQL主从同步配置详解

您提供的配置是一个典型的基于Docker的MySQL主从同步配置。下面我将详细解释每个步骤的原理和作用,帮助您全面理解MySQL主从同步的配置过程。

一、主从同步的基本原理

MySQL主从同步是基于**二进制日志(binlog)**实现的:

  1. 主库(Master)

    • 执行数据变更操作(INSERT/UPDATE/DELETE)
    • 将操作记录到二进制日志(binlog)
    • 二进制日志记录了所有对数据库的修改
  2. 从库(Slave)

    • 通过IO线程连接主库,请求binlog
    • 将binlog写入中继日志(relay-log)
    • 通过SQL线程执行中继日志中的操作
    • 实现与主库的数据同步

二、详细配置解析

步骤1:docker-compose配置

复制代码

yaml

编辑

复制代码
services:
  mysql-master:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: masterpass
      MYSQL_REPLICATION_USER: repl_user
      MYSQL_REPLICATION_PASSWORD: repl_pass
    volumes:
      - ./mysql/master:/var/lib/mysql
      - ./mysql/master.cnf:/etc/mysql/conf.d/master.cnf
    ports:
      - "3306:3306"

  mysql-slave1:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: slavepass
      MYSQL_REPLICATION_USER: repl_user
      MYSQL_REPLICATION_PASSWORD: repl_pass
    volumes:
      - ./mysql/slave1:/var/lib/mysql
      - ./mysql/slave1.cnf:/etc/mysql/conf.d/slave.cnf
    depends_on:
      - mysql-master

关键点解释

  • Docker容器化:将MySQL服务运行在容器中,便于隔离和管理
  • 数据持久化volumes将容器内的MySQL数据目录挂载到宿主机,确保容器重启后数据不丢失
  • 配置文件挂载:将自定义的配置文件挂载到容器内,实现主从配置
  • 依赖关系depends_on确保主库容器先启动,从库容器再启动

步骤2:主库配置文件 (master.cnf)

复制代码

ini

编辑

复制代码
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog_format = ROW
binlog_do_db = chatdb  # 指定要同步的数据库
sync_binlog = 1

关键参数详解

  1. server-id = 1

    • 主库的唯一标识,必须与从库不同
    • 用于区分多个MySQL实例(在集群中必须唯一)
    • 知识库[3]和[7]提到:"server_id 用于区分服务,范围1~2^32-1"
  2. log-bin = mysql-bin

    • 启用二进制日志功能
    • 日志文件名前缀为mysql-bin,实际文件会是mysql-bin.000001
    • 知识库[3]指出:"主数据库master进行增删改操作后,相应操作记录的语句会记录到binlog日志文件中"
  3. binlog_format = ROW

    • 二进制日志格式,有三种模式:
      • STATEMENT:记录SQL语句(可能导致主从不一致)
      • ROW:记录每一行的变更(更安全,推荐)
      • MIXED:混合模式
    • 知识库[5]提到:"STATEMENT模式可能因为函数导致主从数据不一致"
  4. binlog_do_db = chatdb

    • 指定要同步的数据库
    • 仅同步chatdb数据库,避免不必要的数据传输
    • 知识库[6]提到:"binlog-do-db= db1 #需要同步的数据库名称"
  5. sync_binlog = 1

    • 控制binlog刷新到磁盘的频率
    • 1表示每次事务提交都刷新到磁盘,提高数据安全性
    • 知识库[6]提到:"sync_binlog=1,MySQL在每写1次二进制日志时,会将日志同步到磁盘"

步骤3:从库配置文件 (slave.cnf)

复制代码

ini

编辑

复制代码
[mysqld]
server-id = 2  # 每个从库需要唯一ID
relay-log = mysql-relay-bin
read_only = 1  # 确保从库只读

关键参数详解

  1. server-id = 2

    • 从库的唯一标识
    • 必须与主库和其他从库不同
    • 知识库[7]指出:"server_id = 88 #集群唯一标识,主库从库不能重复"
  2. relay-log = mysql-relay-bin

    • 从库的中继日志文件名前缀
    • 用于存储从主库获取的binlog
    • 知识库[8]提到:"中继日志(Relay Log):从库上的一个日志文件,用于存储从主库读取的二进制日志"
  3. read_only = 1

    • 设置从库为只读模式
    • 防止从库被直接写入,保证数据一致性
    • 知识库[9]提到:"从库的只读属性是主从同步的重要保障"

步骤4:初始化主从同步

1. 创建复制用户
复制代码

bash

编辑

复制代码
docker exec -it mysql-master mysql -uroot -pmasterpass -e \
"CREATE USER 'repl_user'@'%' IDENTIFIED BY 'repl_pass'; \
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; \
FLUSH PRIVILEGES;"

关键点

  • 创建专门用于复制的用户repl_user
  • 授予REPLICATION SLAVE权限,这是主从同步必需的
  • GRANT REPLICATION SLAVE ON *.*:授予所有数据库的复制权限
  • 知识库[6]提到:"grant replication slave on . to 'repl'@'%' identified by 'repl';"
2. 查看主库状态
复制代码

bash

编辑

复制代码
docker exec -it mysql-master mysql -uroot -pmasterpass -e "SHOW MASTER STATUS;"

输出示例

复制代码

text

编辑

复制代码
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 |      107 | chatdb       |                  |
+------------------+----------+--------------+------------------+

关键信息

  • File:当前binlog文件名(mysql-bin.000003
  • Position:当前binlog位置(107
  • Binlog_Do_DB:要同步的数据库(chatdb
3. 在从库配置主库信息
复制代码

bash

编辑

复制代码
docker exec -it mysql-slave1 mysql -uroot -pslavepass -e \
"CHANGE MASTER TO \
MASTER_HOST='mysql-master', \
MASTER_USER='repl_user', \
MASTER_PASSWORD='repl_pass', \
MASTER_LOG_FILE='mysql-bin.000003', \
MASTER_LOG_POS=107; \
START SLAVE;"

关键点

  • CHANGE MASTER TO:配置从库连接主库的参数
  • MASTER_HOST='mysql-master':主库容器名(Docker网络中可解析)
  • MASTER_LOG_FILEMASTER_LOG_POS:从SHOW MASTER STATUS获取的值
  • START SLAVE:启动从库的复制线程

三、主从同步工作流程

  1. 主库写入数据

    • 执行INSERT/UPDATE/DELETE操作
    • 将操作记录到binlog(mysql-bin.000003
    • 操作在主库完成
  2. 从库获取数据

    • IO线程连接主库,请求binlog
    • 从主库获取binlog内容
    • 将binlog写入中继日志(mysql-relay-bin
  3. 从库应用数据

    • SQL线程读取中继日志
    • 执行binlog中的操作
    • 数据同步完成

四、主从同步状态检查

复制代码

bash

编辑

复制代码
docker exec -it mysql-slave1 mysql -uroot -pslavepass -e "SHOW SLAVE STATUS\G"

关键状态字段

  • Slave_IO_Running:IO线程状态(Yes表示正常)
  • Slave_SQL_Running:SQL线程状态(Yes表示正常)
  • Seconds_Behind_Master:从库落后主库的时间(0表示同步完成)

五、主从同步的同步方式

根据知识库[1],MySQL主从同步主要有两种方式:

  1. 异步方式

    • 主库立即响应应用,同时异步复制数据
    • 特点:高性能,但主库不可用会影响数据一致性
    • 您的配置默认使用的是异步方式
  2. 半同步方式

    • 主库等待从库确认收到日志才返回响应
    • 特点:数据安全性高,但性能稍低
    • 知识库[1]提到:"半同步方式下,当备实例不可用...主实例会自动切换为异步方式"

六、为什么需要这些配置?

  1. server-id:确保主从库能正确识别彼此,避免循环复制
  2. binlog:主从同步的基础,没有binlog就无法实现同步
  3. binlog_format=ROW:避免STATEMENT模式可能导致的数据不一致
  4. binlog_do_db:只同步必要数据,减少网络传输和存储开销
  5. sync_binlog=1:确保数据安全,避免主库崩溃导致数据丢失
  6. read_only=1:防止从库被直接写入,保证数据一致性

七、常见问题与解决方案

  1. 主从同步失败

    • 检查网络连接:确保主从库之间网络连通
    • 检查复制用户权限:确保repl_user有REPLICATION SLAVE权限
    • 检查binlog位置:确保MASTER_LOG_FILEMASTER_LOG_POS正确
  2. 数据不一致

    • 检查binlog_format:建议使用ROW模式
    • 检查主从数据库版本:确保主从版本一致
    • 使用pt-table-checksum工具检查数据一致性
  3. 性能问题

    • 适当调整sync_binlog:设置为0可能提高性能,但降低数据安全性
    • 使用半同步复制:在MySQL 5.7及以上版本支持

八、与知识库的联系

  • 您的配置与知识库[3]、[6]和[7]中的配置方法一致
  • 详细解释了server-idlog-bin等关键参数
  • 使用了ROW模式的binlog格式,避免了知识库[5]提到的STATEMENT模式问题
  • 通过read_only=1确保从库的只读特性,符合知识库[9]的建议

总结

您提供的配置是一个标准的MySQL主从同步配置,基于Docker实现,使用异步复制方式。这种配置方式:

  • 简单易用,适合开发和测试环境
  • 通过Docker实现环境隔离
  • 使用ROW模式的binlog确保数据一致性
  • 通过read_only设置防止从库被直接写入

主从同步是实现高可用、读写分离和数据备份的基础,正确配置主从同步对构建可靠的应用系统至关重要。

相关推荐
无敌最俊朗@1 小时前
00-7天攻破sqlite数据库(总览sqlite)
数据库·sqlite
Access开发易登软件2 小时前
Access导出带图表的 HTML 报表:技术实现详解
数据库·后端·html·vba·导出·access
_Minato_2 小时前
数据库知识整理——SQL数据定义
数据库·sql·mysql·oracle·database·数据库开发·数据库架构
程序员卷卷狗2 小时前
MySQL 四种隔离级别:从脏读到幻读的全过程
数据库·mysql
l1t3 小时前
改写ITPUB newkid的求解数独DuckDB SQL为Clickhouse格式
数据库·sql·clickhouse·duckdb
国服第二切图仔3 小时前
鸿蒙应用开发之实现键值型数据库跨设备数据同步
数据库·wpf·harmonyos
盒马coding5 小时前
PostgreSQL18新功能COPY命令变得更加用户友好
数据库·postgresql
️️(^~^)5 小时前
触发器,存储过程
数据库
罗光记5 小时前
Quantinuum 发布新型量子计算机“Helios“
数据库·经验分享·其他·百度·twitter