Yet another performance degradation research induced by mutex in an unexpected hotpath in a mature database code.
MariaDB, InnoDB LRU 승격 경로 수정해 일부 시험서 11.8 처리량 2.8배 높여
MariaDB가 InnoDB의 페이지 승격 과정에서 발생하던 전역 뮤텍스 경합을 줄이는 패치를 11.8 브랜치에 병합했습니다. 40스레드·100GiB 버퍼 풀의 읽기 중심 시험에서 11.8 처리량은 수정 전 20,326 QPS에서 수정안 57,052 QPS로 증가했습니다. 특정 벤치마크 결과이며 혼합 읽기·쓰기 작업은 후속 측정 과제로 남았습니다.
- 주제
본문
MariaDB InnoDB의 LRU 페이지 승격 경로를 고친 패치가 특정 읽기 중심 시험에서 11.8의 처리량을 약 2.8배 높였습니다. MariaDB.org에 분석을 공개한 Alessandro Vetere는 10.5 이후 일부 작업에서 나타난 저하가 버퍼 풀 통합만으로 생긴 게 아니라, 페이지 승격 때 전역 뮤텍스(buf_pool.mutex)를 자주 잡게 된 데서 비롯됐다고 설명합니다.
InnoDB 버퍼 풀은 데이터 페이지를 메모리에 보관하는 캐시이며, LRU 목록은 여유 공간이 필요할 때 내보낼 페이지를 고릅니다. 자주 다시 읽은 페이지는 목록의 최근 사용 영역(young)으로 옮겨 퇴출을 늦춥니다. MariaDB 10.5는 여러 버퍼 풀 인스턴스를 하나로 합쳐 전체 서버가 LRU 목록 하나와 이를 보호하는 뮤텍스 하나를 공유하게 했습니다. Vetere의 분석에 따르면 여기에 페이지 해제 동작의 변화가 겹쳤습니다. 이전에는 실제 퇴출이 시작될 때 움직이던 freed_page_clock이 더 일찍 움직이면서, 데이터가 버퍼 풀에 들어맞는 작업에서도 페이지 승격이 발생했고 그때마다 뮤텍스 경합이 커졌습니다.
10.8.8이 예외적으로 높은 처리량을 보인 이유도 승격 빈도와 관련 있다고 Vetere는 추정합니다. 해당 버전에서는 undo 페이지 누수로 버퍼 풀이 거의 찼고, 자주 쓰는 페이지가 이미 young 영역에 들어가 있어 추가 승격이 드물었을 수 있다는 설명입니다. 따라서 이 결과는 단일 버퍼 풀 구조가 성능 저하의 유일한 원인이라는 해석을 약화하고, 페이지 승격 자체의 비용이 중요하다는 쪽을 뒷받침합니다.
수정안은 페이지를 읽는 순간에는 뮤텍스를 잡지 않고, innodb_old_blocks_time 조건을 충족한 페이지에 PROMOTE 표시를 합니다. 페이지 클리너나 LRU 퇴출처럼 이미 뮤텍스를 보유한 작업이 나중에 표시된 페이지를 목록의 최근 사용 영역으로 옮깁니다. 스캔으로 한 번 읽힌 페이지가 뒤늦은 목록 정리 때문에 재접근한 것처럼 취급되지 않도록 승격 자격은 접근 시점에 판정합니다. 변경은 MariaDB 서버 PR #5763에서 11.8 브랜치에 병합됐습니다.
성능 수치는 특정 작업에 한정됩니다. Vetere가 제시한 40스레드, 100GiB 버퍼 풀의 oltp_points_covered.lua 시험에서 수정 전 11.8은 20,326 QPS, 수정안은 57,052 QPS였습니다. 같은 장비에서 각각 3회 실행한 중앙값이며, 수정안 수치는 PR 검토 중인 버전에서 얻었습니다. 별도 Hetzner 호스트의 AMD EPYC 9454 48코어 시험에서는 11.8이 수정 전 17,925 TPS에서 수정 후 66,653 TPS로 올랐고, 12.3과 13.1에서도 각 한 번의 실행에서 처리량이 증가했습니다. 이 시험은 트랜잭션마다 쿼리 하나를 실행해 TPS와 QPS가 같습니다.
이번 결과는 인메모리 읽기 중심 벤치마크의 개선을 보여줍니다. 디스크 입출력이 많은 혼합 읽기·쓰기 HammerDB TPROC-C 시험은 게시글에서 후속 측정 과제로 남겼습니다. 수정 후 Innodb_buffer_pool_pages_made_young 값은 스윕 시점에 집계하므로 이전 버전의 같은 지표와 직접 비교할 수 없습니다.
자료: MariaDB.org / 정리·해설: Trawling
참고 자료
- MDEV-33966: buf_page_make_young() is a contention point by iMineLink · Pull Request #5763 · MariaDB/server — https://github.com/MariaDB/server/pull/5763