performance_schema默认禁止普通用户访问是出于安全考虑,因其直接映射内存结构,可能被滥用于绕过审计或探测内部状态;mysql 5.7+默认关闭非root用户所有权限,需显式grant select并确保instruments/consumers已启用。
为什么 performance_schema 默认不给普通用户查?
因为 performance_schema 不是普通数据库,它底层直接映射服务器运行时内存结构,读取本身几乎无开销,但暴露太多内部状态可能被滥用(比如绕过审计、探测锁竞争模式)。mysql 从 5.7 开始默认关闭所有非 root 用户的访问权限,连 select 都会被拒绝——这不是 bug,是安全策略。
常见错误现象:ERROR 1142 (42000): SELECT command denied to user 'u1'@'%' for table 'events_statements_summary_by_digest',哪怕你已经给了 SELECT 权限到 performance_schema.*,也照样报错。
- 必须显式用
GRANT SELECT ON performance_schema.* TO 'u1'@'%',不能靠GRANT ALL PRIVILEGES自动覆盖 - MySQL 8.0+ 还要额外确认用户是否启用
show_compatibility_56=OFF(默认值),否则部分视图名不一致 - 授权后需执行
FLUSH PRIVILEGES,否则权限不生效(尤其在旧版本或跳过 grant tables 启动后)
GRANT SELECT 到底该授哪些表?
别一股脑 GRANT SELECT ON performance_schema.*。很多表(如 mutex_instances、rwlock_instances)需要 PROCESS 或 SUPER 权限才能查,普通用户授了也没用,反而增加审计风险。
推荐按需最小授权:
- 只查 SQL 执行摘要:授
events_statements_summary_by_digest、events_statements_current、setup_consumers - 查连接和线程状态:加
threads、processlist(注意:MySQL 8.0.14+ 才支持非 super 用户查processlist) - 查索引 I/O:授
table_io_waits_summary_by_index_usage,但得确保对应业务库表已开启相应 instrument(见下节)
示例:GRANT SELECT ON performance_schema.events_statements_summary_by_digest TO 'u1'@'%'; GRANT SELECT ON performance_schema.threads TO 'u1'@'%';
开了权限还是查不到数据?检查 instruments 和 consumers
授了权 ≠ 能看到数据。performance_schema 是“按需采集”,默认只开最基础的 few instruments(比如只开 statement/sql/select,不开 statement/sql/insert),且 consumers 默认关掉大部分汇总表。
用户能查到空结果,大概率是这两个地方没配:
- 确认
setup_instruments中对应 instrument 的ENABLED和Timed都为YES(比如查慢 SQL 得开statement/sql/*类) - 确认
setup_consumers中对应 consumer(如events_statements_history_long)设为ENABLED = YES - 修改需用
root执行:UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE 'statement/sql/%';
注意:这些配置重启失效,建议写进 my.cnf 的 [mysqld] 段:performance-schema-instrument='statement/sql/%=ON'
MySQL 8.0 的角色授权方式更简洁,但有兼容陷阱
8.0 支持用角色统一管理 performance_schema 权限,比如建个 ps_monitor 角色再赋权,比每个用户单独 GRANT 更可控。
但要注意:
- 角色必须先
CREATE ROLE 'ps_monitor',再GRANT SELECT ON performance_schema.* TO 'ps_monitor' - 用户要
GRANT 'ps_monitor' TO 'u1'@'%',且登录后需SET ROLE 'ps_monitor'(除非设为默认角色) - 如果用户之前用
GRANT ... WITH GRANT OPTION授权过别人,角色方式下这个链路会断——WITH GRANT OPTION不继承角色权限
真正容易被忽略的是:performance_schema 的权限检查发生在语句解析阶段,不是执行阶段。哪怕你只 SELECT COUNT(*) FROM events_statements_summary_by_digest,只要表名出现在解析树里,就触发权限校验。所以别指望用视图或存储过程绕过。










