MySQL 主从复制是很多人第一次真正感受到“有状态系统不是多起几个 Pod 就完事”的地方。一旦进入主从结构,身份、拓扑、存储、读写路由和故障切换会同时压过来,Kubernetes 的很多状态化概念也会开始一起生效。

主从复制最基本的逻辑

  • 主库负责写入
  • 从库拉取并重放 binlog
  • 客户端通常写主、读从

概念看起来并不复杂,真正麻烦的是:复制延迟起来后怎么办,主库挂了之后怎么办,客户端到底连到了谁。

为什么 Kubernetes 会让这件事更立体

在 Kubernetes 里,一个复制集通常会依赖:

  • StatefulSet 提供稳定序号身份
  • Headless Service 提供 Pod 级 DNS
  • 每个副本独立 PVC
  • 更谨慎的 readiness 和切主逻辑

所以这篇天然应该和下面这些一起看:

  • kubernetes-quickstart-statefulset.md
  • kubernetes-quickstart-headless-service.md
  • kubernetes-quickstart-pv-pvc.md
  • kubernetes-quickstart-storageclass.md

一开始最值得确认的四件事

在你真正去看 MySQL 复制状态前,先确认:

  1. 每个副本是不是都有自己独立的 PVC
  2. 每个副本的 DNS 身份是不是稳定
  3. readiness 是不是代表真实可用
  4. 客户端是否清楚哪个地址负责写、哪个负责读

这些基础没搭对,后面主从问题通常只会显得更乱。

复制延迟为什么最值得盯

主从系统最危险的地方在于:表面看起来一切都“活着”,其实复制已经悄悄落后了。Pod Running 不代表复制健康,Service 正常也不代表读出来的数据够新。

所以,复制延迟几乎总是最关键的信号之一。

最常见的延迟来源

  • 磁盘慢
  • CPU 被打满
  • 节点间网络抖动
  • 大事务
  • readiness / promote 逻辑设计不合理

真遇到问题时,第一反应通常应该先看 IO 和资源压力,而不是先去调一堆数据库参数。

路由问题和复制问题经常混在一起

很多时候不是复制真坏了,而是流量打错地方了。

典型模式:

  • 写流量进主库 Service
  • 读流量进从库 Service
  • 管理或复制链路用 Pod 级 DNS

如果 Service selector、DNS 名称或客户端连接串写错,症状会看起来像“一致性问题”,但根因其实是路由关系错了。

一套很实用的检查单

上线或排障时,我会优先确认:

  • 主从角色是不是明确区分了
  • 每个副本是不是一卷一实例
  • 读请求到底有没有真的走到从库
  • 主库挂了以后谁来升主
  • 旧主恢复后怎么重新加入

这些问题决定了这个系统是“看起来会跑”,还是“真的能扛事”。

先看这些命令通常最有帮助

kubectl get pods -n <ns> -o wide
kubectl get pvc -n <ns>
kubectl get svc -n <ns>
kubectl get endpoints -n <ns> <svc> -o wide
kubectl describe pod -n <ns> <pod>

从 MySQL 本身看复制状态时,再补这两条:

kubectl exec -n db mysql-primary-0 -- mysql -u root -p -e "SHOW MASTER STATUS\G"
kubectl exec -n db mysql-secondary-0 -- mysql -u root -p -e "SHOW SLAVE STATUS\G"

真正的考验其实是 failover

复制最危险的错觉就是:“有副本,所以应该没问题。”

复制搭起来并不难,真正决定系统韧性的,是:

  • 主库挂了以后多久能升主
  • 客户端在切换期会怎样
  • 旧主怎么重新加入
  • 这期间会不会读到旧数据或丢数据

至少在 staging 里做一次受控切主,看看:

  • 提升主库要多久
  • 旧主重新加入要多久
  • 客户端中断窗口有多长
  • 实际一致性边界是什么

FAQ

Q: 有了主从复制,就等于高可用了吗? A: 不等于。复制只是基础能力,高可用还取决于切主逻辑、客户端路由和恢复流程是否真的可靠。

Q: 如果读出来的数据不新,第一步先查什么? A: 先看复制延迟,再看磁盘和 CPU 压力,然后确认读流量是不是确实进了从库,而不是进错了服务。

Q: 为什么 Kubernetes 没法自动帮我解决这些最难的问题? A: 因为 Kubernetes 管的是生命周期和调度,不是 MySQL 的主从协议、角色提升和业务一致性语义。

下一步阅读

  • 接着读 kubernetes-quickstart-helm-mysql-cluster.md,看 Helm 如何把这套拓扑打包成可复用安装流程
  • 回头读 kubernetes-quickstart-stateful-apps.md,从更广义的有状态运维视角理解这类系统
  • 如果你还想对照简单版本,可以再看 kubernetes-quickstart-mysql-database.md

收个尾

主从复制最容易误导人的地方在于:它很容易让系统“看起来都在跑”,但真正重要的是延迟、切主、恢复和客户端行为。这些事情只有提前演练过,线上才不会在真正出事时一下失控。

参考链接