在数据库日常运维中,执行drop user命令时遇到操作hang住的情况并不少见,这类问题通常和数据库内部的会话状态、锁资源占用、事务未提交等因素相关,需要按照规范的步骤逐步排查定位根因。

一、常见触发原因
drop user操作hang住的核心原因通常是目标用户存在活跃会话、相关对象被其他事务占用锁资源,或者存在未提交的长事务关联了目标用户的对象,常见场景如下:
- 目标用户当前仍有活跃的数据库连接未断开,数据库需要等待这些会话结束才能执行删除操作
- 有其他会话持有了目标用户下对象的锁资源,且未释放,导致drop操作无法获取对应的锁
- 存在未提交的事务关联了目标用户的表、视图等对象,事务未结束前相关对象无法被删除
- 数据库开启了审计或者相关依赖检查机制,检查过程耗时过长导致操作看起来hang住
二、排查步骤
1. 查看当前会话状态
首先可以查询数据库当前的会话信息,确认目标用户是否还有活跃会话,以MySQL为例,查询语句如下:
-- 查询目标用户的所有活跃会话
SELECT
id,
user,
host,
db,
command,
time,
state,
info
FROM information_schema.processlist
WHERE user = '待删除的用户名'
AND command != 'Sleep';如果存在活跃会话,记录对应的会话id,后续可以根据情况选择断开这些会话。
2. 定位锁资源阻塞
如果不存在活跃会话,需要排查是否存在锁阻塞,以MySQL为例,查询当前锁等待情况的语句如下:
-- 查询当前锁等待信息
SELECT
r.trx_id AS waiting_trx_id,
r.trx_mysql_thread_id AS waiting_thread,
r.trx_query AS waiting_query,
b.trx_id AS blocking_trx_id,
b.trx_mysql_thread_id AS blocking_thread,
b.trx_query AS blocking_query
FROM information_schema.innodb_lock_waits w
INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id
INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;通过结果可以找到阻塞drop操作的源会话,记录对应的blocking_thread值。
3. 检查未提交事务
还可以查询是否存在未提交的长事务,避免事务占用资源导致操作无法推进:
-- 查询运行时间超过60秒的未提交事务
SELECT
trx_id,
trx_state,
trx_started,
trx_mysql_thread_id,
trx_query
FROM information_schema.innodb_trx
WHERE trx_started < NOW() - INTERVAL 60 SECOND;三、解决方案
1. 断开目标用户活跃会话
如果排查到目标用户存在活跃会话,可以使用KILL命令断开对应会话,示例如下:
-- 断开指定会话,替换为实际的会话id KILL 会话id;
断开所有目标用户的活跃会话后,再次尝试执行drop user操作。
2. 终止阻塞源会话
如果排查到是其他会话阻塞了drop操作,需要评估阻塞会话的业务影响,确认无影响后可以终止该会话:
-- 终止阻塞会话,替换为实际的阻塞会话id KILL 阻塞会话id;
3. 提交或回滚长事务
如果存在未提交的长事务,联系业务方确认后,提交或者回滚对应事务:
-- 提交事务,需要在对应事务的会话中执行 COMMIT; -- 或者回滚事务 ROLLBACK;
4. 强制删除(谨慎使用)
如果上述方法都无法解决,且确认操作安全,可以在数据库允许的情况下使用强制删除参数,以MySQL为例:
-- 强制删除用户,会断开该用户的所有连接 DROP USER IF EXISTS '待删除的用户名'@'主机范围' FORCE;
注意强制删除操作需要先确认不会影响正在运行的业务,避免数据异常。
四、预防建议
为了避免后续再次出现drop user hang住的问题,可以在执行删除操作前先做好前置检查:
- 删除前先查询目标用户是否存在活跃会话,提前通知业务方断开连接
- 删除前检查是否存在关联目标用户对象的未提交事务,提前处理
- 对于核心业务用户,删除前先在测试环境验证删除流程,确认无异常后再操作生产环境