监控账号必须且仅授予select、process、replication client三项权限:select用于查询information_schema和performance_schema统计表,process用于执行show processlist获取全部会话,replication client用于执行show slave status等命令读取复制状态,缺一不可。

监控账号必须只给 SELECT、PROCESS、REPLICATION CLIENT 三项权限
第三方监控软件(如 mysqld_exporter、Zabbix agent、Prometheus MySQLd Exporter)不需要建库、删表、改用户,更不能碰 FILE 或 SUPER 这类高危权限。它真正依赖的只有三个:
-
SELECT:查information_schema和performance_schema里的统计表(比如processlist、table_io_waits_summary_by_table) -
PROCESS:执行SHOW PROCESSLIST,否则只能看到自己连接,无法发现慢查询或锁等待 -
REPLICATION CLIENT:读取主从状态(SHOW SLAVE STATUS、SHOW MASTER STATUS),缺了就看不到复制延迟
别加 SHOW DATABASES——它会暴露所有库名,违背最小权限原则;也别信“顺手加上 ALL PRIVILEGES ON *.*”,那是把数据库门钥匙直接交出去。
CREATE USER 必须显式指定 host 和认证插件
MySQL 8.0+ 默认用 caching_sha2_password,但很多监控客户端(尤其老版本 exporter)不支持,连不上就会卡在 Access denied,不是权限问题,是认证失败。
正确做法是显式指定插件并绑定真实出口 IP:
CREATE USER 'monitor'@'10.0.0.11' IDENTIFIED WITH mysql_native_password BY 'strong_pass_2026';
注意点:
- host 写成
'10.0.0.11',别用'%'或主机名——DNS 失败会导致连接拒绝 - 确认监控服务实际出站 IP,不是容器内网地址(如
172.18.0.5) - 如果监控跑在云上(如阿里云 ECS),需查其公网出口 IP,不是内网地址
GRANT 后必须立刻 REVOKE information_schema 和 performance_schema 的 SELECT 权限
看起来矛盾?其实不然:SELECT ON *.* 默认包含 information_schema 和 performance_schema,但这两个库里有些表(如 user_privileges、role_edges)含敏感元数据,监控根本不需要。
所以标准流程是:
GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO 'monitor'@'10.0.0.11';<br>REVOKE SELECT ON information_schema.* FROM 'monitor'@'10.0.0.11';<br>REVOKE SELECT ON performance_schema.* FROM 'monitor'@'10.0.0.11';
这一步在 MySQL 8.0.29+ 是强制要求,否则后续 REVOKE SELECT ON *.* 会失败——系统库权限现在要单独处理。
迁移后不能直接复用旧环境的 SHOW GRANTS 输出
从旧实例导出 SHOW GRANTS FOR 'monitor'@'10.0.0.11',拿到新库一执行就报错,常见原因有:
- 目标库还没创建该用户 → 先
CREATE USER,再GRANT - host 不匹配 → 源是
'monitor'@'10.0.0.11',新环境监控跑在容器里,实际 IP 是'172.18.0.5' - 密码字段不兼容 → MySQL 8.0+ 用
authentication_string,旧脚本可能还依赖已弃用的password字段
别找“一键迁移权限”工具,监控账号权限必须手写重建,每条 GRANT 和 REVOKE 都得精确到作用域,且不含 WITH GRANT OPTION。
最容易被忽略的是:监控账号的 host 必须和实际连接来源 IP 完全一致,哪怕多一个空格、IPv4 写成 IPv6 格式、或用了 localhost 但监控走的是 127.0.0.1,都会导致权限不生效——这不是权限没给对,是账号根本没被匹配上。











