不支持。LOCK TABLES是全局权限,只能用REVOKE LOCK TABLES ON .撤销;无法按数据库粒度限制,因其语义本身跨库,且MySQL权限系统要求全局控制以防止绕过。

REVOKE LOCK TABLES 权限是否支持按数据库粒度?
不支持。LOCK TABLES 是全局权限(global privilege),MySQL 不允许对它使用 ON db_name.* 语法。哪怕你写成 REVOKE LOCK TABLES ON mydb.* FROM 'user'@'host',MySQL 会直接报错:ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES。
正确撤销 LOCK TABLES 权限的操作方式
必须用 ON *.* 显式指定全局作用域:
REVOKE LOCK TABLES ON *.* FROM 'user'@'host';
之后别忘了刷新权限:
FLUSH PRIVILEGES;
- 如果用户只被授予过
LOCK TABLES(无其他全局权限),这条命令执行后,该用户将彻底失去该权限 - 如果用户还拥有
ALL PRIVILEGES ON *.*这类通配授权,REVOKE无法部分收回——MySQL 不支持从通配权限中“剔除”某一项,此时必须先DROP USER或重新用GRANT精确赋权 - 注意:撤销操作对当前已加锁的会话无效,已有
LOCK TABLES仍保持有效,直到用户执行UNLOCK TABLES或连接断开
为什么不能限制到某个库?
因为 LOCK TABLES 的语义本身是会话级、跨库的——一条 LOCK TABLES t1 READ, otherdb.t2 WRITE 就能同时锁两个库的表。MySQL 权限系统设计上就要求它必须是全局控制项,否则会出现权限绕过(比如通过锁其他库的表间接影响目标库)。
若业务真需要“仅允许锁某库”,只能靠应用层拦截或代理层(如 ProxySQL)做 SQL 重写/拒绝,MySQL 原生不提供这种能力。
常见误操作与验证方法
执行完 REVOKE 后,建议立即验证权限是否生效:
- 用目标用户登录,执行
SHOW GRANTS FOR CURRENT_USER;,确认输出里不再含LOCK TABLES - 尝试执行
LOCK TABLES mydb.mytable READ;,应返回ERROR 1045 (28000): Access denied for user ... (using password: YES) - 注意:如果看到
Access denied for user ... using password: NO,说明用户认证失败,不是权限问题,别误判
真正容易被忽略的是:撤销权限后,旧连接不会自动失效;只要连接还活着,之前获得的锁和权限上下文依然存在。得等连接重建,新权限才起效。


















