如何通过Grant语法精确限制MySQL普通用户的删除权限?

2026-04-27 21:302阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计885个文字,预计阅读时间需要4分钟。

如何通过Grant语法精确限制MySQL普通用户的删除权限?

普通用户不应该拥有《DELETE` 权限,这是数据库安全的基石。直接使用《GRANT ALL PRIVILEGES ON *.*》授予新用户权限,等同于将删除数据库的钥匙递给对方——那他可能只是一个只会读取报表的用户。

明确禁止 DELETE 时,别用 ALL PRIVILEGES

很多人图省事写 GRANT ALL PRIVILEGES ON testdb.* TO 'reporter'@'%',结果发现这个用户能删表、删行、删整个库。ALL 是真·全权委托,包含 DELETEDROPALTER 等高危权限。

正确做法是显式列出需要的权限:

  • SELECT 必须保留(否则查不了数据)
  • INSERTUPDATE 按业务需要决定是否开放
  • 绝对不写 DELETE,也不写 ALL
  • 如果只需要查,就只给 SELECT;如果还要导出或临时写中间表,再加 CREATE TEMPORARY TABLES(注意这不是 CREATE

grant 语句里漏掉 flush privileges 不会立即生效

MySQL 的权限不是实时加载的,它把权限缓存在内存里。你执行完 GRANT SELECT, INSERT ON testdb.* TO 'reporter'@'%' 后,该用户可能仍连不上、或权限没变——因为缓存没刷新。

必须手动执行:

FLUSH PRIVILEGES;

常见误区:

  • 以为重启 MySQL 才生效(没必要,且影响服务)
  • 在非 root 用户下执行 FLUSH PRIVILEGES 报错(需 RELOAD 权限,一般只有管理员有)
  • 忘记这步,反复测试权限失败,最后怀疑语法写错

回收已有用户的 DELETE 权限要用 REVOKE,不是 GRANT

如果用户已经拥有 DELETE 权限,不能靠“重新 GRANT 一遍不含 DELETE 的权限”来覆盖——MySQL 不会自动撤销旧权限,只会叠加新增的。

必须用 REVOKE 显式收回:

REVOKE DELETE ON testdb.* FROM 'reporter'@'%';<br>FLUSH PRIVILEGES;

注意点:

  • REVOKE 只能撤回之前 GRANT 过的权限,不能撤回未授过的权限(不会报错,但无效)
  • 如果当初是用 GRANT ALL 给的,REVOKE DELETE 有效;但如果想彻底清空,得 REVOKE ALL PRIVILEGES + GRANT 新权限组合
  • 撤回后务必 FLUSH PRIVILEGES,否则用户仍可继续删数据

host 部分写 '%' 和 'localhost' 是两个完全不同的账户

MySQL 认证时用的是 'username'@'host' 全匹配。这意味着:

  • 'reporter'@'%''reporter'@'localhost' 是两个独立账户,权限互不影响
  • 你在远程机器上连的是 'reporter'@'%',但在本机用 mysql -u reporter 默认走 localhost,可能权限完全不同
  • 检查权限时,一定要用 SHOW GRANTS FOR 'reporter'@'%',而不是 SHOW GRANTS(后者只显示当前登录用户的权限)

最容易被忽略的是:开发测试时本地连 localhost 没问题,上线后应用连 % 却报错——其实根本就是两套权限配置,压根没给过远程账户 SELECT

标签:Mysql

本文共计885个文字,预计阅读时间需要4分钟。

如何通过Grant语法精确限制MySQL普通用户的删除权限?

普通用户不应该拥有《DELETE` 权限,这是数据库安全的基石。直接使用《GRANT ALL PRIVILEGES ON *.*》授予新用户权限,等同于将删除数据库的钥匙递给对方——那他可能只是一个只会读取报表的用户。

明确禁止 DELETE 时,别用 ALL PRIVILEGES

很多人图省事写 GRANT ALL PRIVILEGES ON testdb.* TO 'reporter'@'%',结果发现这个用户能删表、删行、删整个库。ALL 是真·全权委托,包含 DELETEDROPALTER 等高危权限。

正确做法是显式列出需要的权限:

  • SELECT 必须保留(否则查不了数据)
  • INSERTUPDATE 按业务需要决定是否开放
  • 绝对不写 DELETE,也不写 ALL
  • 如果只需要查,就只给 SELECT;如果还要导出或临时写中间表,再加 CREATE TEMPORARY TABLES(注意这不是 CREATE

grant 语句里漏掉 flush privileges 不会立即生效

MySQL 的权限不是实时加载的,它把权限缓存在内存里。你执行完 GRANT SELECT, INSERT ON testdb.* TO 'reporter'@'%' 后,该用户可能仍连不上、或权限没变——因为缓存没刷新。

必须手动执行:

FLUSH PRIVILEGES;

常见误区:

  • 以为重启 MySQL 才生效(没必要,且影响服务)
  • 在非 root 用户下执行 FLUSH PRIVILEGES 报错(需 RELOAD 权限,一般只有管理员有)
  • 忘记这步,反复测试权限失败,最后怀疑语法写错

回收已有用户的 DELETE 权限要用 REVOKE,不是 GRANT

如果用户已经拥有 DELETE 权限,不能靠“重新 GRANT 一遍不含 DELETE 的权限”来覆盖——MySQL 不会自动撤销旧权限,只会叠加新增的。

必须用 REVOKE 显式收回:

REVOKE DELETE ON testdb.* FROM 'reporter'@'%';<br>FLUSH PRIVILEGES;

注意点:

  • REVOKE 只能撤回之前 GRANT 过的权限,不能撤回未授过的权限(不会报错,但无效)
  • 如果当初是用 GRANT ALL 给的,REVOKE DELETE 有效;但如果想彻底清空,得 REVOKE ALL PRIVILEGES + GRANT 新权限组合
  • 撤回后务必 FLUSH PRIVILEGES,否则用户仍可继续删数据

host 部分写 '%' 和 'localhost' 是两个完全不同的账户

MySQL 认证时用的是 'username'@'host' 全匹配。这意味着:

  • 'reporter'@'%''reporter'@'localhost' 是两个独立账户,权限互不影响
  • 你在远程机器上连的是 'reporter'@'%',但在本机用 mysql -u reporter 默认走 localhost,可能权限完全不同
  • 检查权限时,一定要用 SHOW GRANTS FOR 'reporter'@'%',而不是 SHOW GRANTS(后者只显示当前登录用户的权限)

最容易被忽略的是:开发测试时本地连 localhost 没问题,上线后应用连 % 却报错——其实根本就是两套权限配置,压根没给过远程账户 SELECT

标签:Mysql