MySQL的GRANT是权限叠加操作,不覆盖旧权限也不清除未声明权限;必须明确指定库表、用户及主机作用域,如'db.tbl'和'user'@'host';权限变更后仅新连接生效,需用SELECT CURRENT_USER()确认匹配账号。

MySQL 的 GRANT 命令不是“授权开关”,而是权限叠加操作——重复执行不会报错,但也不会自动覆盖旧权限,更不会清除未显式声明的权限。
grant 语句必须指定明确的作用域和权限类型
权限不是全局生效的,GRANT 必须写清「对哪个库/表」「由哪个用户」「从哪个主机连接」。漏掉任意一环,权限就加不到目标账户上。
- 作用域格式是
database.table,用*表示全部数据库,*.*才表示所有库所有表 - 用户格式是
'username'@'host',比如'appuser'@'10.20.30.%'和'appuser'@'localhost'是两个完全独立的账号 - 不加
WITH GRANT OPTION,该用户就无法把权限再授给其他人
常见错误:执行 grant 后权限不生效
最常被忽略的是忘记 FLUSH PRIVILEGES —— 但其实它通常不需要手动执行。MySQL 5.7+ 在多数情况下会自动重载权限表;只有当你直接修改了 mysql.user 等系统表后才需要它。
- 真正导致权限不生效的高频原因:用户连接时用的 host 不匹配(比如你授的是
'user'@'192.168.1.%',但客户端连的是localhost,而 MySQL 把localhost当作 socket 连接,走的是'user'@'localhost'这条记录) - 检查当前登录用户实际匹配哪条权限记录:执行
SELECT USER(), CURRENT_USER();,前者是“你声称是谁”,后者是“MySQL 认为你是谁” - 权限变更后,已存在的连接不会立即失效,新连接才会应用新权限
只授必要权限,避免用 ALL PRIVILEGES
ALL PRIVILEGES 包含 FILE、SHUTDOWN、GRANT OPTION 等高危权限,生产环境应严格限制。
- 应用账号通常只需
SELECT, INSERT, UPDATE, DELETE,读写分离场景下甚至只给SELECT - 管理类账号如需建库建表,加上
CREATE, DROP, INDEX, ALTER即可,不必开CREATE USER或RELOAD - 如果误授了
GRANT OPTION,该用户就能给自己或他人加权限,相当于绕过 DBA 控制
权限粒度越细,后期排查越容易。别图省事用 GRANT ALL ON *.* TO ...,一旦出问题,连是哪个库被删的都得翻日志查。










