alter user ... account lock 与 kill 组合是唯一能同时立即禁用认证和实时释放资源的操作;前者仅阻止新连接,后者终止活跃会话,二者缺一不可。

直接用 ALTER USER ... ACCOUNT LOCK 冻结账号,再配合 KILL 终止其当前连接——这是唯一能同时做到“立即禁用认证”和“实时释放资源”的组合操作。
为什么 ACCOUNT LOCK 不能替代 KILL
ACCOUNT LOCK 只阻止新连接建立,对已存在的活跃会话完全无影响。那些卡在 Connect、Query 或 Sleep 状态的连接仍可继续执行语句、读写数据,甚至发起事务回滚。你看到错误日志里反复出现 ERROR 3118 (HY000): Account is locked,说明新连接被拦住了,但老连接还在跑。
- 锁定后仍能看到该用户出现在
information_schema.PROCESSLIST中,Time列可能持续增长 - 若该用户正执行大事务(如全表 UPDATE),不
KILL就无法释放锁和缓冲池内存 - 某些中间件(如 ProxySQL)会重试连接,导致大量
Connect状态堆积,进一步挤占连接数
先查再杀:定位异常账号的活跃连接
别凭用户名瞎猜,用 PROCESSLIST 精准过滤。重点看 User、Host、State 和 Time 四列:
- 查指定用户所有连接:
SELECT id, user, host, db, command, time, state FROM information_schema.PROCESSLIST WHERE user = 'suspect_user' AND host LIKE '192.168.1.%'; - 找长时间卡在
Connect的暴力尝试痕迹:SELECT * FROM information_schema.PROCESSLIST WHERE user = 'suspect_user' AND command = 'Connect' AND time > 10; - 排除误伤:跳过
State = 'Killed'的连接(它们正在退出,无需重复KILL)
批量生成并安全执行 KILL 语句
手动 KILL 12345 容易漏、易手抖。用查询自动生成语句更可靠,但必须加条件过滤,避免误杀系统线程或主从复制线程:
- 生成目标用户的
KILL语句:SELECT CONCAT('KILL ', id, ';') FROM information_schema.PROCESSLIST WHERE user = 'suspect_user' AND id > 0 AND command != 'Sleep' AND time > 5; - 执行前先复制结果到文本编辑器,人工检查一遍 ID 是否合理(比如排除
id 的后台线程) - 确认无误后,在 MySQL 客户端中粘贴执行;不要用脚本自动执行
KILL,防止网络中断导致部分语句未生效 - 执行完立刻再查一次
PROCESSLIST,确保该用户连接数归零
锁定账号本身要带精确 host,否则报错
ALTER USER 要求用户名和主机名必须与 mysql.user 表中存储的记录完全一致。用模糊匹配(如 @'%')去锁一个实际是 @'192.168.1.100' 的账户,会直接报 ERROR 1396 (HY000): Operation ALTER USER failed for 'suspect_user'@'%'。
- 先查真实 host:
SELECT User, Host FROM mysql.user WHERE User = 'suspect_user'; - 再执行锁定:
ALTER USER 'suspect_user'@'192.168.1.100' ACCOUNT LOCK; - 如果用户有多个 host 记录(如
@'192.168.1.%'和@'localhost'),必须分别执行锁定 - MySQL 5.7.6+ 才支持
ACCOUNT LOCK,低于此版本只能走REVOKE ALL PRIVILEGES+GRANT USAGE路线
真正容易被忽略的是:锁定和 KILL 是两个独立动作,缺一不可。只锁不杀,连接还在耗资源;只杀不锁,几分钟后攻击者换个连接又来了。生产环境里,这两步必须在 30 秒内完成闭环。











