#Backend

Aurora MySQL 인덱스 DDL이 Reader 버퍼풀을 비운다?

Aurora MySQL 인덱스 DDL이 Reader 버퍼풀을 비운다?
01

Summary

인덱스 하나 숨겼을 뿐인데... 당근 DB팀이 추적한 Aurora MySQL 버퍼풀 증발 사건

Writer는 무풍지대인데 Reader의 캐시만 stale 상태로 마비시켰던 기이한 엔진 버그 디버깅기

당근 DB팀에서 미사용 인덱스를 안전하게 정리하고자 INVISIBLE 설정을 시도하는 중, Reader 노드의 CPU 및 ReadIOPS가 비정상적으로 치솟는 장애 상황을 맞닥뜨렸습니다. 끈질긴 추적 끝에 캐시 내 테이블 전체를 쓸모없게 만드는 MySQL 및 Aurora 엔진 결함을 규명했고, AWS에 직접 제보하여 글로벌 엔진 패치 수정까지 이루어낸 짜릿한 트러블슈팅 일대기입니다.

  • 01인덱스를 INVISIBLE로 전환하는 가벼운 메타데이터 수정 작업이 Reader의 캐시 전체를 오염시키는 예측 불가능한 병목을 유발했습니다.
  • 02INNODB_BUFFER_PAGE 뷰의 IS_STALE 상태값을 정밀 추적하여, 메모리에 탑재된 페이지는 유지되나 내부 플래그가 무효화되는 오작동을 규명했습니다.
  • 03단 하나의 인덱스 DDL 수행만으로 테이블 메인 데이터(PRIMARY)와 전체 인덱스 캐시 페이지의 약 95% 이상이 강제 stale 상태로 격하되는 현상을 포착했습니다.
  • 04ADD COLUMN(INSTANT) 같은 다른 비테이블 재빌드 DDL과 대비해 인덱스 관련 DDL에서만 예외적으로 해당 결함이 발생함을 체계적인 격리 테스트로 입증했습니다.
  • 05AWS 고객 지원팀과의 긴밀한 리포팅 프로세스를 통해 Aurora MySQL 엔진 릴리즈 3.14에서 결함 버그가 공식적으로 수정되도록 이끌었습니다.

RECOMMENDATION

대형 프로덕션 환경에서 Aurora MySQL을 운용 중인 팀이라면, 3.14 미만 버전에서 무중단 인덱스 drop/invisible 작업을 계획할 시 Reader의 캐시 부하 스파이크 및 ReadIOPS 급증 가능성을 염두에 두어야 하며 조속한 엔진 업데이트를 적극 권장합니다.

The Problem

Aurora MySQL에서 사용하지 않는 인덱스를 정리하기 위해 ALTER INDEX INVISIBLE 등의 DDL을 실행했을 때, Writer 노드는 정상적이었으나 Reader 노드들에서만 CPU 사용량 및 ReadIOPS가 급증하고 Buffer Cache Hit Ratio가 급락하는 부하 스파이크 현상이 발생했습니다.

The Solution

버퍼풀 상태를 실시간 감시할 수 있는 INNODB_BUFFER_PAGE의 IS_STALE 컬럼 정보를 비교 분석하여, 인덱스 임시 비활성화(INVISIBLE) 시 해당 인덱스뿐만 아니라 테이블 전체 데이터 페이지가 무효화되는 현상을 DDL 종류별로 재현해 분석을 완료했습니다.

The Result

특정 인덱스 DDL 작업 시 Reader 버퍼풀에서 전체 테이블 캐시가 불필요하게 무효화되는 동작을 확인하고 AWS 서포트에 리포팅하여, 결국 Aurora MySQL 엔진의 결함임을 공식 승인받고 엔진 버전 3.14 릴리즈에 수정사항을 반영시키는 결실을 맺었습니다.

Trade-off

버퍼풀의 상세한 세부 정보를 조회하기 위해 사용된 INNODB_BUFFER_PAGE 테이블 스캔은 대규모 버퍼풀 메모리 환경에서 조회의 속도가 수 초 이상 지연되고 추가적인 데이터베이스 부하를 유발하므로 운영 중 잦은 조회는 지양해야 합니다.

03

Key Concepts

Concept · 01

Aurora Replication

Aurora MySQL에서 스토리지를 공유하며 Writer가 Redo 로그를 전송해 복제를 처리하고, Reader는 각자 개별적인 캐시 버퍼풀을 확보하여 성능을 높이는 고유 아키텍처입니다.

  • Writer의 쓰기 redo 로그만을 전송받아 독립된 Reader 메모리 내 캐시를 업데이트합니다.
  • 테이블 전체를 재생성하는 대형 DDL 시에는 tablespace ID의 변경으로 인해 Reader의 캐시 페이지가 완전 유실되는 특성을 보입니다.
Concept · 02

IS_STALE

MySQL 8.0.24부터 도입된 tablespace 무효화 식별 컬럼으로, 버퍼풀 내의 특정 페이지가 더 이상 유효하지 않아 백그라운드나 탐색 과정에서 즉시 소멸시켜야 하는 대상임을 지시하는 속성입니다.

  • INDEX INVISIBLE 작업을 실행한 직후 Reader 버퍼풀 상에서 해당 테이블 데이터 페이지의 stale_pct가 95% 이상 폭등함을 탐지했습니다.
  • 실제 메모리가 삭제되진 않지만 만료된 상태로 분류되어 Reader가 다음 읽기 쿼리 시 스토리지로부터 리로딩을 유발하는 결정적 근거가 되었습니다.
Concept · 03

INDEX INVISIBLE

인덱스 정보 자체는 디스크 및 메모리에 유지하면서, 옵티마이저가 쿼리 계획 수립 시 해당 인덱스를 활용하지 않도록 선택적으로 투명하게 비공개 처리하는 기능입니다.

  • 데이터 유실 위험 없이 인덱스 DROP의 리스크를 사전 탐지할 목적으로 실무에서 롤백을 감안해 적극 도입되었습니다.
  • 본래 메타데이터의 버전 정보만 수정되어야 하지만 Aurora 엔진 결함으로 인해 Reader의 전체 테이블 공간 무효화 사태를 폭발시킨 원인이 되었습니다.