MySQL创建用户必须指定host,如'appuser'@'%';GRANT在5.7.6+无需FLUSH PRIVILEGES;8.0默认caching_sha2_password兼容性差,应显式指定mysql_native_password插件。

创建 MySQL 用户时必须指定 host,否则可能无法登录
MySQL 的用户由 username@host 共同构成,不是只设用户名就行。比如 'appuser'@'localhost' 和 'appuser'@'%' 是两个完全不同的账号。
常见错误是执行 CREATE USER 'appuser' IDENTIFIED BY 'pwd123';,这等价于 'appuser'@'localhost',结果应用从远程连就报 Access denied for user 'appuser'@'xxx.xxx.xxx.xxx'。
实操建议:
- 明确连接来源:本地开发用
'appuser'@'localhost',应用服务器用'appuser'@'192.168.1.100'或'appuser'@'%'(后者慎用) - 创建时显式写全:
CREATE USER 'appuser'@'%' IDENTIFIED BY 'pwd123'; - 若已误建,用
DROP USER 'appuser'@'localhost';清理后再重来
GRANT 之后必须执行 FLUSH PRIVILEGES 吗?
不需要。在 MySQL 5.7.6+(含 8.0),GRANT 语句本身会自动刷新权限表;只有直接操作 mysql.user 等系统表后才需手动 FLUSH PRIVILEGES;。
但要注意:
- 如果用
INSERT INTO mysql.user插入用户或改权限,不FLUSH就不会生效 - MySQL 8.0 起推荐用
CREATE USER + GRANT组合,避免直改系统表 - 执行
GRANT后可立刻用新用户测试连接,无需等待或重启
分配权限时别乱给 ALL PRIVILEGES,按最小权限原则配
ALL PRIVILEGES 包含 DROP DATABASE、SHUTDOWN、GRANT OPTION 等高危权限,生产环境绝不能随便授予应用账号。
典型安全做法:
- 只读应用:用
GRANT SELECT ON mydb.* TO 'appuser'@'%'; - 读写应用:加
INSERT, UPDATE, DELETE,如GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.orders TO 'appuser'@'%'; - 避免跨库:不要用
mydb.*如果只用到其中一两张表;更细粒度可到列级(如SELECT(id,name) ON mydb.users) - 禁止授
GRANT OPTION,否则该用户能再给别人授权
MySQL 8.0 的默认认证插件 change 导致旧客户端连不上
MySQL 8.0 默认用 caching_sha2_password 插件,而老版本 MySQL 客户端或某些 ORM(如旧版 pymysql)不支持,会报 Authentication plugin 'caching_sha2_password' cannot be loaded。
解决方法分两种:
- 创建用户时指定旧插件:
CREATE USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd123'; - 或修改已有用户:
ALTER USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd123'; - 注意:改完不用
FLUSH PRIVILEGES,但客户端需重连才生效










