不能用 root 或高权限用户直连 mysqld_exporter,因其会将 performance_schema 中的 sql 文本等敏感元数据暴露于监控链路,一旦配置泄露即引发严重安全风险;exporter 仅需最小权限:select(information_schema、performance_schema、mysql)、process、replication client、show databases,且严禁授予 drop、grant option 或业务库访问权。

为什么不能用 root 或高权限用户直连 Prometheus MySQL Exporter
直接让 mysqld_exporter 用管理员账号连接 MySQL,等于把数据库的元数据、表结构甚至部分敏感配置(如 performance_schema 中的 SQL 文本)暴露给监控链路。一旦 exporter 配置泄露或被恶意访问,风险远超监控本身所需。
MySQL Exporter 实际只读取固定几类系统表和状态变量,比如 information_schema.tables、performance_schema.events_statements_summary_by_digest、SHOW GLOBAL STATUS 等。没必要也不应该给它 SELECT 以外的权限,更不该给 DROP、GRANT OPTION 或对业务库的任意访问权。
必须授予的最小权限集合
Exporter 启动时默认执行一系列 SQL 查询,缺失任一权限都会报错退出,常见错误如:ERROR 1142 (42000): SELECT command denied to user 或 Access denied for user ... to database 'performance_schema'。
以下权限需全部授予,且作用域限定在系统库(mysql、information_schema、performance_schema),**不涉及任何业务数据库**:
-
SELECT权限:对information_schema、performance_schema、mysql三个库的所有表(注意不是所有库) -
PROCESS权限:用于执行SHOW PROCESSLIST(检查连接数、慢查询等指标) -
REPLICATION CLIENT权限:用于获取主从复制状态(SHOW SLAVE STATUS) -
SHOW DATABASES权限:Exporter 初始化时会尝试列出数据库,否则报错Access denied; you need (at least one of) the SHOW DATABASES privilege(s)
示例建用户并授权(MySQL 5.7+):
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'your_strong_password'; GRANT SELECT ON information_schema.* TO 'exporter'@'localhost'; GRANT SELECT ON performance_schema.* TO 'exporter'@'localhost'; GRANT SELECT ON mysql.* TO 'exporter'@'localhost'; GRANT PROCESS, REPLICATION CLIENT, SHOW DATABASES ON *.* TO 'exporter'@'localhost'; FLUSH PRIVILEGES;
连接时必须禁用 autocommit 并显式指定数据库
Exporter 启动参数中若使用 --web.listen-address 等基础配置没问题,但连接串里如果漏掉 database 参数或未关闭自动提交,某些 MySQL 版本(尤其是 8.0+)会因权限校验逻辑变化导致初始化失败,错误类似:failed to ping mysqld: Error 1045: Access denied for user 'exporter'@'localhost' (using password: YES),实际是权限够但连接上下文不匹配。
正确做法是:
- 在 exporter 启动命令中,用
--config.my-cnf指向一个专用配置文件(推荐),或用--data.source显式传参 - 配置文件中必须包含
database=information_schema(任意系统库名均可,仅用于建立初始连接上下文) - 务必添加
autocommit=0—— 这不是性能优化,而是绕过 MySQL 8.0 对只读用户的事务上下文限制
示例 .my.cnf 文件内容:
[client] user=exporter password=your_strong_password host=localhost port=3306 database=information_schema autocommit=0
验证权限是否真正生效
别只信 GRANT 语句执行成功。登录 MySQL 后,用 exporter 用户身份手动执行它最常查的几条语句,确认无报错:
mysql -uexporter -pyour_strong_password -e "SELECT COUNT(*) FROM information_schema.tables;"
mysql -uexporter -pyour_strong_password -e "SELECT VARIABLE_NAME, VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME IN ('Threads_connected', 'Uptime');"
mysql -uexporter -pyour_strong_password -e "SHOW PROCESSLIST;"
mysql -uexporter -pyour_strong_password -e "SHOW SLAVE STATUS\G"
只要这几条都返回结果(哪怕空集),说明权限已就位。特别注意 SHOW SLAVE STATUS 在非从库上会返回空,不算错误;但如果报 Access denied,说明 REPLICATION CLIENT 没授对。
Exporter 日志里出现 INFO[0000] Starting mysqld_exporter 且后续无 level=error 行,才是最终确认信号。很多问题卡在 performance_schema 表不可见,本质是没开对应开关(如 setup_actors 表默认关闭),但这属于 MySQL 配置层面,和用户权限无关 —— 别一出错就加权限,先看日志里具体哪条 SQL 被拒。











