select user() 返回当前连接的客户端身份('user'@'host'),不反映权限上下文或角色切换;需用户名部分可用 substring_index(user(), '@', 1);与 current_user() 语义不同,后者体现 mysql 实际执行身份。

怎么用 SELECT USER() 查当前连接用户
SELECT USER() 返回的是「客户端连接时声明的身份」,格式通常是 'user'@'host'。它不反映权限上下文,也不等同于实际生效的权限主体——比如你用 root 登录但通过 SET ROLE 切换角色,USER() 依然显示原始登录名。
- 直接执行
SELECT USER();就能拿到当前会话的连接用户字符串 - 如果只想要用户名部分(不含
@host),可以用SUBSTRING_INDEX(USER(), '@', 1) - 注意:该函数在存储过程、函数或触发器中行为一致,但无法在视图定义里直接依赖它做动态权限过滤
USER() 和 CURRENT_USER() 的区别在哪
这是最容易混淆的点。USER() 看「你是谁连进来的」,CURRENT_USER() 看「MySQL 认为你现在以谁的身份执行」。后者受代理用户(proxy user)、SET ROLE、GRANT … AS 子句影响。
- 常见错误现象:明明用
app_user连接,CURRENT_USER()却返回'admin'@'%'—— 很可能配置了代理用户映射 - 使用场景:审计日志里记录操作者,应优先用
CURRENT_USER();排查连接来源 IP,则看USER()的 host 部分 - 性能上无差异,但语义完全不同,混用会导致权限逻辑误判
连接池环境下 USER() 返回值还可靠吗
在使用 mysql-connector-python、go-sql-driver/mysql 或 HikariCP 等连接池时,USER() 仍准确反映该物理连接的认证身份,但它**不代表发起 SQL 的应用线程身份**。
- 典型坑:多个微服务共享一个数据库账号,靠
USER()区分调用方——这不可行,因为连接池会复用连接,且中间件可能统一配置连接参数 - 正确做法:在业务 SQL 中显式传入调用方标识(如
SET @app_id = 'order-service'),再结合SELECT @app_id辅助追踪 - 兼容性提示:MySQL 5.7+ 支持
information_schema.PROCESSLIST查实时连接,但需PROCESS权限,生产环境通常禁用
想查所有活跃连接的用户信息,该查哪张表
别依赖 USER() 函数,它只对当前会话有效。要看全局连接情况,得查 performance_schema.threads 或 information_schema.PROCESSLIST(旧版兼容)。
-
SELECT USER, HOST, COMMAND, TIME FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep';是最常用的一句 - MySQL 8.0+ 推荐用
performance_schema.threads,字段更全(如PROCESSLIST_USER,PROCESSLIST_HOST),且支持按资源消耗过滤 - 注意权限:普通用户默认看不到其他人的连接,需授予
PROCESS权限才能查全量 - 避免在高并发下频繁轮询
PROCESSLIST,它会触发全表扫描,可能拖慢 performance_schema











