22_MySQL 运维自动化平台 ------ 部署编排 + 监控 + 巡检 + 告警 + 工单闭环一体化
系列定位 :《MySQL 数据库全栈运维实战系列》第 22 篇(收官篇),与《Oracle 数据库全栈运维实战系列(VMware 版)》同构对标。适用版本 :MySQL 8.0(5.7 差异随文标注)。官方文档:MySQL 8.0 Reference Manual、Ansible / Prometheus / Grafana / Alertmanager 官方文档。
一、为什么需要一体化平台

图 1
前面 21 篇讲的都是"单点技能":怎么装、怎么备、怎么调、怎么修。但一个真正的 DBA 团队要管几十上百套 MySQL,靠人肉 SSH + 手抄命令一定会出事。运维自动化平台的目标是把部署、监控、巡检、告警、工单串成闭环,让 DBA 从"救火队员"变成"平台运营者"。

图 2
| 模块 | 解决什么问题 | 类比 Oracle 体系 |
|---|---|---|
| 部署编排 | 新实例 30 分钟上线,不靠手抄命令 | EMCA / DBCA 静默部署 |
| 监控 | 7×24 指标采集,不靠人肉登库 | Enterprise Manager Cloud Control |
| 巡检 | 每日健康检查,主动发现隐患 | 智能巡检脚本 |
| 告警 | 异常秒级触达,分级收敛 | EM 告警 + 邮件 |
| 工单 | 告警→建单→处置→复盘留痕 | ITSM / 工单系统 |
VMware 虚机环境注意事项:自动化平台本身也跑在虚机上,建议至少 2 台(主备),用 keepalived 飘 VIP。MySQL 节点虚机的生命周期(创建、快照、删旧实例)可以通过 vCenter API(pyVmomi / govc)纳管,实现"申请→自动开虚机→自动装 MySQL→自动加监控"全流程。生产虚机禁止 thin 盘 + 多快照,这一条要写进部署 Playbook 的前置检查。
二、部署编排:Ansible 一键装 MySQL 8.0

图 3
2.1 目录结构
mysql-ansible/
├── inventory/
│ ├── prod.ini # 生产实例清单
│ └── group_vars/
│ └── mysql.yml # 统一参数
├── playbooks/
│ ├── install_mysql.yml # 安装
│ ├── init_replica.yml # 搭从库
│ └── backup.yml # 配 Xtrabackup
└── roles/
└── mysql/
├── tasks/main.yml
├── templates/my.cnf.j2
└── handlers/main.yml
2.2 关键 Playbook 片段
# playbooks/install_mysql.yml(解释:从 yum 安装到启动到加监控,一条命令)
- hosts: mysql_nodes
become: yes
vars:
mysql_version: "8.0"
tasks:
- name: 卸载 mariadb(解释:CentOS 默认带 mariadb-libs,冲突)
yum: { name: "mariadb-libs", state: absent }
- name: 配置 MySQL 官方 yum 源
yum: { name: "https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm", state: present }
- name: 安装 MySQL Server
yum: { name: "mysql-community-server", state: present }
- name: 下发 my.cnf(解释:J2 模板按角色渲染主/从参数)
template:
src: roles/mysql/templates/my.cnf.j2
dest: /etc/my.cnf
notify: restart mysql
- name: 启动并设开机自启
systemd: { name: mysqld, state: started, enabled: yes }
- name: 取出临时密码并改密(解释:8.0 首次 root 密码在 error log)
shell: grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}'
register: tmp_pwd
changed_when: false
- name: 安装 mysqld_exporter(解释:监控采集端,第 17 篇讲过)
yum: { name: "mysqld_exporter", state: present }
# 一键执行(解释:-l 限定某台,--check 先干跑)
ansible-playbook -i inventory/prod.ini playbooks/install_mysql.yml -l db-prod-01 --check
ansible-playbook -i inventory/prod.ini playbooks/install_mysql.yml -l db-prod-01
| 收益 | 手工装 | Ansible 编排 |
|---|---|---|
| 单实例上线耗时 | 2~4 小时 | 20 分钟 |
| my.cnf 参数一致性 | 靠人记,常漏 | 模板统一渲染 |
| 新成员上手 | 看文档一周 | 看 Playbook 即可 |
三、监控采集:mysqld_exporter + Prometheus + Grafana

