Postgres Internals Deep Dive: 프로세스 아키텍처

저자: Srinath Reddy
2025년 9월 3일

서론

PostgreSQL이 시작될 때부터 종료될 때까지 내부에서 어떤 일이 일어나며, 프로세스들이 어떻게 함께 동작하는지 궁금했던 적이 있나요? 이 블로그는 그 과정을 단계별로 안내합니다.


프로세스 아키텍처

pg_ctl을 사용해 postgres를 시작하면, 가장 먼저 실행되는 것은 postmaster로, 이후 대부분의 프로세스의 부모 프로세스 역할을 합니다.
postmaster는 main() 함수를 실행하고, 그 안에서 PostmasterMain을 호출하는데 여기서 중요한 작업들이 진행됩니다.

  • GUC(Global User Configuration) 옵션 초기화
  • postgres 실행 파일의 명령줄 인자 파싱 및 관련 GUC 설정
  • 데이터 디렉터리, lock 파일, control 파일 확인 및 datadir lock 파일 생성 (해당 파일에는 postmaster 상태와 pid가 기록되어, 하나의 클러스터에 하나의 서버만 실행되도록 보장)
  • 공유 라이브러리 로드 및 필요한 공유 메모리 크기 계산
  • 해당 크기만큼 공유 메모리 세그먼트 할당

그 다음은 핵심 루프인 ServerLoop가 시작됩니다. 이 루프는 결코 끝나지 않으며, 종료된다면 서버도 내려갑니다.


ServerLoop (생명의 루프)

이는 무한 이벤트 루프로, 시그널 핸들러에 의해 설정된 Latch나 소켓에 대기 중인 새로운 연결 요청을 기다립니다.

이 루프에서:

  • 새로운 자식 프로세스가 시작되고, 죽은 프로세스는 정리됩니다.
  • 백엔드에서 오는 요청/시그널이 처리됩니다.
  • 필요한 프로세스가 실행 중인지 확인하고, 부족하면 IO workers나 백그라운드 프로세스를 새로 시작합니다 (LaunchMissingBackgroundProcesses).

자식 프로세스의 등장

postmaster의 자식 프로세스는 다음과 같습니다:

  • IO workers: 페이지를 비동기적으로 읽어 일반 백엔드의 부하를 줄임
  • Checkpointer: 오래된 WAL 정리 및 공유 버퍼의 dirty 페이지를 디스크에 기록
  • Background writer: 공유 버퍼의 dirty 페이지를 주기적으로 기록해 백엔드의 부하 감소
  • Startup process: 마스터에서는 복구 완료 시까지 WAL을 재생, 리플리카에서는 지속적으로 WAL을 재생
  • WAL writer: WAL 버퍼에서 디스크로 플러시
  • Autovacuum launcher: 주기적으로 autovacuum-worker 실행

이외에도 요청에 따라 다양한 프로세스가 fork되며, 각각 별도 블로그에서 다룰 만한 주제입니다.

PostgreSQL은 시점에 따라 자식 프로세스를 다르게 생성합니다:

  • 서버 시작 시 기본 프로세스 생성
  • 이후 필요 시:
    • Backend 프로세스 (클라이언트 연결 처리)
    • Background workers (확장에서 제공하는 사용자 정의 코드 실행)

대부분의 자식 프로세스는 postmaster_child_launch 함수로 생성되며, BackendType enum에 따라 해당 프로세스의 main 함수가 호출됩니다.


백엔드 프로세스

기본적으로 postmaster는 listen_addresses (기본값: localhost)에서 클라이언트 연결 요청을 기다립니다.
psql 클라이언트가 libpq를 통해 postmaster에 연결 요청을 보내면, postmaster는 새로운 백엔드 프로세스를 fork하여 해당 클라이언트의 쿼리를 처리하게 합니다.

  • 각 psql 클라이언트마다 서버에 새로운 자식 프로세스가 생성됨
  • 새 백엔드 프로세스는 공유 메모리에 접근 가능 (예: BufferBlocks)
  • 쿼리 실행 시 필요한 페이지가 공유 버퍼에 없으면 디스크에서 읽어옴
  • 버퍼가 가득 차면 백엔드가 직접 dirty 페이지를 디스크에 기록 후 새 페이지를 로드

