Linux 7.0, PostgreSQL 성능 절반으로 뚝... 원인은?

by DD
1개월 전
조회수 10

Linux 7.0에서 PREEMPT_NONE 옵션 제거로 인해 PostgreSQL의 성능이 절반으로 감소하는 문제 발생

StrategyGetBuffer 함수 내 스핀락(Spinlock) 사용 중 마이너 페이지 폴트(Minor Page Fault) 발생이 주요 원인으로 분석됨

Huge Pages 설정을 통해 페이지 폴트 횟수를 줄여 성능 저하 문제를 해결 가능

Restartable Sequences(rseq)를 활용한 해결책이 제시되었으나, PostgreSQL 커뮤니티에서는 PREEMPT_NONE 복구를 더 선호하는 분위기

Linux 7.0 프리엠션(Preemption) 변화와 PostgreSQL 성능 저하

Linux 7.0에서 PREEMPT_NONE 옵션 제거로 인해 PostgreSQL의 성능이 저하된 원인을 분석한다. 특히, PREEMPT_LAZY 환경에서 StrategyGetBuffer 함수 내 스핀락(Spinlock) 사용 중 마이너 페이지 폴트(Minor Page Fault) 발생 시, 락을 획득한 스레드가 프리엠션(Preemption)되어 다른 백엔드(Backend)들이 CPU를 소모하는 상황을 설명한다. 이는 96-vCPU 환경에서 s_lock 함수가 CPU 시간의 55%를 차지하는 결과로 이어졌다.

스핀락(Spinlock)과 페이지 폴트(Page Fault)의 상호 작용

PostgreSQL의 StrategyGetBuffer 함수는 공유 버퍼 풀(Shared Buffer Pool)에 대한 접근을 제어하기 위해 스핀락(Spinlock)을 사용한다. 스핀락은 락을 획득하기 위해 대기하는 스레드가 CPU를 계속 소모하는 방식이다. 마이너 페이지 폴트(Minor Page Fault)가 발생하면 락을 획득한 스레드가 페이지 할당을 위해 커널(Kernel)에 의해 중단될 수 있으며, 이로 인해 다른 스레드들이 락을 얻기 위해 불필요하게 CPU 사이클을 소모하게 된다. 이러한 상황은 성능 병목(Performance Bottleneck)을 유발한다.

Huge Pages를 활용한 성능 개선

성능 저하 문제를 해결하기 위해 Huge Pages를 사용하는 방법을 제시한다. Huge Pages는 4KB 대신 2MB 또는 1GB 크기의 메모리 페이지를 사용함으로써, 잠재적인 페이지 폴트(Page Fault) 발생 횟수를 줄인다. 120GB 공유 버퍼 풀(Shared Buffer Pool)을 사용하는 환경에서 Huge Pages를 사용하면 페이지 폴트 횟수를 수백만에서 수십 개로 줄일 수 있으며, 이는 TLB(Translation Lookaside Buffer) 압력 감소성능 향상으로 이어진다.

Restartable Sequences(rseq)의 대안

Intel 엔지니어는 Restartable Sequences(rseq)를 사용하여 PostgreSQL의 성능 문제를 해결하는 방법을 제안했다. rseq는 사용자 공간 코드에서 프리엠션(Preemption) 여부를 감지하고, 필요한 경우 작업을 다시 시작할 수 있도록 하는 Linux 커널 기능이다. 하지만 PostgreSQL 커뮤니티에서는 PREEMPT_NONE 옵션 복구를 선호하며, 이는 기존 성능 유지커널 변경에 대한 부담 감소를 위한 선택으로 보인다.

How Linux 7.0 Broke PostgreSQL: The Preemption Regression Explained