一、MySQL 双活机制:实现无单点故障的核心方案
MySQL 双活(也叫 "主主 / 双主架构")的核心目标是让两个 MySQL 节点互为备份、均可对外提供读写服务,彻底解决单节点故障导致的业务中断问题。
1. 核心原理
双活的本质是双向主从复制 + 冲突规避机制,核心逻辑分两步:
- 双向复制:两个节点(A、B)互相配置为对方的 "主库(master)" 和 "从库(slave)"------A 同步 B 的二进制日志(binlog),B 也同步 A 的 binlog,确保两边数据一致;
- 冲突规避:最关键的是解决 "自增主键重复" 问题,给两个节点配置不同的自增规则:
- 节点 A:
auto_increment_increment=2(步长 2)、auto_increment_offset=1(起始值 1),生成 ID:1、3、5...; - 节点 B:
auto_increment_increment=2、auto_increment_offset=2(起始值 2),生成 ID:2、4、6...。
- 节点 A:
2. 关键配置要点
- 基础配置:两个节点均开启 binlog(
log_bin=ON),server_id必须不同(如 A=1、B=2),推荐开启 GTID(gtid_mode=ON)保证复制一致性; - 读写策略:建议 "读写分离"(优先写 A、读写分摊到 A/B),避免双写导致的冲突;故障切换需配合 Keepalived/ProxySQL 实现自动切换;
- 数据一致性:开启半同步复制(
rpl_semi_sync_master=ON),确保主库提交事务前,至少一个从库确认接收 binlog,减少数据丢失风险。
3. 核心价值与注意事项
- 价值:无单点故障,节点故障时业务可秒级切换,几乎无感知;
- 注意:严禁对同一条记录在两个节点同时更新,需在业务层做写隔离(如特定表仅写一个节点)。
二、MySQL 备份:从基础到最佳实践
MySQL 备份的核心目标是 "能恢复、快恢复、恢复准",主流方案分 "逻辑备份" 和 "物理备份",需结合 "全量 + 增量" 满足不同场景需求。
1. 逻辑备份(中小数据量首选)
逻辑备份是将数据导出为 SQL 语句,优点是易理解、易恢复,缺点是大数据量下效率低,核心工具是mysqldump(官方)、mydumper(多线程)。
-
全量备份实操(mysqldump):
# 备份所有库,InnoDB无锁,记录binlog位置,压缩存储 mysqldump -u root -p --all-databases --single-transaction --master-data=2 | gzip > /backup/mysql_full_$(date +%Y%m%d).sql.gz -
增量备份:基于 binlog 实现,定期备份新增的 binlog 文件:
# 刷新binlog生成新文件 mysql -u root -p -e "FLUSH LOGS" # 备份最新binlog cp /var/lib/mysql/mysql-bin.0000xx /backup/binlog/ -
恢复:先恢复全量备份,再用
mysqlbinlog执行增量 binlog,可恢复到指定时间点。
2. 物理备份(大数据量首选)
物理备份是直接拷贝数据文件,优点是备份 / 恢复速度快,核心工具是 Percona XtraBackup(开源)。
-
全量备份实操:
# 全量备份 xtrabackup -u root -p --backup --target-dir=/backup/mysql_phy_full_$(date +%Y%m%d) # 准备备份(整理数据,使其可恢复) xtrabackup --prepare --target-dir=/backup/mysql_phy_full_$(date +%Y%m%d) -
增量备份:仅备份全量备份后变化的数据页,大幅减少备份体积。
3. 备份最佳实践
- 定时执行:通过 crontab 设置 "每日全量 + 每小时增量";
- 异地存储:备份文件同步到另一服务器 / 云存储,防止本地故障;
- 定期验证:每月将备份恢复到测试库,确认数据完整、恢复流程可行。
三、Docker 资源异常:CPU / 内存飙升排查思路
Docker 中 CPU、内存飙升,核心是 "资源配额不足" 或 "容器内进程异常",需按 "从易到难" 的顺序排查:
1. 第一步:核查容器资源限制配置
先确认容器的 CPU / 内存限制是否匹配应用需求,这是最基础也最易解决的问题:
# 查看容器资源限制(重点看Memory、CpuQuota)
docker inspect <容器ID/名称> | grep -E "Memory|CpuQuota|CpuPeriod"
- 关键参数:
Memory是内存硬限制,CpuQuota/CpuPeriod(默认 100000)决定 CPU 核数(如 CpuQuota=50000 表示 0.5 核); - 问题判断:若限制的内存 / CPU 远低于应用实际需求(如 Java 程序配 - Xmx1g 但容器仅限 512m),会导致进程频繁申请资源,触发 CPU / 内存飙升。
2. 第二步:排查容器内进程占用
资源限制无问题时,需定位容器内的异常进程:
# 实时监控容器资源使用
docker stats <容器ID/名称>
# 进入容器查看进程详情
docker exec -it <容器ID/名称> top
- 常见异常:
- 代码 bug:进程死循环、无限递归,占满 CPU;
- 资源泄漏:内存泄漏(如未释放的连接、缓存),持续占用内存直至触发 OOM;
- 应用未适配 Docker:Java、MySQL 等默认读取宿主机资源,未按容器限制调整配置。
3. 第三步:核查宿主机层面资源
若容器内无异常,需看宿主机是否本身资源不足:
# 查看宿主机CPU/内存使用
top
# 查看宿主机内存详情
free -m
- 问题场景:宿主机内存耗尽,导致容器使用 swap(磁盘交换),swap 读写效率极低,会触发 CPU 飙升;宿主机 CPU 核心被占满,容器调度开销增大。
4. 第四步:日志与监控辅助定位
通过日志和监控缩小问题范围:
- 容器日志:
docker logs -f <容器ID>,查看应用是否有 OOM、连接超时等报错; - 应用日志:进入容器查看应用日志(如 Java GC 日志、MySQL 慢查询日志),定位资源消耗的具体环节;
- 监控工具:通过 Prometheus+Grafana、cAdvisor 监控容器资源趋势,确定飙升的时间点和触发条件(如定时任务、流量峰值)。
5. 常见解决方案
- 临时调整资源限制:
docker update --memory 1g --cpus 2 <容器ID>; - 适配应用配置:Java 程序添加
-XX:+UseCGroupMemoryLimitForHeap,让 JVM 识别 Docker 内存限制; - 修复根本问题:解决代码 bug、资源泄漏,优化应用性能(如慢查询、冗余计算)。