MySQL单服务器主从复制部署实践与优化
2026/9/10 23:35:23 网站建设 项目流程

1. 项目概述

在数据库运维领域,MySQL主从复制是最基础也最关键的架构设计之一。传统的主从架构通常会将主库和从库部署在不同的服务器上,但实际业务场景中,我们经常会遇到需要在同一台服务器上同时部署主从库的需求。这种部署方式看似违反常规,但在特定场景下却有着不可替代的优势。

我最近在为一个客户部署测试环境时,就采用了单服务器主从架构。客户需要快速验证业务逻辑,但云服务器资源有限。通过在单台4核8G的ECS上部署主从两个MySQL实例,不仅节省了60%的云资源成本,还完美满足了开发团队的联调测试需求。当然,这种架构在生产环境使用时需要更加谨慎。

2. 环境准备与规划

2.1 硬件资源评估

单服务器部署主从库的首要考量是硬件资源是否充足。根据我的经验,至少需要满足以下条件:

  • CPU:建议4核以上,主从库的SQL线程和IO线程都是CPU密集型
  • 内存:每实例建议4GB以上,计算公式为:(innodb_buffer_pool_size + key_buffer_size + 其他缓存) × 实例数
  • 磁盘:推荐SSD,IOPS建议在3000以上。特别注意二进制日志和从库relay log的写入压力

重要提示:务必监控磁盘空间使用率,主从库的二进制日志会占用大量空间。我曾经遇到过因为binlog爆满导致服务器宕机的生产事故。

2.2 软件版本选择

MySQL版本选择直接影响复制功能的稳定性和性能。以下是版本选择的建议:

MySQL版本复制特性推荐场景
5.7GTID复制稳定优先的老系统
8.0.23+增强型半同步复制新项目首选
8.0.26+组复制优化高可用集群

我强烈建议使用MySQL 8.0最新稳定版,它在并行复制和故障恢复方面有显著改进。曾经在5.7版本上遇到的复制延迟问题,在8.0上通过设置slave_parallel_workers参数得到了完美解决。

2.3 目录结构规划

合理的文件目录结构是避免冲突的关键。这是我常用的目录布局:

/mysql ├── master │ ├── data # 主库数据目录 │ ├── logs # 主库日志目录 │ └── conf # 主库配置文件 └── slave ├── data # 从库数据目录 ├── logs # 从库日志目录 └── conf # 从库配置文件

这种结构清晰隔离了两个实例的所有文件,避免了配置文件、数据文件和日志文件的冲突。记得为每个目录设置正确的权限:

