운영 서버 CPU 사용률 최적화 - PostgreSQL 인덱스 추가로 해결하기

Olivia·5일 전
0

[Trouble Shooting👾]

목록 보기
7/7

문제 상황

운영 중인 서비스에서 데이터 센터로부터 CPU 사용량이 MAX를 기록했다는 알림 메일을 받았다. 처음에는 특정 시간대에만 발생하는 문제라면 크론잡(cron job) 관련 이슈일 가능성을 생각했지만, 실제로는 불특정 시간에 지속적으로 발생하는 문제였다.

문제 원인 분석

CPU 사용률이 급증하는 원인을 파악하기 위해 데이터베이스 성능부터 점검해보기로 했다. PostgreSQL에서 테이블별 스캔 통계를 확인할 수 있는 쿼리를 실행했다.

SELECT schemaname, relname, seq_scan, seq_tup_read, idx_scan
FROM pg_stat_user_tables
ORDER BY seq_tup_read DESC;

이 쿼리를 통해 각 테이블의 아래 목록을 확인할 수 있었다:

  • seq_scan: Sequential Scan(전체 테이블 스캔) 횟수
  • seq_tup_read: Sequential Scan으로 읽은 행의 총 개수
  • idx_scan: Index Scan 횟수

문제 발견

통계 결과를 분석한 결과, 가장 많이 스캔되는 상위 4개 테이블에서 인덱스가 설정되지 않은 컬럼들이 빈번하게 조회되고 있었다. 이로 인해 매번 전체 테이블을 스캔(Full Table Scan)하면서 CPU 사용률이 급증한 것으로 판단되었다.

해결 방법

운영 중인 서비스이므로 서비스 중단 없이 인덱스를 추가해야 했다. PostgreSQL의 CONCURRENTLY 옵션을 사용하여 인덱스를 생성했다.

CREATE INDEX CONCURRENTLY index_name ON "table_name" ("column_name");

CONCURRENTLY 옵션을 사용하는 이유

✅ CONCURRENTLY 사용 시

  • 인덱스 생성 중에도 테이블에 대한 읽기/쓰기 작업이 정상적으로 가능
  • 서비스 중단 없이 인덱스 생성 가능
  • 사용자 경험에 영향 없음

❌ CONCURRENTLY 미사용 시

  • 인덱스 생성 동안 해당 테이블이 완전히 락(lock) 됨
  • 모든 INSERT, UPDATE, DELETE 작업이 블록됨
  • 테이블 크기에 비례하여 락 시간 증가 (수 분 ~ 수십 분)
  • 서비스 장애 발생 위험

성능 개선 결과

인덱스 추가 후 쿼리 실행 시간을 테스트해보았다.

EXPLAIN (ANALYZE, BUFFERS)
SELECT "table"."column"
FROM "table"
WHERE "table"."column" = 'test_value'
LIMIT 1;

실행 계획 분석 결과, 쿼리 실행 시간이 대폭 단축되었다.

결론

  • 운영 서버의 성능 이슈 발생 시 데이터베이스 스캔 통계 확인이 효과적
  • 자주 조회되는 컬럼에는 반드시 적절한 인덱스 설정 필요
  • 운영 중인 서비스에서는 CONCURRENTLY 옵션으로 무중단 인덱스 생성 권장
  • 성능 최적화 후 반드시 실행 계획 분석을 통한 검증 수행

간단한 인덱스 추가만으로도 시스템 성능을 크게 개선할 수 있었던 사례였다.
자세한건 운영팀의 모니터링 결과를 좀 보긴 해야한다..!

profile
👩🏻‍💻

0개의 댓글