12.6.3 쿼리 실행 시간 제한(Timeout) 및 리소스 고갈 방지
지금까지 다루었던 권한 제어와 정적 분석이 파괴자들의 ’악의적인 검’을 막는 것이었다면, 이번 절에서 다룰 방어선은 어리석은 모델이 순수하고 악의 없이 저지르는 가장 무서운 “바보 같은 짓“으로부터 시스템의 체력을 지켜내는 것이다. 그 주범은 관계 대수학 공간에서 폭하듯 나타나는 **카테시안 곱(Cartesian Product, 조인 누락)**의 재앙이다.
자연어를 쿼리로 바꾸는 MLOps 평가 파이프라인에서, AI 모델 에이전트가 2개 이상의 거대 팩트(Fact) 테이블이나 디멘전(Dimension) 테이블을 교차 결합(Join)하면서 가장 핵심인 매핑 조건 노드(ON 또는 WHERE)를 깜빡 빼먹는 실수를 저지르는 일은 비일비재하다. 이 순간, 데이터베이스 물리 엔진은 아무런 논리적 브레이크 없이 A 테이블의 1,000만 건과 B 테이블의 500만 건을 단순 교차 곱하기 시작하여, 순식간에 50조 건의 말도 안 되는 잉여 튜플 반환을 시도하는 거대한 무한 스파이럴(Infinite Spiral) 무저갱에 빠져버린다.
이는 즉시 해당 코어의 CPU 점유율을 100%로 영구 고착시키고 가용한 모든 시스템 가상 메모리 공간(RAM Buffer)을 진공청소기처럼 일거에 빨아들여 치명적인 OOM(Out-Of-Memory) 패닉을 일으킨다. 그리고 단 몇 초 후, 오라클을 구동하는 소중한 호스트(Host) 서버 전체가 핑(Ping) 래그에 걸려 먹통이 되며 강제 리부팅(Kernel Panic) 이라는 사형선고를 맞이하게 되는 것이다.
이러한 무자비한 하드웨어 자원 고갈 파업(Denial of Service, DoS) 현상을 원천 방어하기 위해, 오라클 기획자는 쿼리 실행 커넥터 단에서 반드시 ‘타임아웃(Timeout)’ 타이머와 ‘리소스 하드 리밋(Resource Hard Limit)’ 방어망을 입체적으로 교차 구축해야 한다.
1. 세션 커넥터 레벨의 절대적 타임아웃 트리거 (Query-level Timeout)
파이썬 인터프리터가 쿼리를 날릴 때 “기다림“의 통제 주도권을 데이터베이스 엔진 측의 리액션에 온전히 맡겨버리면, 그 즉시 스레드(Thread)는 죽지도 살지도 못하는 영원한 Blocked(I/O Wait) 대기 상태 늪에 빠지게 된다.
위대한 오라클 아키텍트는 샌드박스와 통신 커넥션 라인을 개통할 때부터 선제적으로 세션(Session) 단위의 생명 시한폭탄(Time Bomb)을 집어던져 통제해야 한다.
- 엔진 세션(Session) 통제: PostgreSQL의 경우 해당 AI의 쿼리를 물리적으로 실행하기 바로 전 줄에
SET statement_timeout = 3000;(절대 3초 한계선)이라는 강력한 타임 캡 환경 변수 명령을 패시브로 먹여버린다. - 스레드 예외 처리의 쾌감: 쿼리가 동작하여 커서가 디스크를 스캔하던 중 정확히 3초 한계가 넘어가는 그 찰나, 드라이버 파서가 트랜잭션을 내부적으로 강제 폭파시키고 어플리케이션 계층으로
psycopg2.errors.QueryCanceledError(또는 TimeoutError)를 가차 없이 던져 올린다. 시스템의 거대한 리소스는 바로 이 짧은 순간 영구 강제 해방(Release)을 맞이하게 되고, 해당 건은ERROR_TYPE: EXECUTION_TIMEOUT_EXCEEDED0점 로그를 남긴 채 평화를 누리게 된다.
2. Docker Cgroups 기반의 메모리 OOM 강제 캡핑(Capping) 절단 계층
하지만 불행하게도 순수 소프트웨어 레벨의 타임아웃 타이머만으로는, 3초라는 짧은 시간 내에 무려 수십 기가바이트의 커널 메모리와 버퍼 캐시를 폭력적으로 치솟게 잡아먹어버리는 미친듯한 메모리 폭주형 쿼리의 흉폭함을 100% 막아낼 수 없다.
따라서, 이 샌드박스로 가동되는 도커(Docker) 컨테이너 껍데기 그 자체에 리눅스 커널의 물리적인 하드웨어 한계선인 cgroups (Control Groups) 권한 제어 제한을 극단적으로 적용해야 한다.
오라클 도커 오케스트레이션(Docker Compose 등) 설정 단에서 docker run --memory="1g" --cpus="1.0" 와 같은 비정한 물리적 자원 상한선(Cap)을 컨테이너 생성 옵션에 강압 타격하여 파이프라인 엔진 환경을 조립한다.
이렇게 컨테이너를 가두는 마법을 벌여두면, 1GB의 임계점을 넘는 거대한 메모리 누수 조인 폭주가 일어날 때, 호스트 리눅스의 도커 데몬(Docker Daemon)이 즉각 무적의 OOM 킬러(OOM Killer, SIGKILL - 9)를 발동하여 악성 샌드박스의 호흡 파이프만을 정확하게 단절시켜버린다. 그 결과 샌드박스는 소멸할지언정 그 밖에서 점수를 기록하고 다른 벤치마크 루프를 돌리고 있는 가장 중요한 호스트 파이썬 메인 인터프리터 생태계는 완벽하게 숨을 쉬며 영원토록 생존할 수 있는 절대 무적의 방어 진지를 확보하게 되는 것이다.