
刚接触Zabbix监控MySQL的时候我一度以为这不就是装个agent、选个模板、填个地址的事吗真正动手才发现从监控账号怎么建、agent怎么配、脚本怎么写到模板宏怎么覆盖每一环都有不少隐含前提。最尴尬的是搜了一堆文章大多只讲“照着点”不讲“为什么这么点”一旦环境有点差别就全废了。这篇文章就以“agent监控mysql”为主线把Zabbix通过Agent方式监控MySQL的完整链路拆开讲一遍。包括整体架构、指标选型、监控账号创建、UserParameter关键配置、模板与宏设置、问题排查经验。我尽量按实际动手的顺序写把能复用的脚本和可落地的参数都放进来。不管你是刚开始试水的运维新手还是已经被线上监控搞到头大的数据库管理员这篇都能给你省点时间。先说明一点标题里的agent指的是Zabbix Agent这个数据采集组件不是说现在风口上的AI Agent。Zabbix Agent是部署在被监控服务器上的轻量进程负责采集本机各种状态指标再回报给Zabbix Server。我的整个方案就是围绕它展开的。1. 先用“框架”眼光看agent监控MySQL这件事1.1 三个角色分别干什么在Zabbix监控MySQL的业务场景里一共有三个核心角色。搞清楚它们的职责后面配置才能不迷糊。MySQL实例被监控对象它对外提供3306端口和本地socket里面保存着数据库的各种运行指标、状态变量和慢查询日志。Zabbix Agent部署在MySQL所在服务器上的采集器以普通用户或root身份运行按Zabbix Server的指令去执行探测。它本身不分析数据只负责“取数”把结果返回给Server。Zabbix Server负责统一下发采集任务、接收数据、触发告警并写入历史数据库。策略、阈值、通知都在这层配置。你可以把Agent理解成“驻场巡检员”Server是“中控台”。巡检员按工单去设备前读数把数字报回中控台中控台负责判断有没有超标、需不需要找人处理。MySQL是“设备本身”。1.2 为什么偏要用agent而不是SNMP或其他手段监控MySQL的方式很多常见的有SNMP、外部脚本、JDBC直连、Zabbix Agent。但我在实际落地时绝大多数场景都优先选Agent理由很直接。相比SNMPAgent走的是Zabbix私有协议能直接在MySQL服务器本地执行SHOW GLOBAL STATUS、SHOW MASTER STATUS这类命令。SNMP想拿到这些信息得额外写脚本或依赖厂商MIB库很多MySQL状态项根本取不到。相比JDBC直连Agent避免了在Zabbix Server和数据库之间打开网络数据库连接。JDBC直连需要放开数据库端口给监控服务器安全审计时很容易被标红。Agent方案里Zabbix Server只访问Agent的10050端口数据库连接全部发生在MySQL本机到本地socket之间安全边界清晰得多。相比纯粹的外部脚本Agent有天然的集成优势不用自建调度、不用考虑失败重试、模板里已经定义好了数百个监控项和触发器导入即用。你要写的只是几个核心的自定义采集命令。另外还有一个“看不见”的优势Agent可以拿到操作系统层的信息。监控MySQL的时候你经常要结合CPU、内存、磁盘I/O判断是不是硬件瓶颈。如果选JDBC方案OS层指标还得另起一套系统去采数据对上号非常费劲。Agent一台机器搞定两件事省掉不少对齐的功夫。1.3 方案整体架构和默认工作流我的监控方案最终长这样Zabbix Server通过Agent的被动检查模式向被控端发起请求Agent收到请求后调用UserParameter定义的shell脚本脚本执行mysqladmin status、SHOW GLOBAL STATUS这类命令把数值返回给ServerServer再按模板规则入库并评估触发器。整个链路里MySQL上只需要额外建一个低权限的监控账号Agent上一共就一个自定义配置文件加一个脚本文件改动面非常小。这也是我推荐这个方案的最大原因——出问题好回退拔掉一个UserParameter就恢复原状了。2. 想清楚再动手这四类指标必须盯住很多教程上来就教你怎么配模板但我觉得更值得先聊的是到底要监控哪些指标。指标选得不对后面的告警全是噪音。2.1 基础状态类指标先确认数据库还活着监控的第一层一定是“探活”。数据库如果已经挂了后面的性能分析全都失去意义。探活我习惯看两个点一个是端口层面mysqladmin ping能不能返回正常另一个是逻辑层面能不能真正执行一条SELECT 1。端口通不代表数据库能正常服务有时候实例处于“假死”状态端口还在但连接已经严重排队。常见做法是执行mysqladmin ping但返回值只有mysqld is alive这一句对Zabbix来说还要做文本匹配。我更倾向于直接构造一个SELECT 1的检测返回1就认为存活。这个判断更接近业务视角——能响应SQL的数据库才是活着的。2.2 性能与容量类指标日常运维的主战场这一层指标是监控的核心也是我花时间最多的地方。优先级最高的是这几个Threads_connected当前连接数。它直接反映数据库并发压力也是判断max_connections是否需要扩容的最直观依据。Threads_running正在执行的线程数。它比连接数更能说明真实的CPU竞争情况如果这个值长期超过CPU核数好几倍基本可以断定存在慢查询或锁等待。Slow_queries累计慢查询数。注意它是一个累计值要结合时间间隔算速率不能只看绝对值。QPS / TPS每秒查询数和每秒事务数。这两个指标反映数据库的主业务流量做容量规划和活动保障时必看。Innodb_buffer_pool_read_requests 和 Innodb_buffer_pool_reads这两个值的比例就是缓冲池命中率。命中率高说明大量读操作在内存里就完成了如果持续偏低就要评估是不是innodb_buffer_pool_size配小了。连接数这块我特别说一下。很多团队的告警阈值是“连接数达到max_connections的80%就报警”这个思路方向对但细节上要注意max_connections默认值可能是151如果没改过80%就是120而业务稍微一忙就可能打满。更好的做法是先摸清线上真实的连接数水位再定阈值而不是套默认值。2.3 复制与一致性指标主从架构的生命线只要你的MySQL用了主从复制复制状态监控就是优先级最高的监控项没有之一。复制中断的伤害可以看这个真实场景某天业务方报线上数据查不到排查发现从库SQL线程早在12小时前就停了这期间主库的binlog一直堆积从库落后了几十万个事务。如果复制监控做得好这个问题应该早在12小时前就触发告警了。复制监控核心看两个指标Slave_IO_RunningI/O线程是否在正常接收主库binlog。Slave_SQL_RunningSQL线程是否在正常回放relay log。在MySQL 8.0里这两个值对应SHOW REPLICA STATUS中的Replica_IO_Running和Replica_SQL_Running。另外建议监控Seconds_Behind_Source这个值是从库延迟的秒数虽然不是绝对精确但对日常告警足够了。2.4 告警阈值设计原则阈值设计比大部分人想象的重要。我踩过几次坑后总结出三个原则第一阈值要分级。不要把所有指标都设为同一个严重级别。探活类指标直接P1复制中断P1连接数超限P2慢查询速率偏高P3。分级的意义在于半夜收到告警时值班的人能快速判断该不该爬起来处理。第二尽量用速率而不是绝对值。像Slow_queries、Queries这类累计值一定要转成“每分钟增量”再做阈值判断。否则一旦累计值超过阈值告警就永远不会恢复。第三上线前要做“告警演练”。故意停掉复制、调低连接数限制触发一次真实告警看看告警消息能不能正确送达恢复后能不能自动恢复。不要等故障真来了才去验证告警链路。3. 环境与监控账号先把路修通3.1 环境版本与拓扑规划这篇文章的实操部分我以一套相对主流的配置为例。数据库用的是MySQL 8.0操作系统是CentOS 7兼容环境Zabbix Server端是6.0 LTS版本被监控端安装的Zabbix Agent版本也是6.0。模板选择上我用的Zabbix官方自带的“MySQL by Zabbix agent 2”和“MySQL by Zabbix agent”各调过一套最终稳定使用的是官方模板配合自定义UserParameter因为可控性更强。有一个容易忽略的版本提醒Zabbix Server、Zabbix Agent、模板这三者最好保持大版本一致。比如6.0的Server去连6.0的Agent没问题但如果Agent是老版本5.0某些新模板项可能不兼容。比如模板里的某些item类型在老Agent上不被识别就会出现“该监控项不受支持”的经典红字。这个坑我踩过不止一次现在统一版本成了我的铁律。3.2 创建最小权限监控账号监控MySQL不需要给root权限但权限也不能太小。我之前图省事直接用了业务账号结果连接数统计把监控本身的连接也算进去了导致指标失真。推荐的做法是单独建一个专用监控账号。这里的关键SQL如下CREATE USER zbx_monitor127.0.0.1 IDENTIFIED BY 这里写一个强密码; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO zbx_monitor127.0.0.1; FLUSH PRIVILEGES;三个权限各有用途PROCESS权限允许执行SHOW PROCESSLIST等管理命令这是采集连接数类指标的基础REPLICATION CLIENT权限允许查看主从复制状态SELECT权限允许从performance_schema和sys库中读取性能数据。注意host我限定为127.0.0.1因为Agent就运行在本机不需要从外部访问。这个方法虽然限制了一点灵活性但安全性大大提高了审计的时候也说得清楚。3.3 避开MySQL 8的认证插件坑MySQL 8.0默认的认证插件是caching_sha2_password而Zabbix Agent端的MySQL客户端库如果版本比较老可能不支持这个插件连接时直接报Authentication plugin caching_sha2_password cannot be loaded。如果遇到这个问题通常有两个解法方案A升级Agent端的MySQL客户端库或改用官方较新的MySQL Shell。方案B把监控账号的认证插件改成mysql_native_password。在测试环境或兼容性不确定时方案B最省事。创建账号时直接指定CREATE USER zbx_monitor127.0.0.1 IDENTIFIED WITH mysql_native_password BY 这里写一个强密码; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO zbx_monitor127.0.0.1; FLUSH PRIVILEGES;不过需要注意从MySQL 8.0.34开始mysql_native_password被标记为废弃未来大版本会移除。所以这个解法更多是“应急兼容”新环境建议优先升级Agent端的客户端组件。还有一个我看到很多人踩过的坑账号建好了但密码里带特殊字符比如、$、!之类的。这些字符在shell脚本里如果没转义会直接导致连接失败或者连接串被截断。所以我写监控脚本时会强烈建议监控账号的密码尽量只用大小写字母和数字别给自己埋雷。4. UserParameter核心配置全解析4.1 UserParameter语法与检查顺序Zabbix Agent自带的监控项覆盖了系统层的大多数指标但MySQL指标不属于系统通用项所以必须通过UserParameter把自定义的采集脚本“挂”到Agent上。UserParameter的语法非常简单在agent配置文件的/etc/zabbix/zabbix_agentd.conf.d/目录下新建一个文件比如mysql_status.conf内容格式为UserParametermysql.status[*],/etc/zabbix/scripts/mysql_status.sh $1 $2我来拆解一下这行的含义。mysql.status[*]是监控项的key[*]表示这个key接收参数逗号后面是Agent收到请求时要执行的命令脚本路径加上参数位。当Zabbix Server端定义一个key为mysql.status[Uptime]的监控项Agent收到后就会执行/etc/zabbix/scripts/mysql_status.sh Uptime如果key定义为mysql.status[Com_select,10]则执行/etc/zabbix/scripts/mysql_status.sh Com_select 10。参数通过$1、$2传给脚本非常灵活。文件放好后记得重启agent服务systemctl restart zabbix-agent检查配置是否加载可以用zabbix_agentd -t命令zabbix_agentd -t mysql.status[Uptime]如果返回[q]开头的结果说明配置生效了如果返回[ZABBIX-5041]之类的错误多半是key没匹配上或脚本路径有问题。4.2 mysql_status.sh脚本拆解脚本是整套方案里最核心的部分。我给出的脚本是我在线上环境稳定跑过很久的版本为了可读性和安全性做了一些优化。#!/bin/bash # MySQL Zabbix Agent 自定义监控脚本 # 支持通过第一个参数动态获取不同的状态指标 MYSQL_CMD/usr/local/mysql/bin/mysql SOCKET/tmp/mysql.sock MYSQL_USERzbx_monitor MYSQL_PASSWORD这里换成你的强密码 # 统一从环境变量读取避免密码出现在进程列表 export MYSQL_PWD${MYSQL_PASSWORD} get_status() { local key$1 ${MYSQL_CMD} --socket${SOCKET} -u${MYSQL_USER} -N -e \ SHOW GLOBAL STATUS LIKE ${key} 2/dev/null | awk {print $2} } get_variable() { local key$1 ${MYSQL_CMD} --socket${SOCKET} -u${MYSQL_USER} -N -e \ SHOW VARIABLES LIKE ${key} 2/dev/null | awk {print $2} } case $1 in ping) ${MYSQL_CMD} --socket${SOCKET} -u${MYSQL_USER} -N -e SELECT 1 2/dev/null ;; version) get_variable version ;; uptime) get_status Uptime ;; threads_connected) get_status Threads_connected ;; threads_running) get_status Threads_running ;; slow_queries) get_status Slow_queries ;; qps) # QPS Questions / Uptime直接返回原始值实现在模板里用计算型监控项处理 echo $(( $(get_status Questions) / $(get_status Uptime) )) ;; com_select) get_status Com_select ;; com_insert) get_status Com_insert ;; com_update) get_status Com_update ;; com_delete) get_status Com_delete ;; buffer_pool_hit_rate) # InnoDB缓冲池命中率这里返回的是百分比数值 local reads$(( $(get_status Innodb_buffer_pool_read_requests) )) local disk_reads$(( $(get_status Innodb_buffer_pool_reads) )) if [ ${reads} -gt 0 ]; then echo scale2; (1 - ${disk_reads} / ${reads}) * 100 | bc else echo 0 fi ;; slave_io_running) echo $(get_replica_status Replica_IO_Running) ;; slave_sql_running) echo $(get_replica_status Replica_SQL_Running) ;; seconds_behind_master) echo $(get_replica_status Seconds_Behind_Source) ;; *) echo UNKNOWN_PARAMETER ;; esac这个脚本有几个设计点值得单独说。第一用MYSQL_PWD环境变量实现免交互比在命令行里写-p密码更安全因为-p密码形式的密码会出现在进程列表里执行ps aux就能看到明文这是个很典型的隐患。第二通过动态传入key的方式把几十个监控项收敛到同一个脚本里。新增一个指标不需要改脚本只需要在模板里加一个key为mysql.status[新指标名]的监控项即可非常方便。第三QPS的计算我故意返回的是Questions除以Uptime的均值。严格来说更精确的QPS应该取两个相邻时间点的差值但Zabbix模板里可以用change()或rate()这类预处理函数来做脚本层只要返回原始值就行。实际使用时我更推荐模板里用rate()计算每秒增量这样得到的曲线更平滑也更贴近瞬时波动。4.3 配置后必须做的三步验证配置完成后一定要按下面三步验证不能直接丢给Zabbix Server那边就完事了。第一步在Agent本机验证脚本能跑通chmod x /etc/zabbix/scripts/mysql_status.sh /etc/zabbix/scripts/mysql_status.sh uptime如果返回的是数字说明脚本本身没问题如果报错先看是不是权限、socket路径、密码环境变量的问题。第二步用zabbix_agentd -t验证Agent能否正确执行这个keyzabbix_agentd -t mysql.status[uptime]这一步验证的是UserParameter配置是否被Agent正确加载以及参数传递是否正常。如果这里能出结果网络链路基本就通了。第三步在Zabbix Server端本机用zabbix_get验证Server能不能从Agent取到值zabbix_get -s 192.168.1.100 -p 10050 -k mysql.status[uptime]zabbix_get在Server端装了Zabbix Server包后就会自带。这一步是模拟Server拉取数据的完整过程如果这里通了接下来配模板和监控项就水到渠成了。注意防火墙要放通10050端口否则这一步会卡在连接超时。5. 模板导入与宏让监控项自动铺开5.1 官方模板还是Percona模板Zabbix里有两套主流的MySQL监控模板一套是官方自带的“MySQL by Zabbix agent”另一套是Percona提供的模板。我两套都用过说说我的取舍。官方模板的优势是和Zabbix版本强绑定兼容性好导入可用升级Zabbix时模板一般也能平滑迁移。但它覆盖的指标大多偏基础比如连接数、缓冲池命中率、慢查询数等对高级指标覆盖不足。Percona模板的指标非常丰富从InnoDB行锁等待到临时表创建到排序缓冲命中率几乎全都有。但它的配置路径依赖mysqladmin客户端并且需要Percona Toolkit的环境支持落地成本高。我用Percona模板的时候遇到过几次版本更新后脚本路径变了导致一堆监控项变红的状况。所以我最终的选择是官方模板兜底自定义UserParameter补齐指标。这样既不需要引入额外依赖又能覆盖我关心的核心指标。5.2 用宏管理账号密码Zabbix模板里有一个非常聪明的设计就是宏Macro。它允许你不在每个监控项里写死账号密码而是通过模板或主机级别的宏统一管理。官方模板里会用到{$MYSQL.DSN}、{$MYSQL.USER}这类的宏。对于自定义的UserParameter方案我们可以在主机上配置宏来管理数据库用户名和密码然后在脚本里读取。但我这边的推荐方式更简单直接如果走UserParameter密码就写在脚本环境变量里不通过宏传递因为UserParameter的key本身没有宏释放能力。如果你用的是Zabbix Agent 2情况就不一样了。Agent 2内置了MySQL的采集插件可以直接在模板宏里配置{$MYSQL.USER}和{$MYSQL.PASSWORD}由Agent 2插件直连数据库采集。这种方式比UserParameter更优雅不需要维护shell脚本但需要安装zabbix-agent2包并且数据库要允许Agent 2所在主机连接。如果你的环境推进得动我其实更推荐Agent 2方案。它配置简洁、插件内置、报错信息清晰还能用zabbix_agent2 -t直接测试插件。这篇文章的核心思路依然适用于Agent 2只是把“自定义shell脚本”替换成“内置mysql插件”而已。5.3 触发器和图表的微调思路模板导入后不是万事大吉。官方模板自带的触发器阈值对很多业务来说太“学院派”了。比如Threads_connected告警阈值模板里默认75%的max_connections就触发警告但有些业务晚上的连接数长期就在85%附近震荡如果照搬模板你会发现晚上告警响个不停。我的处理思路是这样的先静默观察一周在“监测 → 主机 → 图形”里看每个关键指标的真实水位。然后按“正常水位上浮30%作为警告线上浮50%作为严重线”的原则去改模板里的宏值或触发器表达式。举个例子某套库白天连接数峰值在200左右max_connections是1000那我就不需要套75%的默认阈值直接设last(/MySQL host/threads_connected)300为警告高于500为严重。这样告警是“跟着业务走”而不是“跟着模板走”。这里额外分享一个我常用的开发技巧在Zabbix里新建一个“调试主机组”把你正在调模板的主机放进去配置一个只发给指定收件人的告警媒介然后在这个组里调阈值、调触发器表达式。调好确认无误后再挪到正式业务主机组。这个流程能极大减少“测试告警轰炸占用正式告警通道”的问题我强烈建议团队使用。6. 排查实录与常见坑速查表6.1 高发问题速查表下面这张表是我这几年用Zabbix监控MySQL时遇到最多的问题和对应的解决办法。基本覆盖了90%的新手故障。问题现象根因解决办法监控项显示“不受支持”UserParameter key与模板key不匹配或脚本执行失败用zabbix_agentd -t定位Agent端问题确认key和脚本都正常监控项显示“超时”Agent执行命令耗时超过Zabbix默认超时时间通常10秒查脚本是否卡在连接数据库上socket路径是否正确适当调整Timeout参数探活项一直返回0脚本里的SELECT 1执行不了多半是账号权限问题用监控账号手动执行SELECT 1确认是否有SELECT权限确认认证插件是否兼容连接数指标明显偏高监控账号也被算进了连接数或者多个Zabbix监控项同时连接用专用监控账号把采集频率调低避免自身连接污染指标Agent端日志报ZABBIX-5041用户参数key在Agent端没有被加载确认配置文件放在include目录里重启agent后用zabbix_agentd -p查看已加载key列表模板导入后大量监控项显示“不支持”Server和Agent版本跨度太大模板要求的新监控项类型Agent不支持统一大版本必要时用Agent 2内置插件替代UserParameter脚本密码含特殊字符导致脚本连接失败特殊字符在脚本里被shell或MySQL解析只使用大小写字母和数字或者用MYSQL_PWD环境变量避免特殊字符进命令行主从延迟显示为NULL从库不在复制状态或MySQL 8.0字段名变化脚本取不到对应字段检查复制配置确认是用Replica_IO_Running而不是MySQL 5.7的Slave_IO_Running这里想重点展开一下“数据精度”的问题。有一段时间我发现Zabbix里的小数指标比如缓冲池命中率全部显示为0排查到最后发现是脚本里用了bc命令但Agent运行环境里的bc没有安装导致整个脚本直接报错返回空。从此以后我的习惯是要么在脚本里用纯shell表达式计算要么在目标机器上提前确认bc、awk这些工具都齐全。依赖缺失是脚本类监控项最容易踩的暗坑没有之一。6.2 排查思路的“由近到远”原则如果哪天监控项变红了不要慌按下面的顺序排查效率最高。先看Zabbix Server前端页面的监控项报错内容。Zabbix 6.0之后的版本监控项的最新数据页会直接给出比较具体的错误描述比如“no info for key”“timeout while executing”“receiver 127.0.0.1 timeout”等。这个信息能帮你锁定问题出在哪个环节。再说Agent端看日志文件/var/log/zabbix/zabbix_agentd.log。Agent日志会记录执行UserParameter时的错误信息包括脚本返回值、超时情况等。很多“脚本权限不对”“文件不存在”这类问题日志里都有明确线索。最后再用zabbix_get从Server端发起一次手动采集。这是最直接有效的验证手段。如果zabbix_get能拿到数据说明Agent、脚本、网络都没问题问题多半在模板监控项配置上比如key写错了、参数顺序不对、宏没替换成功。我总结成一个口诀先看前端报错再翻Agent日志最后手动测试。从外层到内层逐层剥开看问题不要一上来就怀疑写脚本写错了。80%的情况都是配置层面的小细节真正需要看代码修复的脚本问题反而很少。6.3 一些压箱底的小经验最后这部分是我长期用agent监控MySQL攒下来的一些不太好系统归类、但确实有用的经验。第一脚本里的时间参数要慎重。不要在自定义监控脚本里做复杂的判断逻辑比如“如果今天是周末就怎样”。Zabbix的UserParameter是高频海量执行的脚本越简单越不容易出问题。复杂的判断、计算尽量放到Zabbix的预处理函数或触发器表达式里做那才是它该干的事。第二UserParameter脚本要考虑并发。如果模板里配置了大量的监控项同一时刻Agent可能并发执行多个脚本实例。脚本内部尽量不要用临时文件所有数据都通过变量传递。如果必须用临时文件一定要加$$后缀比如/tmp/mysql_tmp_$$.txt避免多个实例互相覆盖。第三模板导入之前先在一台测试机上做全流程验证。不要直接在上一百台主机上导入模板除非你非常确定每个监控项的key都和Agent端配置对得上。我见过最惨的案例是把模板导入整个主机群后发现有一半的监控项key对不上瞬间几千个“不支持”报警直接把告警通道打爆。正确做法是先在单台主机上导入模板观察10分钟确认数据正常后再批量关联。第四告警恢复通知必须开。很多人只配了问题告警没配恢复通知。结果半夜被叫醒来处理问题处理完了没通知心里还得惦记着“到底恢复了没有”。配置告警动作时把“恢复操作”也加上能省很多不必要的牵挂。第五定期做一次监控数据有效期检查。Zabbix默认的历史数据保留时长和趋势数据保留时长需要按需调整。对于高频采集的MySQL监控项历史数据保留时间不宜太长否则数据库膨胀很快。但主从延迟和连接数这两个指标建议保留时间长一些方便未来做故障复盘和容量分析。写在最后做监控这行我越来越觉得工具永远是第二位的第一位是理解你要守护的东西是什么。Zabbix Agent只是帮你把MySQL的内部状态搬到了屏幕上真正判断“这个库有没有问题、问题有多严重”的还是背后对数据库本身的理解。最后分享一个我自己的小习惯每次新接一个MySQL实例第一件事不是装agent、配模板而是先登录上去执行SHOW GLOBAL STATUS把Uptime、Threads_connected、Innodb_buffer_pool_read_requests这几个值看一遍亲手验证一遍数据源。这个习惯帮我避开了大量模板失效和监控数据不准的坑。如果你正准备在公司里落地一套MySQL监控不妨就按这篇文章的路径走一遍。先建好最小权限监控账号配好UserParameter脚本用zabbix_get验证通了再导入模板、慢慢调阈值。整个过程踩不了几个大坑但收获的是一个真正能说明白“数据库到底跑得怎么样”的监控大盘。