장시간 실행 쿼리 / 작업
증상
하나의 쿼리/작업이 몇 시간째 끝나지 않고 실행 중이며, 리소스를 소비하거나 다른 작업에 영향을 준다.
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 / _analyze3. 결정: 대기 또는 취소
진행 중이고 곧 끝난다면 기다린다(취소 시 롤백 비용으로 더 오래 걸릴 수 있음). 멈췄거나 잘못 실행 중이거나 운영에 영향을 준다면 종료한다. 취소 전에 롤백 시간을 고려한다.
4. 필요하면 종료한다
쿼리만 취소하는 것(세션 유지)을 우선한다. 효과가 없으면 세션을 종료한다.
Oracle
ALTER SYSTEM CANCEL SQL 'sid,serial#'; -- 18c+; otherwise KILL SESSIONPostgreSQL
SELECT pg_cancel_backend(pid); -- otherwise pg_terminate_backend(pid)MySQL
KILL QUERY <id>;SQL Server
KILL <session_id>;MongoDB
db.killOp(<opid>)5. 영구적으로 해결한다
쿼리를 최적화하고(인덱스, 계획, 페이지네이션/배치 처리), 무거운 작업은 비피크 시간대로 옮기며, 필요하면 나누어 실행한다. 반복되는 보고서에는 materialized view / read replica를 고려한다.