ALTER USER ... ACCOUNT LOCK 是最直接安全的下线方式,立即拦截新连接并报错 ERROR 3118,不进入权限校验,原子生效、开销低;但需确认 MySQL 版本≥5.7.6、主机名准确,并同步处理硬编码、连接池及活跃会话。

用 ALTER USER ... ACCOUNT LOCK 立即阻断新连接
这是最直接、最安全的下线方式。执行后,任何新连接尝试都会在认证阶段被拦截,立刻报错 ERROR 3118 (HY000): Access denied [] Account is locked,不进入权限校验流程,响应快、行为确定。
它不是删除账号,也不改密码,所以不会触发应用层自动重连或轮询恢复;也不会影响其他账号或库表结构。但要注意:ACCOUNT LOCK 是 MySQL 5.7.6+ 原生支持的功能,低版本不识别该语法,会报错 ERROR 1064。
常见错误现象:在 MySQL 5.6 或更早版本执行该语句失败;或者主机名写错(比如把 'zhangsan'@'192.168.10.%' 写成 'zhangsan'@'%'),导致锁错对象。
冻结前必须确认三件事:硬编码、连接池、活跃会话
账号下线不是“执行一条 SQL 就完事”。真正引发故障的,往往不是数据库本身,而是外部依赖:
- 查硬编码:在应用服务器上运行
grep -r 'zhangsan' /opt/app/conf/ /etc/systemd/system/ 2>/dev/null,重点看application.yml、datasource.properties、*.service文件 - 查连接池残留:已建立但空闲的连接(如 HikariCP 的 idle 连接)不会被主动断开,仍保留在连接池中,可能在后续请求中被复用——这些连接能执行语句直到超时或被应用主动关闭
- 查当前活跃会话:运行
SELECT * FROM performance_schema.threads WHERE PROCESSLIST_USER = 'zhangsan';(需确保performance_schema已启用),确认没有正在跑的长事务或定时任务
GRANT/REVOKE 不适合“下线”,只适合“降权”
用 REVOKE SELECT ON sales.* FROM 'zhangsan'@'192.168.10.%'; 这类操作,只是回收权限,账号本身仍可登录,且只要还有任意一条未被收回的权限(比如 USAGE),就能成功建连——这完全达不到“下线”目的。
它适合的场景是权限收敛(例如从 ALL PRIVILEGES 收到只读),而不是人员退出。而且 REVOKE 后若没执行 FLUSH PRIVILEGES(MySQL 8.0.16+ 可省略),变更可能延迟生效;而 ACCOUNT LOCK 是原子操作,无需刷新即刻生效。
MySQL 数据库管理技能,能够通过自然语言查询和管理数据库,支持 SELECT/INSERT/UPDATE/DELETE、表管理、备份恢复等操作。当用户提及 MySQL、数据库查询、建表或数据备份时使用此技能。
性能影响方面:REVOKE 需更新 mysql.tables_priv 等授权表并重载内存权限缓存;ACCOUNT LOCK 只改 mysql.user.account_locked 字段(MySQL 8.0)或内部状态位(5.7),开销更低。
后续动作不能漏:台账同步 + 定期审计
执行 ALTER USER 'zhangsan'@'192.168.10.%' ACCOUNT LOCK; 后,必须同步更新你的账号管理台账,标注冻结时间、操作人、关联应用和冻结原因。
最容易被忽略的是:没人去查这个账号是否还出现在备份脚本、ETL 调度、监控探针或 DBA 自动化巡检工具里。这些地方一旦残留,可能在某次例行执行中意外触发连接失败告警,甚至因重试逻辑拖垮中间件。
建议每月用 SELECT user, host, account_locked FROM mysql.user WHERE account_locked = 'Y';(MySQL 8.0)或结合注释字段人工核对(5.7),做一次账号状态盘点。










