DBAtlas · 数据库运维图谱

长时间运行的查询 / 作业

症状

某个查询/作业已运行数小时仍未结束;它消耗资源或影响其他操作。

1. 捕获查询及其运行时长

是哪个查询、已运行多久、哪个用户/应用?

Oracle

SELECT sid, serial#, sql_id, last_call_et/60 running_min, username FROM v$session WHERE status='ACTIVE' AND type='USER' ORDER BY last_call_et DESC;

PostgreSQL

SELECT pid, now()-query_start dur, usename, query FROM pg_stat_activity WHERE state='active' ORDER BY query_start;

MySQL

SELECT id, user, time, state, info FROM information_schema.processlist WHERE command='Query' ORDER BY time DESC;

SQL Server

SELECT session_id, total_elapsed_time/1000 sec, status, command FROM sys.dm_exec_requests WHERE session_id IN (SELECT session_id FROM sys.dm_exec_sessions WHERE is_user_process = 1) ORDER BY total_elapsed_time DESC;

MongoDB

db.currentOp({ active: true, secs_running: { $gt: 60 } })

2. 是在推进还是卡住了

它真的在运行,还是在等待锁?查看进度指标(Oracle v$session_longops、PG pg_stat_progress_* 视图)。若在等待,请转到“阻塞与锁危机”应急手册。

Oracle

SELECT sid, opname, sofar, totalwork, ROUND(sofar/NULLIF(totalwork,0)*100,1) pct, time_remaining FROM v$session_longops WHERE sofar<totalwork;

PostgreSQL

SELECT * FROM pg_stat_progress_create_index;  -- or pg_stat_progress_vacuum / _cluster / _analyze

3. 决定:等待还是取消

若正在推进且很快就会完成,就等待(取消带来的回滚代价可能使其耗时更长)。若已卡住、运行有误或影响生产,就终止它。取消前要考虑回滚时间。

4. 必要时终止

优先只取消查询(保留会话);若无效,再终止会话。

Oracle

ALTER SYSTEM CANCEL SQL 'sid,serial#';  -- 18c+; otherwise KILL SESSION

PostgreSQL

SELECT pg_cancel_backend(pid);  -- otherwise pg_terminate_backend(pid)

MySQL

KILL QUERY <id>;

SQL Server

KILL <session_id>;

MongoDB

db.killOp(<opid>)

5. 永久修复

优化查询(索引、计划、分页/分批),将繁重作业移到非高峰时段,必要时分块运行。对于周期性报表,考虑使用物化视图 / 只读副本。

在 DBAtlas 中打开 →