이 과정에서 백엔드의 부하를 줄이기 위해 checkpointerbackground writer가 도와주어 쿼리 실행 속도를 개선합니다.


변신하는 백엔드 프로세스

복제(replication) 상황에서는 특별한 동작이 발생합니다.

  • 리플리카 노드가 시작되면 startup process가 walreceiver 프로세스를 실행
  • walreceiver가 libpq로 primary postmaster에 replication 메시지를 보내 연결 요청
  • postmaster는 이를 일반 백엔드처럼 처리하지만, startup packet에 “replication”이 있으면 해당 백엔드를 walsender로 변환
  • 물리적 복제에서는 WAL을 그대로 전송, 논리적 복제에서는 WAL을 해석해 전송

즉, walsender도 사실은 일반 백엔드 프로세스로 시작합니다.


백그라운드 워커

확장에서 제공하는 사용자 정의 코드를 실행하는 프로세스입니다.

  • 확장이 shared_preload_libraries에 지정되면 _PG_init()이 호출되고, RegisterBackgroundWorker로 postmaster의 리스트에 추가
  • postmaster의 ServerLoop에서 maybe_start_bgworkers가 호출되면 실행
  • 서버 실행 중에도 RegisterDynamicBackgroundWorker로 추가 가능

예: 논리적 복제 런처(logical replication launcher)는 서버 시작 시 함께 실행되는 백그라운드 워커입니다.


시그널 처리

postmaster는 다양한 시그널을 처리합니다.

시그널핸들러처리 함수
SIGHUPhandle_pm_reload_request_signalprocess_pm_reload_request
SIGINThandle_pm_shutdown_request_signalprocess_pm_shutdown_request
SIGQUIThandle_pm_shutdown_request_signalprocess_pm_shutdown_request
SIGTERMhandle_pm_shutdown_request_signalprocess_pm_shutdown_request
SIGUSR1handle_pm_pmsignal_signalprocess_pm_pmsignal
SIGCHLDhandle_pm_child_exit_signalprocess_pm_child_exit

예:

  • SIGHUP: postgresql.conf 재로드
  • SIGUSR1: 백엔드 요청, promote/logrotate 처리

종료 모드 (Shutdown Modes)

PostgreSQL에는 3가지 종료 모드가 있습니다:

시그널모드설명
SIGTERMSmart모든 클라이언트 종료 후 종료
SIGINTFast즉시 종료 (기본값)
SIGQUITImmediate즉시 종료 (복구 필요)
  • Smart: 기존 연결이 모두 종료될 때까지 기다림, 신규 연결 차단
  • Fast: 클라이언트 종료 대기 없이 백엔드 종료
  • Immediate: 모든 프로세스 강제 종료, 재시작 시 복구 필요

체크포인트 및 walsender 종료, IO workers 종료 등이 순차적으로 진행되며, syslogger는 마지막에 종료됩니다.


리퍼 (Reaper)

자식 프로세스 종료 시 postmaster가 처리하는 방식입니다.

  • 자식 프로세스 종료 → postmaster가 SIGCHLD 수신
  • handle_pm_child_exit_signal 실행 → pending_pm_child_exit = true 설정
  • ServerLoop에서 이를 감지해 process_pm_child_exit() 호출 → 자원 정리

비정상 종료 시 HandleChildCrash API가 모든 프로세스에 종료 신호를 보내고, 서버 재시작 및 crash recovery가 진행됩니다.


결론

PostgreSQL의 프로세스 아키텍처는 postmaster와 다양한 자식 프로세스들의 협력 구조입니다.

  • 클라이언트 쿼리 처리: 백엔드 프로세스
  • 성능 최적화: checkpointer, background writer
  • 복제: walreceiver, walsender
  • 확장 기능: 백그라운드 워커
  • 안정성: 시그널 및 종료 모드

이 모든 것이 맞물려 PostgreSQL이 안정적으로 작동합니다.

메일: salesinquiry@enterprisedb.com