Skip to content

MySQL 高可用集群操作文档

对应部署见 部署文档。集群:命名空间 mysql,RKE2 v1.35.6。 密码统一保存在交付目录 .secrets.env(本文以 $PW 代指 root 密码)。 更新:2026-08-01

1. 连接信息速查

用途地址说明
应用统一入口mysql-proxysql.mysql.svc.cluster.local:3306自动读写分离(推荐)
直连主库(写)mysql-primary.mysql.svc.cluster.local:3306DDL、延迟敏感读
直连从库(读)mysql-secondary.mysql.svc.cluster.local:3306报表、备份取数
ProxySQL 管理pod 内 127.0.0.1:6032(admin)仅允许 localhost

账号:xxx appdb)、root(管理)、replicator(复制内部使用)。

2. 日常巡检

bash
export KUBECONFIG=~/.kube/config-122.31

# Pod 与节点分布(6 个 Pod 应 1/1 Running,分散在不同节点)
kubectl -n mysql get pods -o wide

# 复制健康(两台从库都执行):IO/SQL 线程 = Yes,Seconds_Behind 应接近 0
for s in 0 1; do
  kubectl -n mysql exec mysql-secondary-$s -c mysql -- mysql -uroot -p"$PW" \
    -e "SHOW REPLICA STATUS\G" | grep -E 'IO_Running|SQL_Running|Seconds_Behind'
done

# 备份文件(每天 02:00 北京 新增一个,超过 7 天自动清理)
kubectl -n mysql exec deploy/mysql-nfs-provisioner -- \
  sh -c 'ls -lh /persistentvolumes/mysql-mysql-backup-*/ 2>/dev/null | tail -5'

# PVC 用量
kubectl -n mysql get pvc

告警关注项(可接入 rancher-monitoring):复制线程非 Yes、Seconds_Behind_Source 持续 >60、 CronJob 连续失败、PVC 剩余空间 <20%。

3. 备份与恢复

3.1 备份策略

  • 方式:mysqldump --single-transaction --routines --triggers --all-databases | gzip
  • 频率:每天 02:00(北京),文件 mysql-YYYYMMDD-HHMMSS.sql.gz 写入 NFS(mysql-backup PVC)
  • 保留:7 天自动清理(CronJob 内 find -mtime +7 -delete
  • 一致性:--single-transaction 对 InnoDB 一致性快照,不锁表;备份期间对主库有少量 IO 压力

3.2 手动备份

bash
kubectl -n mysql create job --from=cronjob/mysql-backup mysql-backup-manual-$(date +%s)
kubectl -n mysql logs -f job/mysql-backup-manual-<TS>

3.3 恢复

bash
# 在能访问 NFS 的机器上找到备份文件,解压后灌入主库
gunzip < mysql-20260801-043441.sql.gz | \
  kubectl -n mysql exec -i mysql-primary-0 -c mysql -- mysql -uroot -p"$PW"

# 从库无需单独处理:恢复产生的 binlog 会自动同步到从库

全量恢复会重放全部 binlog,从库 Seconds_Behind 短暂升高属正常。

4. 扩缩容

4.1 增加只读从库

bash
# 修改 mysql-values.yaml 中 secondary.replicaCount 后:
helm upgrade mysql oci://192.168.122.156:30000/charts/mysql \
  --version 12.3.5 --plain-http -n mysql -f mysql-values.yaml

新从库 Pod 自动克隆主库数据并接入复制;mysql-secondary Service 自动纳入读流量。

4.2 ProxySQL 扩容

修改 proxysql.yamlreplicas(建议 2,最多不超过节点数),kubectl apply。 注意同步调整 PDB minAvailable(保持 = replicas - 1)。

4.3 存储扩容

bash
# nfs-mysql SC 已开启 allowVolumeExpansion
kubectl -n mysql patch pvc data-mysql-primary-0 -p '{"spec":{"resources":{"requests":{"storage":"50Gi"}}}}'

NFS 不提供真实配额,扩容只是更新声明值,实际容量由 NFS 服务端磁盘决定(df -h /mnt/xfs)。

5. 主库故障切换 SOP(手动)

bitnami 主从架构无自动故障转移。主库宕机且短时间无法恢复时:

bash
# 1. 确认主库确实不可用(排除网络抖动)
kubectl -n mysql get pod mysql-primary-0

# 2. 选延迟最低的从库,停复制并提升为主
kubectl -n mysql exec mysql-secondary-0 -c mysql -- mysql -uroot -p"$PW" -e "
  STOP REPLICA;
  SET GLOBAL read_only=OFF; SET GLOBAL super_read_only=OFF;"

# 3. 重置 helm release 让原从库角色转正(二选一):
#    方式A(推荐,保持声明式):调整 values 后 helm upgrade,
#    将 primary 指向新主、secondary 重建(数据量大时耗时)
#    方式B(快速恢复业务):直接把应用/ProxySQL 写指向 mysql-secondary-0 的 Pod DNS,
#    待原主修复后作为从库重新接入
# 4. 原主库修复后,清空数据目录重建为从库(helm upgrade 重建 secondary)

切换后更新 ProxySQL 写节点指向(proxysql.yaml 中 HG10 的 address),kubectl apply 并重启 ProxySQL Pod。

6. ProxySQL 管理

bash
# admin 仅允许 localhost:在 proxysql pod 内操作(镜像无 mysql 客户端,
# 用同集群任意 mysql pod 的客户端通过 pod IP 不行——6032 拒绝远程;
# 临时方案:kubectl debug 或起一个带 mysql 客户端的 pod 与 proxysql 同 pod 网络不可行,
# 推荐直接改 proxysql.yaml 的 Secret 配置后重建 Pod(配置即代码))
kubectl -n mysql edit secret mysql-proxysql-config    # 修改配置(base64)
kubectl -n mysql rollout restart deploy/mysql-proxysql

路由规则现状:SELECT ... FOR UPDATE → 主库;SELECT → 从库;其余 → 主库。 ProxySQL 对后端做 ping 监控,异常节点自动 shun,恢复后自动上线。

7. 密码管理

  • 所有密码生成于 .secrets.env,已注入 chart values 与 proxysql Secret
  • 轮换 root/应用密码:xxx values + secret 后 helm upgrade / kubectl apply, 并滚动重启 Pod;三处必须同步:MySQL 内实际密码、helm values、ProxySQL mysql_users
  • .secrets.env 不得提交公共仓库

8. 常见问题

现象原因处理
Pod CrashLoop,日志 MY-012960 Cannot create redo log files初始化被探针打断,redo 损坏删 Pod 对应 PVC 重建;确认 startupProbe 未被改小
从库 Seconds_Behind 持续增大大事务/备份高峰/NFS IO 慢观察;长期如此检查 NFS 服务端负载
备份 Job 失败NFS 抖动/空间不足看 Job 日志;df -h /mnt/xfs 查服务端空间
ProxySQL 503后端全部 shun检查 MySQL Pod 与 Service;看 proxysql 日志 kubectl -n mysql logs deploy/mysql-proxysql
应用读写未分离客户端用了连接池预热以外的语句或非 SELECT 开头(如 WITH)复杂场景在 ProxySQL 增加 query rule

9. 卸载

bash
helm uninstall mysql mysql-nfs-provisioner -n mysql
kubectl -n mysql delete -f proxysql.yaml -f backup.yaml
kubectl -n mysql delete pvc --all     # 数据随之删除(SC 回收策略 Delete),操作前确认已备份
kubectl delete ns mysql