创建Grafana只读账号需授权SELECT on监控库(如monitoring.*)及INFORMATION_SCHEMA.TABLES、COLUMNS(必要)、STATISTICS(可选),禁用全库授权,注意账号主机匹配与MySQL 8认证兼容性。

创建只读账号前先确认监控库名和表结构
Grafana 连 MySQL 通常用 mysql 数据源插件,它不依赖存储过程或视图,只要能 SELECT 到指标表就行。但很多人直接用 root 或业务账号连,存在权限过大风险。实际只需对 Grafana 查询的库(比如叫 monitoring、metrics 或 grafana_metrics)授予 SELECT,且**不能漏掉 INFORMATION_SCHEMA 的部分表**——因为 Grafana 在配置数据源时会查 INFORMATION_SCHEMA.TABLES 和 INFORMATION_SCHEMA.COLUMNS 来自动补全表名/字段名,否则界面报错 Access denied for user ... to database 'INFORMATION_SCHEMA'。
- 先登录 MySQL 确认监控库是否存在:
SHOW DATABASES LIKE 'monitoring'; - 检查 Grafana 查询语句里涉及哪些表,例如
cpu_usage、disk_io,确保它们确实在目标库中 - 若用 Prometheus + mysqld_exporter 上报指标,它默认写入的是本地临时库(如
mysqld_exporter),不是必须建库——这时 Grafana 实际连的是 exporter 暴露的 HTTP 接口,**根本不用 MySQL 账号**;只有直接查 MySQL 表才需要配账号
执行 GRANT 时必须显式指定库和表范围
MySQL 的 GRANT 对 INFORMATION_SCHEMA 是受限的:你不能直接 GRANT SELECT ON INFORMATION_SCHEMA.* TO ...,但可以针对具体表授权。Grafana 最低可用权限组合是:
-
SELECTonmonitoring.*(替换成你的实际库名) -
SELECTonINFORMATION_SCHEMA.TABLES -
SELECTonINFORMATION_SCHEMA.COLUMNS -
SELECTonINFORMATION_SCHEMA.STATISTICS(可选,用于 SHOW INDEX 等操作)
执行命令示例(注意替换 grafana_reader 和 192.168.1.%):
CREATE USER 'grafana_reader'@'192.168.1.%' IDENTIFIED BY 'strong_password_123'; GRANT SELECT ON monitoring.* TO 'grafana_reader'@'192.168.1.%'; GRANT SELECT ON INFORMATION_SCHEMA.TABLES TO 'grafana_reader'@'192.168.1.%'; GRANT SELECT ON INFORMATION_SCHEMA.COLUMNS TO 'grafana_reader'@'192.168.1.%'; GRANT SELECT ON INFORMATION_SCHEMA.STATISTICS TO 'grafana_reader'@'192.168.1.%'; FLUSH PRIVILEGES;
别用 GRANT SELECT ON *.*——这等于开放所有库,包括 mysql 系统库,可能泄露用户哈希或权限配置。
测试账号是否真能被 Grafana 正常使用
光看 GRANT 成功不代表 Grafana 能连。常见失败点:
- Grafana 数据源配置里的 Host 填了
localhost,但账号是'grafana_reader'@'192.168.1.%',导致连接被拒;应统一用 IP 或改账号为'grafana_reader'@'%'(生产环境慎用) - MySQL 8 默认认证插件是
caching_sha2_password,旧版 Grafana(Client does not support authentication protocol;解决方法是创建账号时指定插件:CREATE USER 'grafana_reader'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx'; - 防火墙或安全组没放开 MySQL 端口(默认 3306),尤其云服务器上容易忽略
- Grafana 查询用了函数如
NOW()、CURRENT_DATE,这些不需要额外权限;但若用了CONVERT_TZ(),需确保mysql.time_zone表可读,否则报错Function 'convert_tz' does not exist
权限回收和定期审计不能只靠一次性 GRANT
账号建完不是一劳永逸。运维中容易忽略两点:
- 如果后续新增监控表(比如加了
network_traffic),必须手动追加GRANT SELECT ON monitoring.network_traffic TO ...,MySQL 不支持“未来新建表自动继承权限” - MySQL 5.7+ 支持角色(
CREATE ROLE),可把上述权限打包成grafana_ro_role,再GRANT给多个账号,方便批量管理;但 Grafana 本身不感知角色,只是 DBA 管理手段 - 建议在
my.cnf中开启log_error_verbosity = 3,并定期查错误日志里是否有Access denied记录,快速发现权限遗漏
最麻烦的其实是 Grafana 面板里写的 SQL 用了库名全限定(如 SELECT * FROM monitoring.cpu_usage),但某天 DBA 把库名改成 metrics_v2,而忘了同步改账号权限和面板 SQL——这时候权限没错,查询却失败,排查方向容易跑偏。


















