查 mysql.user 表是最可靠方式,SELECT User, Host FROM mysql.user; 可查用户及允许连接的主机范围,Host 为 % 表示任意 IP,localhost 与 127.0.0.1 视为不同账户。

直接查 mysql.user 表是最可靠的方式
MySQL 的所有用户信息都固化在 mysql.user 系统表里,不依赖缓存或视图,查它就是查“事实”。其他命令(比如 SHOW USERS)根本不存在——这是新手常搜错的关键词。
-
SELECT User, Host FROM mysql.user;是最常用、最轻量的写法,返回用户名和允许连接的主机范围 - 注意
Host列值为%表示通配任意 IP,localhost和127.0.0.1在 MySQL 中是两个不同账户,权限不互通 - 如果想看更完整的账户状态(比如是否锁定、密码过期时间),用:
SELECT User, Host, account_locked, password_expired, password_last_changed FROM mysql.user;
show grants for 'user'@'host' 查权限时必须带完整 host
只写 SHOW GRANTS FOR 'admin'; 会报错,因为 MySQL 要求精确匹配 User@Host 元组。哪怕你刚用 CREATE USER 'admin'@'%' IDENTIFIED BY 'pwd'; 创建,也得按原样写全。
- 常见错误现象:
ERROR 1141 (42000): There is no such grant defined for user 'admin' on host '%'—— 很可能是因为实际创建的是'admin'@'localhost',但你查的是'admin'@'%' - 快速确认某用户是否存在且 host 匹配:先执行
SELECT User, Host FROM mysql.user WHERE User = 'admin'; - 权限语句输出里出现
GRANT USAGE ON *.*,说明该用户只有登录权,没授任何数据库级权限
别用 root 直接连生产库查用户,尤其别漏掉 --skip-grant-tables 风险
有些教程教人重启 mysqld 加 --skip-grant-tables 绕过权限检查来“恢复”用户,这在生产环境等于裸奔——此时任何本地用户都能无密码进库改数据。
- 真正安全的做法是:用已有高权限账号(如 root@localhost)登录后操作,且确保连接走 socket(非 TCP),避免网络暴露
- 如果 root 密码丢了,应通过系统级方式重置(如 systemctl stop mysqld → 启动时加
--init-file执行 SQL 修改密码),而不是跳过权限验证 - 执行完用户操作后,记得运行
FLUSH PRIVILEGES;—— 大多数情况不需要,但修改了mysql.user表直改后必须刷,否则新权限不生效
Linux 系统用户 ≠ MySQL 用户,别混查 /etc/passwd
看到有人 cat /etc/passwd | grep mysql 想找数据库用户,这是典型概念混淆。MySQL 用户是逻辑账户,存在自己的 mysql 数据库里;系统用户只是运行 mysqld 进程的操作系统身份。
-
/etc/passwd里的mysql用户只负责启动服务,跟CREATE USER 'app'@'%'...完全无关 - 如果你在排查“谁连上了数据库”,应该用
SHOW PROCESSLIST;(需有 PROCESS 权限),它显示的是当前活跃连接对应的 MySQL 用户,不是 Linux 用户名 - 权限模型上,MySQL 用户权限粒度细到库、表、列甚至行(通过存储过程模拟),而系统用户权限是进程级的,二者边界必须分清
Host 字段的语义:它不是“来源 IP”,而是客户端发起连接时声明的 host 名(或 DNS 解析结果),且受 skip_name_resolve 配置影响。没关这个选项时,反向 DNS 查询失败可能导致本该匹配 'user'@'192.168.%' 的连接被记成 'user'@'%' ,权限行为就变了。


















