AWS RDS CPU 100% 폭주 완벽 해결: 슬로우 쿼리(Slow Query) 최적화 아키텍처

[Troubleshooting] AWS RDS CPU 100% 폭주 완벽 해결: 슬로우 쿼리 아키텍처

"마케팅 팀에서 앱 푸시 알람을 쏘자마자 AWS RDS(데이터베이스)의 CPU 사용률이 100%를 찍으며 빨간불이 들어왔고, 서버 전체가 타임아웃에 빠지며 장렬하게 전사했습니다."

서비스가 스케일업(Scale-up)하는 과정에서 백엔드 엔지니어들이 겪는 가장 끔찍한 인프라 붕괴 현상입니다. 코드는 그대로인데 데이터가 수십만 건으로 누적되면서 서서히 발생한 시한폭탄이 터진 것입니다.

초보자들은 당황하여 RDS 인스턴스의 클래스를 t3.medium에서 t3.xlarge로 사양만 올리며 엄청난 과금 폭탄을 감수합니다. 하지만 밑 빠진 독에 물을 부어도 CPU는 며칠 뒤 또다시 100%를 칠 것입니다. 본 가이드에서는 디스크 I/O를 혹사시키는 데이터베이스 엔진의 비효율을 해체하고, 슬로우 쿼리(Slow Query) 분석을 통해 병목을 원천 절단하는 엔터프라이즈 튜닝 아키텍처를 단호하게 제시합니다.

📌 이 글의 핵심 포인트

  • 병목의 본질: CPU를 혹사시키는 주범은 쿼리 양이 아니라 인덱스(Index) 없이 100만 건을 뒤지는 풀 테이블 스캔(Full Table Scan)
  • AWS 파라미터 그룹: RDS에서 3초 이상 걸리는 악성 쿼리를 낚아채는 슬로우 쿼리 로그(Slow Query Log) 활성화 기법
  • EXPLAIN 실행 계획: 추출된 쿼리를 분석하여 최적의 인덱스를 설계하는 무결점 데이터베이스 튜닝

1단계: 핵심 원인 분석 - 무식한 스캔(Full Table Scan)의 비극

CPU가 100%를 치는 이유는 단순합니다. 사용자가 "2026년에 가입한 남성 유저 찾아줘"라고 쿼리를 날렸을 때, 데이터베이스에 색인(Index) 탭이 없다면 DB 엔진은 100만 명의 유저 데이터를 1번부터 100만 번까지 일일이 열어보고 뒤지느라 CPU와 디스크 자원을 극한으로 소모합니다.

트래픽이 적을 때는 이 무식한 방법(Full Table Scan)도 티가 나지 않지만, 트래픽이 몰리면 디스크를 뒤지는 작업이 병목이 되어 전체 DB가 마비되는 것입니다.

2단계: 완벽한 트러블슈팅 1 - RDS 슬로우 쿼리 로그 활성화

범인을 잡으려면 블랙박스를 켜야 합니다. AWS RDS 콘솔에서 [파라미터 그룹(Parameter Group)]을 열고 아래 3가지 옵션을 수정하여 지연 쿼리 추적망을 가동하십시오.


-- 1. 슬로우 쿼리 로그 활성화
slow_query_log = 1

-- 2. 몇 초 이상 걸린 쿼리를 기록할 것인가? (보통 2~3초로 세팅)
long_query_time = 2

-- 3. 로그를 파일로 쌓도록 설정 (CloudWatch로 내보내기 위함)
log_output = FILE

이 설정을 완료하고 RDS 인스턴스를 재부팅(또는 동적 적용)하면, 2초 이상 걸리는 무거운 쿼리들이 AWS CloudWatch Logs에 slowquery라는 이름으로 고스란히 기록되기 시작합니다.

3단계: 완벽한 트러블슈팅 2 - EXPLAIN 튜닝 및 인덱스(Index) 부착

CloudWatch에서 범인 쿼리(예: SELECT * FROM users WHERE status='ACTIVE' ORDER BY created_at DESC;)를 찾아냈다면, 데이터베이스 터미널(DataGrip 등)에 접속하여 쿼리 앞에 EXPLAIN이라는 마법의 단어를 붙여서 실행해 봅니다.


-- ❌ EXPLAIN 결과: type 항목이 'ALL' (100만 건을 다 뒤졌다는 최악의 뜻)
EXPLAIN SELECT * FROM users WHERE status='ACTIVE' ORDER BY created_at DESC;

-- ✅ 완벽한 해결책: 쿼리 조건에 맞는 복합 인덱스(Index) 생성
CREATE INDEX idx_status_created ON users (status, created_at);

-- 복합 인덱스 생성 후 EXPLAIN 결과: type 항목이 'ref'로 변경됨 
-- 이제 DB는 100만 건을 뒤지지 않고 인덱스 목차만 보고 0.01초 만에 결과를 가져옴

인덱스를 씌우고 나면, CPU 100%를 찍으며 비명을 지르던 RDS가 마치 마법처럼 5% 미만의 쾌적한 상태로 뚝 떨어지는 기적을 목격하게 될 것입니다.

🙋‍♂️ 자주 묻는 질문 (FAQ)

Q. 모든 컬럼에 다 인덱스를 걸어두면 무조건 빠른 거 아닌가요?
A. 절대 아닙니다! 인덱스도 결국 하드디스크의 공간을 차지하는 '또 다른 책'입니다. 인덱스를 무작정 많이 만들면, 새로운 데이터가 추가(INSERT/UPDATE)될 때마다 인덱스 책을 다시 정렬해야 하므로 쓰기 속도가 끔찍하게 느려집니다. 반드시 병목을 일으키는 SELECT 조건에만 정밀하게 인덱스를 부여해야 합니다.

💡 핵심 정리 및 마무리

클라우드 컴퓨팅 시대에도 데이터베이스의 인덱스 설계라는 고전적인 엔지니어링의 본질은 변하지 않습니다. 인스턴스 사양에 돈을 쏟아붓는 무책임한 해결책을 버리십시오. 슬로우 쿼리 블랙박스를 켜고 데이터를 추출해내는 SQL의 내부 메커니즘(Execution Plan)을 통제할 때, 당신은 비로소 인프라와 비용을 모두 지배하는 진정한 아키텍트로 성장할 수 있습니다.

댓글

이 블로그의 인기 게시물

Zapier & Make.com 자동화의 덫: 무한 루프(Infinite Loop) 에러 완벽 방어 아키텍처

엑셀 보고서의 종말: 구글 스프레드시트와 루커 스튜디오(Looker Studio)로 실시간 대시보드 구축하기

Docker OOMKilled (Exit Code 137) 에러의 진실: 컨테이너 메모 누수 방어 및 리소스 최적화 아키텍처