TL;DR

  • Percona XtraDB Cluster(PXC)에서 GCache 정리(purge)가 동결되면 쓰기 작업이 계속되는 동안 gcache.page.* 파일이 누적되며, 테스트에서는 MySQL 재시작만으로 디스크 공간이 회수되지 않음.
  • 운영 로그에서 2026년 7월 9일 GCache 정리 동결과 첫 페이지 파일 생성이 확인됐으며, 이어 클러스터 파티션 발생이 관찰됨.
  • GCache 링 파일이 약 60GB이고 트랜잭션 크기 상한이 2GB이므로, 예외적으로 큰 쓰기 집합(write set)이 원인이라는 설명은 성립하기 어려움.
  • 실험실 테스트에서 gcache.freeze_purge_at_seqno를 설정하고 sysbench 부하를 발생시키자 페이지 파일이 계속 생성됐으며, gcache.keep_pages_count=3 설정도 이를 막지 못함.
  • 실용적인 해결 방법은 MySQL을 중지한 뒤 로컬 galera.cache와 gcache.page.* 파일을 삭제하고 재시작하는 것이며, 테스트에서는 전체 상태 스냅샷 전송(SST) 대신 증분 상태 전송(IST)으로 재가입함.

사례 개요

  • Percona XtraDB Cluster(PXC) 데이터 디렉터리에 수천 개의 gcache.page.* 파일이 쌓여 디스크 공간을 점차 소비하는 사례가 발생함.
  • 처음에는 GCache가 자체 정리를 멈춘 것처럼 보였으며, 조사는 파일이 언제 생기기 시작했는지와 당시 클러스터에서 무엇이 바뀌었는지를 확인하는 데서 출발함.

시작 시점 확인

  • 가장 오래된 파일은 문제가 7월 9일 시작됐음을 보여줌. gcache.page.000000부터 순차적으로 생성됐으며, 예시 파일 크기는 각각 128MB임.
  • 가장 최근 파일은 7월 26일 생성된 것으로, 이 시점 이후 파일 생성이 멈췄다는 조사 기준을 제공함.
  • 파일 생성은 무작위로 일어나지 않았으며, 특정 시점에 시작해 다음 MySQL 재시작 이후 멈춘 양상임.

대규모 트랜잭션이 원인일 수 있는가?

  • Galera가 오래된 페이지를 회수하지 못하거나 예외적으로 큰 쓰기 집합이 추가 페이지 할당을 강제하지 않는 한, 수천 개의 GCache 페이지 파일이 생기는 일은 일반적이지 않음.
  • 해당 환경의 GCache 링 파일은 약 60GB였음. 그러나 가장 큰 트랜잭션 크기는 2GB로 제한되므로, 대규모 쓰기 집합이 원인이라는 가설은 사실상 불가능함.
  • 이에 따라 오류 로그를 조사했고, 다음 기록을 발견함.
  • Freezing gcache purge at 16198595494
  • Created page .../gcache.page.000000 of size 134217728 bytes
  • gcache.freeze_purge_at_seqno가 활성화되면 Galera는 오래된 GCache 페이지 회수를 중지함. 복제가 계속되면 기존 페이지를 디스크에 남겨 둔 채 새 페이지 파일을 할당함.

클러스터 활동과의 상관관계

  • 오류 로그에서 몇 초 뒤 클러스터 파티션 기록이 확인됨. GCache 정리 동결, 첫 페이지 파일 생성, 멤버십 변경이 이어지는 순서임.
  • 로그에는 정리가 동결된 이유가 명시적으로 나오지 않음. 다만 사건 순서는 파티션된 노드가 재가입할 때 증분 상태 전송(IST)을 수행할 가능성에 대비해 Galera가 쓰기 집합을 보존했음을 강하게 시사함.
  • 로그에는 노드 c3acab8a-8a74를 잊었다는 기록과, 해당 노드가 파티션된 상태로 나타나는 클러스터 뷰가 포함됨.

