主题
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:3306 | DDL、延迟敏感读 |
| 直连从库(读) | 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-backupPVC) - 保留: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.yaml 的 replicas(建议 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、ProxySQLmysql_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