process权限必须全局授予(on .),不可限定库或表,否则报错1221;正确命令为grant process on . to 'u'@'h';替代方案是授权select on performance_schema.threads。

PROCESS 权限必须以全局方式授予,不能限定在某个库或某张表上。普通用户默认只能看到自己的连接,要让其查看所有线程(包括其他用户的),必须显式授予 PROCESS 全局权限。
为什么 GRANT PROCESS ON mydb.* TO 'u'@'h' 会报错
MySQL 报 ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES,是因为 PROCESS 是全局权限(global privilege),不支持按数据库粒度授权。任何带具体库名(如 mydb.*)的写法都会被拒绝。
-
ON *.*是唯一合法的范围写法 -
ON mysql.*、ON test.*、ON `mydb`.*全部无效 - 即使用户只管理一个业务库,也得走全局授权路径
正确授予权限的命令和验证步骤
用高权限账号(如 root)执行:
GRANT PROCESS ON *.* TO 'monitor_user'@'%'; FLUSH PRIVILEGES;
之后让该用户登录并执行:
SHOW PROCESSLIST;
如果能看到其他用户的连接(比如 User 列出现 app_user、backup 等),说明已生效。若仍只看到自己,检查两点:
- 是否漏了
FLUSH PRIVILEGES(尤其在旧版本 MySQL 中) - 用户连接时用的 host 是否匹配授权中的
'monitor_user'@'%'—— 比如实际是'monitor_user'@'192.168.1.100',但授权写的是@'localhost',就会失败
替代方案:performance_schema.threads 更稳定
有些场景下你无法给普通用户开 PROCESS 权限(比如安全策略禁止),又需要查全量线程信息,可以转向 performance_schema.threads:
- 它不要求
PROCESS权限,只要用户有SELECT权限即可:GRANT SELECT ON performance_schema.threads TO 'monitor_user'@'%'; - 返回字段更全,含
THREAD_OS_ID、PROCESSLIST_INFO(未截断)、RESOURCE_GROUP_NAME等 - 注意:MySQL 5.7+ 默认启用;5.6 需确认配置文件中
performance_schema=ON - 过滤活跃连接示例:
SELECT THREAD_ID, PROCESSLIST_USER, PROCESSLIST_DB, PROCESSLIST_COMMAND, PROCESSLIST_TIME FROM performance_schema.threads WHERE PROCESSLIST_ID IS NOT NULL AND PROCESSLIST_TIME > 30;
容易忽略的权限冲突和兼容性细节
MySQL 8.0+ 引入了角色(roles)机制,如果你用 CREATE ROLE + GRANT ... TO role 方式管理权限,要注意:
-
PROCESS不能通过角色间接授予 —— 它必须直接GRANT给用户(官方文档明确标注为 non-role-grantable) - 使用
SHOW PROCESSLIST时,Info字段默认最多显示 100 字符,长 SQL 会被截断;而performance_schema.threads.PROCESSLIST_INFO在 8.0.14+ 支持完整显示(需确认版本) - 某些云厂商 RDS(如阿里云 PolarDB)会屏蔽
PROCESS权限,此时唯一可行路径就是performance_schema+ 显式SELECT授权