정리가 어떻게 동결됐을 수 있는가?

  • 코드베이스와 문서를 추가로 조사한 결과, Galera가 GCache 페이지 정지 기능을 자체적으로 호출할 가능성은 사실상 없으며, 현실적인 실행 방법은 다음 전역 설정을 사용하는 것이라는 단서가 나옴.
  • SET GLOBAL wsrep_provider_options='gcache.freeze_purge_at_seqno=XYZ';
  • 참고 자료: Percona Galera pull request 132
  • 관련 읽을거리: No SST node rejoins in PXC

동작 재현

  • Peter Sylvester(SoS)가 실험 환경에서 gcache.freeze_purge_at_seqno를 수동 설정하고 sysbench로 부하를 생성해 동작을 재현함. 결과는 운영 환경에서 관찰한 현상과 일치함.
  • gcache.keep_pages_count=3으로 설정했더라도 정리가 동결된 상태에서는 Galera가 페이지 파일을 계속 생성함.
  • 실험에서는 wsrep_last_committed 값 94559를 확인한 뒤 gcache.freeze_purge_at_seqno=94559로 설정함.
  • 클러스터의 원본 호스트에서 sysbench oltp_read_write를 실행함. MySQL 드라이버와 sysbench 데이터베이스를 사용하고, 테이블 4개·스레드 4개·테이블 크기 1,000으로 부하를 생성함. 실행 시간과 처리량 제한을 모두 해제한 무기한 테스트였으며, 5초 시점에 초당 트랜잭션 수는 311.80, 초당 쿼리 수는 6,246.62였음.
  • 부하 중 데이터 디렉터리에는 약 10MB 크기의 gcache.page.000000부터 gcache.page.000006까지와 약 11MB 크기의 galera.cache가 존재함.
  • 부하 종료 후 mysqld를 중지하고 다시 시작했지만, 페이지 파일은 제거되지 않고 디스크에 그대로 남음.

추가 관찰

  • 이후 MySQL을 다시 시작해 사용하지 않는 페이지가 회수되는지 확인했지만, 모든 페이지 파일이 디스크에 남음.
  • gcache.freeze_purge_at_seqno=-1을 명시적으로 설정한 뒤에도 파일은 삭제되지 않음.
  • 테스트 결과, 정지가 해제됐다는 이유만으로 시작 시 복구 과정이 누적된 페이지 파일을 자동 제거하지는 않음. 정지가 발생해 페이지 파일이 쌓인 뒤에는 MySQL 재시작만으로 공간을 회수하기에 충분하지 않음.
  • 이 동작을 해결하기 위한 버그 PXC-5323이 등록됨.

파일을 삭제해도 되는가?

  • MySQL을 중지한 뒤 로컬 GCache 파일을 제거하고 노드를 다시 시작하는 방식으로 확인함.
  • Galera는 필요한 캐시 구조를 자동으로 다시 만들었음. 더 중요한 점은 노드가 IST를 성공적으로 완료했으며, 테스트에서는 로컬 페이지 파일 삭제가 SST를 강제하지 않았다는 것임.
  • 파일을 제거하기 전에는 해당 노드를 중지하고, 필요한 쓰기 집합을 제공할 수 있는 정상 노드가 클러스터에 있는지 확인해야 함.
  • 운영 환경에서 적용하기 전에 자체 환경에서 이 동작을 검증해야 함. 테스트에서는 IST로 충분했음.

결론

  • 운영 로그와 실험실 테스트를 종합하면 gcache.page.* 파일 누적의 원인은 GCache 정리 동결임.
  • 테스트에서는 MySQL 재시작으로 누적 파일이 회수되지 않음. PXC 노드가 GCache 페이지 파일을 계속 생성하는 동작은 PXC-4495에서 이미 수정됨.
  • 실용적인 우회 방법은 MySQL을 중지하고 로컬 galera.cache 및 gcache.page.* 파일을 제거한 뒤 노드를 다시 시작하는 것임.
  • 테스트에서 노드는 전체 SST 없이 IST를 사용해 클러스터에 재가입함. 정리 작업 전에는 다른 정상 노드가 필요한 쓰기 집합을 보유하는지 확인해야 함.