图 4
# /etc/prometheus/prometheus.yml 片段(解释:自动发现 MySQL 节点)
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets:
- 'db-prod-01:9104'
- 'db-prod-02:9104'
labels:
env: 'prod'
# 关键告警规则(解释:Prometheus Alert 表达式)
# 主从延迟 > 30s
(mysql_slave_status_seconds_behind_master > 30)
# 连接数使用率 > 80%
(mysql_global_status_threads_connected / mysql_global_variables_max_connections > 0.8)
# Buffer Pool 命中率 < 99%
(1 - rate(mysql_global_status_innodb_buffer_pool_reads[5m])
/ rate(mysql_global_status_innodb_buffer_pool_read_requests[5m])) < 0.99
# 磁盘满 > 85%
(mysql_global_status_innodb_data_writes / on() vector(1)) # 仅示例,真实用 node_filesystem_avail
| 看板 | 关键指标 | 对应 Oracle EM |
|---|---|---|
| 实例总览 | QPS/TPS、连接数、Buffer Pool 命中率 | 实例概览 |
| 复制状态 | 主从延迟、IO/SQL 线程状态 | DG 状态 |
| InnoDB | row lock wait、redo 刷盘、buffer pool 命中 | 性能页 |
| 主机 | CPU/内存/磁盘/IO | 主机页 |
四、智能巡检:每日健康评分脚本
#!/bin/bash
# mysql_inspect.sh(解释:每天 8 点跑,输出健康分,异常项写告警)
# 类比 Oracle 巡检脚本 / ora_check.sh
MYSQL_USER="inspect"
MYSQL_PWD="***"
REPORT=/data/inspect/$(date +%F).txt
{
echo "===== MySQL 巡检 $(date) ====="
# 1. 主从延迟
mysql -e "SHOW REPLICA STATUS\G" | grep Seconds_Behind_Source
# 2. 连接数使用率
mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';"
# 3. Buffer Pool 命中率
mysql -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';"
# 4. 慢查询今日条数
mysql -e "SHOW GLOBAL STATUS LIKE 'Slow_queries';"
# 5. 表碎片 TOP 5
mysql -e "SELECT table_name, ROUND(data_free/1024/1024) free_mb
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','sys','performance_schema')
ORDER BY data_free DESC LIMIT 5;"
# 6. 备份是否成功(解释:前一天 Xtrabackup 日志)
ls -l /backup/xtrabackup/$(date -d yesterday +%F)/ 2>/dev/null || echo "BACKUP MISSING!"
} > $REPORT
# 异常项钉钉推送
grep -E "MISSING|Seconds_Behind_Source: [0-9]{3,}" $REPORT \
&& curl -s -X POST -H 'Content-Type: application/json' \
-d '{"msgtype":"text","text":{"content":"[MySQL巡检] 发现异常,见 '$REPORT'"}}' \
https://oapi.dingtalk.com/robot/send?access_token=***
| 巡检项 | 阈值 | 类比 Oracle |
|---|---|---|
| 主从延迟 | > 30s 警告 | DG lag |
| 连接数使用率 | > 80% | sessions |
| Buffer Pool 命中率 | < 99% | buffer cache hit |
| 慢查询增量 | 突增 3 倍 | Top SQL |
| 备份成功率 | 失败即告警 | RMAN 备份 |
| 表碎片 | > 1G 列出来 | 段碎片 |
五、告警收敛与工单闭环

图 5
告警收敛三条铁律:
- 同实例同规则 15 分钟内合并,别让一块磁盘满刷 50 条告警。
- 维护窗口静默:巡检窗口、变更窗口提前 silence。
- 告警必须可执行:每条告警文案带"一键排查命令"链接,不要只发"CPU 高"。
六、闭环:一个告警从产生到复盘的完整链路

图 6