chown -R mysql:mysql /mysql chmod 750 /mysql/*/data

3. MySQL实例部署

3.1 主库安装与配置

首先安装MySQL服务器(以Ubuntu为例):

sudo apt update sudo apt install mysql-server-8.0

主库的核心配置文件(/mysql/master/conf/my.cnf)需要特别注意以下参数:

[mysqld] server-id = 1 log_bin = /mysql/master/logs/mysql-bin binlog_format = ROW binlog_row_image = FULL expire_logs_days = 7 max_binlog_size = 100M binlog_group_commit_sync_delay = 100 binlog_group_commit_sync_no_delay_count = 10 datadir = /mysql/master/data socket = /mysql/master/mysql.sock port = 3306 # 性能相关 innodb_buffer_pool_size = 2G innodb_log_file_size = 256M

初始化主库数据目录:

mysqld --initialize --user=mysql --datadir=/mysql/master/data

启动主库服务:

mysqld_safe --defaults-file=/mysql/master/conf/my.cnf &

3.2 从库安装与配置

从库的安装过程与主库类似,但配置有显著差异(/mysql/slave/conf/my.cnf):

[mysqld] server-id = 2 relay_log = /mysql/slave/logs/relay-bin log_slave_updates = ON read_only = ON super_read_only = ON datadir = /mysql/slave/data socket = /mysql/slave/mysql.sock port = 3307 # 复制性能优化 slave_parallel_workers = 4 slave_parallel_type = LOGICAL_CLOCK

特别注意:

  1. server-id必须与主库不同
  2. 使用不同的端口(如3307)和socket文件
  3. 启用read_only防止误操作

初始化从库数据目录:

mysqld --initialize --user=mysql --datadir=/mysql/slave/data

启动从库服务:

mysqld_safe --defaults-file=/mysql/slave/conf/my.cnf &

4. 主从复制配置

4.1 主库用户创建

在主库上创建复制专用账户:

CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'SecurePass123!'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;

安全提示:不要使用弱密码!曾经有客户因为使用简单密码导致数据库被入侵。建议密码包含大小写字母、数字和特殊字符,长度至少16位。

4.2 数据同步

有多种方式初始化从库数据,我推荐使用mysqldump:

# 主库备份 mysqldump --single-transaction --master-data=2 --triggers --routines --all-databases -uroot -p > /tmp/full_dump.sql # 从库恢复 mysql -uroot -p --port=3307 --socket=/mysql/slave/mysql.sock < /tmp/full_dump.sql

对于大型数据库,可以考虑使用物理备份工具如Percona XtraBackup,它能显著减少停机时间。

4.3 启动复制

在从库上配置复制源:

CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='repl', MASTER_PASSWORD='SecurePass123!', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154, MASTER_CONNECT_RETRY=10;

启动复制进程:

START SLAVE;

验证复制状态:

SHOW SLAVE STATUS\G

关键指标检查:

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes
  • Seconds_Behind_Master: 0或很小的值

5. 监控与维护

5.1 监控指标

建立完善的监控体系至关重要。以下是我必监控的关键指标:

  1. 复制延迟:

    SHOW SLAVE STATUS\G
  2. 线程状态:

    SHOW PROCESSLIST;
  3. 性能指标:

    SELECT * FROM performance_schema.replication_applier_status_by_worker;

5.2 日常维护

定期维护任务清单:

  1. 日志清理:

    PURGE BINARY LOGS BEFORE '2023-08-01 00:00:00';
  2. 表一致性检查:

    pt-table-checksum --replicate=test.checksums h=127.0.0.1,u=root,p=password,P=3306
  3. 定期优化表:

    ANALYZE TABLE important_table;

6. 常见问题与解决方案

6.1 复制中断处理

错误示例:

Last_Error: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY

解决方案:

STOP SLAVE; SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;

更安全的做法是使用GTID:

STOP SLAVE; SET @@SESSION.GTID_NEXT= 'aaa-bbb-ccc-ddd:12345'; BEGIN; COMMIT; SET SESSION GTID_NEXT = AUTOMATIC; START SLAVE;

6.2 性能优化

如果发现复制延迟,可以尝试:

  1. 增加并行复制线程:

    STOP SLAVE; SET GLOBAL slave_parallel_workers = 8; START SLAVE;
  2. 调整以下参数:

    slave_parallel_type = LOGICAL_CLOCK slave_preserve_commit_order = ON
  3. 优化主库binlog写入:

    sync_binlog = 1000 binlog_group_commit_sync_delay = 100

7. 高级配置技巧

7.1 半同步复制

提高数据安全性的配置:

主库:

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; SET GLOBAL rpl_semi_sync_master_enabled = 1; SET GLOBAL rpl_semi_sync_master_timeout = 10000; # 10秒

从库:

INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; SET GLOBAL rpl_semi_sync_slave_enabled = 1;

7.2 过滤复制

只需要复制特定库或表时:

CHANGE REPLICATION FILTER REPLICATE_DO_DB = (important_db), REPLICATE_IGNORE_DB = (mysql, sys, performance_schema);

7.3 多源复制

单从库可以同时复制多个主库:

CHANGE MASTER TO MASTER_HOST='master1' ... FOR CHANNEL 'master1'; CHANGE MASTER TO MASTER_HOST='master2' ... FOR CHANNEL 'master2';

8. 生产环境注意事项

  1. 资源隔离:使用cgroups或Docker容器隔离主从实例资源
  2. 监控告警:设置复制延迟超过5分钟触发告警
  3. 定期演练:每季度执行主从切换演练
  4. 备份策略:即使有从库,也要坚持定期全量备份
  5. 安全加固:配置适当的防火墙规则和访问控制

我曾经遇到过一个典型案例:客户的生产系统因为磁盘IO瓶颈导致主从延迟高达2小时。通过分析发现是主库和从库的binlog写入产生了IO竞争。解决方案是将主库的binlog和从库的relay log分别放在不同的物理磁盘上,同时调整了sync_binlog参数,最终将延迟控制在10秒以内。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询