新用户默认无权限是mysql等数据库的强制安全策略,执行create user后仅能连接服务器,需显式授权才能执行select、show databases等操作,遵循最小权限原则。

新用户默认无权限是安全设计,不是bug
这是MySQL(以及PostgreSQL、Oracle等主流数据库)的强制安全策略:执行 CREATE USER 后,该用户仅能连接到服务器,连 SELECT 一个空表都会报错。这不是遗漏或配置错误,而是防止未授权访问的基本防线。
为什么连登录后执行 SHOW DATABASES 都被拒绝?
因为 SHOW DATABASES 权限默认不开放——它会暴露所有库名,属于敏感信息。新用户没有该权限时,执行该命令会得到:ERROR 1044 (42000): Access denied for user 'newuser'@'localhost' to database ''。
- 即使你只打算让这个用户查某个库,也必须显式授予
SELECT权限,例如:GRANT SELECT ON mydb.* TO 'newuser'@'localhost' -
GRANT ALL PRIVILEGES ON *.*是高危操作,生产环境应避免;最小权限原则要求只授所需权限 - 用户身份由
'username'@'host'全称唯一确定,'user'@'localhost'和'user'@'%'是两个完全不同的账号
FLUSH PRIVILEGES 到底要不要执行?
绝大多数情况下不需要手动执行 FLUSH PRIVILEGES —— 因为 GRANT 语句本身就会即时写入权限表并生效。只有在直接修改 mysql.user 等系统表后才需刷新。
- 误用
FLUSH PRIVILEGES不会报错,但可能掩盖真实问题(比如权限语句写错了却以为是没刷新) - 如果你刚执行完
GRANT还提示无权限,优先检查:SHOW GRANTS FOR 'newuser'@'localhost'返回结果是否匹配预期 - 注意:MySQL 8.0+ 的密码认证插件(如
caching_sha2_password)可能导致连接成功但权限不生效,此时需确认用户创建时指定的认证方式
常见权限漏点:localhost vs % 导致“能连不能用”
用户创建时用了 'user'@'localhost',但应用实际从 Docker 容器或远程机器连接,走的是 'user'@'%' 路径——而后者根本没被授权,自然报 Access denied。
- 测试连接时,用
mysql -u user -h 127.0.0.1 -p(TCP连接)而非mysql -u user -p(默认 Unix socket,等价于 localhost),可提前暴露 host 匹配问题 - 若需支持任意主机,授权必须明确写成
'user'@'%',且确保 MySQL 服务监听了非本地地址(检查bind-address配置) - 匿名用户(
''@'localhost')可能干扰匹配,可用SELECT User, Host FROM mysql.user;检查是否存在冲突条目
权限不是“开箱即用”的功能,而是逐层叠加的锁链。每一条 GRANT 都在加固一环,漏掉任何一环(比如忘了 USAGE 或 SELECT),就卡在那一层。最稳妥的做法是:先用 SHOW GRANTS 确认当前状态,再按需补授权,而不是反复试错。











