<p>SHOW GRANTS FOR CURRENT_USER() 是最准的起点,它返回当前连接实际生效的全局权限语句,如 GRANT SELECT, PROCESS ON . TO 'admin'@'%';CURRENT_USER() 与 USER() 可能不同,前者是权限系统匹配到的真实账号,后者仅为登录声明身份;查 mysql.user 表仅反映磁盘全局权限字段,不等同运行时生效权限,且需 FLUSH PRIVILEGES 才对新连接生效。</p>

SHOW GRANTS FOR CURRENT_USER() 是最准的起点
它返回当前连接实际生效的全局权限语句,比如 GRANT SELECT, PROCESS ON *.* TO 'admin'@'%'。这不是“理论上该有的权限”,而是 MySQL 运行时真正检查并执行的权限集合。注意:CURRENT_USER() 和 USER() 可能不同——前者是权限系统匹配到的账号(如 'admin'@'%'),后者只是你登录时声明的身份(如 'admin'@'192.168.10.5')。先执行 SELECT CURRENT_USER(); 确认目标,再查权限,否则容易看错人。
查 mysql.user 表只能看到全局权限字段,但不等于全部生效权限
直接 SELECT select_priv, process_priv, super_priv FROM mysql.user WHERE user = 'x' AND host = 'y'; 能看到 Y/N 值,但它只反映全局级别字段,且在 MySQL 8.0+ 中已不包含 EXECUTE、CREATE VIEW 等权限(这些移入数据字典)。更关键的是:即使这里显示 process_priv = 'Y',若没执行过 FLUSH PRIVILEGES,内存中仍可能沿用旧值,SHOW PROCESSLIST 就会失败。所以这张表只适合快速核对“磁盘写入状态”,不能替代运行时验证。
权限是否生效,取决于 FLUSH PRIVILEGES 是否执行过
MySQL 启动时把 mysql.user 等表加载进内存;后续手动 UPDATE mysql.user 或 INSERT 修改后,必须显式执行 FLUSH PRIVILEGES,新权限才会对**新建立的连接**生效。已有连接不受影响(它们用的是连接建立时加载的权限快照)。这意味着:
-
SELECT查mysql.user看到的是最新磁盘值,但SHOW GRANTS或实际操作可能还是旧行为 - 主从架构下,
FLUSH PRIVILEGES不复制,从库需单独执行 - 用
GRANT/REVOKE修改权限时,MySQL 会自动触发内存刷新,无需手动FLUSH
别被 USAGE 权限骗了
SHOW GRANTS 输出里出现 GRANT USAGE ON *.* TO 'u'@'h',说明这个账号在 mysql.user 表中所有全局权限字段都是 N,但它仍可能拥有库级或表级权限(比如 GRANT SELECT ON db1.* TO 'u'@'h')。此时 USAGE 不代表“完全没权限”,只是没有全局权限。要确认真实能力,得结合 mysql.db、mysql.tables_priv 等表查,或者直接试操作——比如连上去执行 USE db1; 和 SELECT 1;。


















