1. 同机部署MySQL主从架构的典型场景
在真实的数据库运维中,我们经常会遇到需要在单台物理服务器上同时部署MySQL主库和从库的需求。这种架构看似违背了主从分离的常规认知,但实际上在以下场景中具有独特价值:
- 开发测试环境:程序员本地调试需要完整的主从链路验证代码逻辑,但资源有限无法使用多台机器
- 成本敏感型项目:初创企业或小型项目初期为控制硬件成本,需要在一台高配服务器上实现读写分离
- 数据迁移过渡期:将单实例数据库平滑迁移到主从架构时,同机部署可作为中间过渡状态
- 特殊备份需求:需要实时备份但又不能影响主库性能,本地从库比远程备份更节省带宽
我最近在为某电商平台搭建促销活动专用的数据库时,就采用了这种方案。他们的秒杀系统需要处理突发流量,但预算只够采购一台32核128G的阿里云ECS。通过精心配置,最终实现了主库处理订单写入、从库支撑数据分析的混合负载,QPS稳定在1.2万以上。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与避坑指南
2.1 服务器硬件配置建议
虽然主从同机节省了机器成本,但对单机性能提出了更高要求。根据MySQL官方文档和我的实测经验,建议配置:
code复制CPU:至少8核(推荐16核以上)
内存:主从实例总内存不超过物理内存的70%
磁盘:建议SSD阵列,主从数据目录分开挂载
重要提示:务必为主从实例配置不同的数据目录(如/var/lib/mysql-master和/var/lib/mysql-slave),否则启动时会因文件锁冲突导致服务崩溃。这是我用血泪教训换来的经验。
2.2 MySQL安装的版本控制
通过APT/YUM安装时容易掉入的坑:
bash复制# 错误示范(会导致主从版本不一致):
sudo apt-get install mysql-server # 默认安装最新版
sudo yum install mysql-community-server
# 正确做法(指定相同版本):
wget https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.22-1_all.deb
sudo apt-get update
sudo apt-get install mysql-server=8.0.33-1ubuntu22.04
建议下载官方二进制包手动安装,可以更灵活控制版本。我曾经因为主从版本差了一个小版本号(5.7.28 vs 5.7.29),导致GTID复制异常,排查了整整两天。
3. 主库配置详解
3.1 核心参数优化
编辑/etc/mysql/my.cnf主配置文件时,这些参数需要特别注意:
ini复制[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
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
# 关键:为从库预留资源
innodb_buffer_pool_size = 12G # 假设机器有16G内存
innodb_log_file_size = 2G
table_open_cache = 4000
3.2 创建复制账号的正确姿势
很多教程建议用root账号做复制,这是极其危险的做法。应该创建专用复制账号:
sql复制CREATE USER 'repl'@'localhost' IDENTIFIED BY 'ComplexP@ssw0rd';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'localhost';
ALTER USER 'repl'@'localhost' REQUIRE SSL; # 强制SSL加密
记得执行FLUSH PRIVILEGES后立即在从库测试连接:
bash复制mysql -urepl -pComplexP@ssw0rd -h127.0.0.1 --ssl-mode=REQUIRED
4. 从库配置实战
4.1 配置文件关键差异
从库的my.cnf需要特别关注这些参数:
ini复制[mysqld]
server-id = 2 # 必须与主库不同
relay_log = /var/log/mysql/mysql-relay.log
log_slave_updates = ON # 允许级联复制
read_only = ON # 关键保护措施
skip_slave_start = ON # 防止自动启动复制
# 资源隔离配置
innodb_buffer_pool_size = 4G
innodb_io_capacity = 200
4.2 启动复制的完整流程
- 先导出主库数据(注意锁表方式):
sql复制FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS; -- 记录File和Position
-- 新开终端执行
mysqldump -uroot -p --all-databases --master-data > dump.sql
UNLOCK TABLES;
- 导入数据到从库:
bash复制mysql -uroot -p < dump.sql
- 配置复制链路:
sql复制CHANGE MASTER TO
MASTER_HOST='127.0.0.1',
MASTER_USER='repl',
MASTER_PASSWORD='ComplexP@ssw0rd',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=154,
MASTER_SSL=1;
START SLAVE;
- 验证复制状态:
sql复制SHOW SLAVE STATUS\G
-- 确保Slave_IO_Running和Slave_SQL_Running都是Yes
-- Seconds_Behind_Master应该逐渐减小
5. 性能监控与故障处理
5.1 关键监控指标
建议部署以下监控项(示例PromQL表达式):
code复制# 主库写入压力
rate(mysql_global_status_commands_total{command="query"}[1m])
# 从库复制延迟
mysql_slave_status_seconds_behind_master
# 资源竞争监控
process_resident_memory_bytes{instance="localhost:9104"}
system_cpu_usage{instance="localhost:9100"}
5.2 常见故障处理手册
问题1:从库SQL线程停止,错误1236
解决方案:
sql复制STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
-- 如果频繁发生,考虑重置复制
问题2:主从数据不一致
校验工具:
bash复制pt-table-checksum --replicate=test.checksums h=127.0.0.1,u=root,p=password
pt-table-sync --replicate test.checksums h=127.0.0.1,u=root,p=password --print
问题3:磁盘IO瓶颈
优化方案:
ini复制# 调整从库参数
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK
innodb_flush_neighbors = 0
6. 高级调优技巧
6.1 资源隔离方案
使用cgroups限制从库资源占用:
bash复制# 创建mysql-slave控制组
cgcreate -g cpu,memory:/mysql-slave
# 限制从库进程
echo "50000" > /sys/fs/cgroup/cpu/mysql-slave/cpu.cfs_quota_us
echo "4G" > /sys/fs/cgroup/memory/mysql-slave/memory.limit_in_bytes
6.2 读写分离实现
通过MySQL Router配置自动分流:
ini复制[routing:read_write]
bind_address=0.0.0.0
bind_port=6446
destinations=127.0.0.1:3306
protocol=classic
[routing:read_only]
bind_address=0.0.0.0
bind_port=6447
destinations=127.0.0.1:3307
protocol=classic
应用连接串示例:
python复制# 写操作
write_conn = pymysql.connect(host='127.0.0.1', port=6446)
# 读操作
read_conn = pymysql.connect(host='127.0.0.1', port=6447)
在实际使用中,我发现当主库突发大量写入时,从库查询响应时间会明显上升。这时可以通过设置从库的innodb_thread_concurrency参数来保证查询稳定性,通常设置为CPU核数的2倍效果最佳。
