본문으로 건너뛰기
10.2 클러스터 시작·정지·재시작

10.2 클러스터 시작·정지·재시작

PostgreSQL 클러스터 라이프사이클 명령에는 세 가지 인터페이스가 있습니다. 공식 도구인 pg_ctl, OS 통합인 systemctl, 그리고 OS 패키지가 제공하는 헬퍼 명령입니다. 운영에서는 systemd가 표준이지만 옛 패턴이나 디버깅에서는 pg_ctl로 직접 다룹니다.

명령 비교

작업pg_ctlsystemctl (PGDG RHEL)pg_ctlcluster (Debian)
시작pg_ctl -D <PGDATA> startsystemctl start postgresql-17pg_ctlcluster 17 main start
정지pg_ctl -D <PGDATA> stop -m fastsystemctl stop postgresql-17pg_ctlcluster 17 main stop
재시작pg_ctl -D <PGDATA> restartsystemctl restart postgresql-17pg_ctlcluster 17 main restart
reload (config)pg_ctl -D <PGDATA> reloadsystemctl reload postgresql-17pg_ctlcluster 17 main reload
상태pg_ctl -D <PGDATA> statussystemctl status postgresql-17pg_ctlcluster 17 main status

운영 표준: systemctl. 부팅 시 자동 시작, 로그 통합, 종속성 관리 등 OS 통합 이점.

정지 모드 — pg_ctl -m

모드동작
smart (기본)모든 클라이언트가 연결을 끊을 때까지 기다림 — 운영에서는 영원히 안 끝남
fast활성 트랜잭션을 rollback하고 정지. 운영 표준
immediatecrash recovery와 동일 — WAL 재생 필요. 비상용
pg_ctl -D /var/lib/pgsql/17/data stop -m fast

systemctl은 내부적으로 fast를 씁니다.

시그널 직접 보내기

postmaster는 시그널을 받습니다. 디버깅에 가끔 사용합니다.

시그널효과
SIGTERMfast shutdown
SIGINTsmart shutdown
SIGQUITimmediate shutdown
SIGHUPreload
sudo -u postgres kill -HUP $(head -1 $PGDATA/postmaster.pid)

postmaster.pid 첫 줄에 PID가 들어 있습니다.

reload vs restart 결정

파라미터 변경필요
옵티마이저 비용·로깅·autovacuum 등reload
pg_hba.conf·pg_ident.confreload
메모리·WAL·shared 영역restart

pg_settings.pending_restart로 확인:

SELECT name, setting FROM pg_settings WHERE pending_restart;

systemd 유닛 파일

PGDG 패키지의 postgresql-17.service:

[Unit]
Description=PostgreSQL 17
After=syslog.target network-online.target

[Service]
Type=notify
User=postgres
Environment=PGDATA=/var/lib/pgsql/17/data
ExecStart=/usr/pgsql-17/bin/postmaster -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=300

[Install]
WantedBy=multi-user.target
항목의미
Type=notifysystemd가 postgres의 “준비 완료” 신호 대기 (--with-systemd 빌드 필요)
TimeoutSec=3005분 안에 시작 못 하면 실패 처리 — 큰 WAL 재생에서는 늘려야
KillSignal=SIGINTsmart shutdown — 운영에서는 fast(SIGTERM)로 변경 권장

override

배포 표준 유닛을 직접 수정하지 말고 systemctl edit 사용:

sudo systemctl edit postgresql-17
[Service]
KillSignal=SIGTERM
TimeoutSec=900
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
Environment=PG_OOM_ADJUST_VALUE=-1000

PG_OOM_ADJUST_*은 OOM killer가 postmaster를 우선 후순위로 두도록 함 (1.4 참고).

자식 프로세스 보호 (OOM)

기본적으로 backend는 OOM killer에 죽을 수 있습니다. postmaster가 무사하더라도 backend 하나가 죽으면 다른 모든 backend가 강제로 재기동됩니다(3.1). PGDG 패키지는 postmaster만 보호하는 게 표준입니다.

세밀히 하려면:

# postgresql.conf
oom_score_adj = 0   # backend 기본

postmaster 자체는 systemd 유닛의 PG_OOM_ADJUST_VALUE로 보호하고, backend가 죽는 것은 자연스러운 동작입니다(3.1 참고).

Debian/Ubuntu의 다중 클러스터

Debian 계열은 한 호스트에 여러 클러스터 운영을 정식 지원합니다.

# 클러스터 목록
pg_lsclusters
# Ver Cluster Port Status Owner    Data directory               Log file
# 17  main    5432 online postgres /var/lib/postgresql/17/main  ...
# 17  staging 5433 online postgres /var/lib/postgresql/17/staging  ...

# 새 클러스터 만들기
sudo pg_createcluster 17 reporting --start

# 정지
sudo pg_ctlcluster 17 reporting stop

# 삭제
sudo pg_dropcluster 17 reporting

각 클러스터의 systemd 유닛: postgresql@17-main.service. 그룹 postgresql.service가 모두 시작/정지.

시작 시 진단

# 시작 실패 시
sudo journalctl -u postgresql-17 -n 200
sudo tail -200 /var/lib/pgsql/17/data/log/postgresql-*.log

흔한 시작 실패 원인:

메시지원인
could not bind ... Address already in use다른 프로세스가 포트 점유
database files are incompatible with server버전 mismatch — pg_upgrade 필요
directory ... is not empty (initdb)옛 데이터 디렉토리
lock file already existscrash 후 stale postmaster.pid — 안전 확인 후 수동 삭제
could not load libraryshared_preload_libraries에 존재하지 않는 모듈

정상 종료의 의미

PostgreSQL이 정상 종료(fast shutdown)되면:

  1. 새 연결 거부
  2. 활성 트랜잭션 rollback
  3. dirty page를 디스크에 모두 flush
  4. WAL 안전 위치까지 fsync
  5. postmaster.pid 삭제
  6. exit

postmaster.pid가 남아 있으면 아직 죽지 않았거나 비정상 종료한 것입니다. 운영 중에는 systemctl이 이 파일을 자동으로 정리하지만, 수동으로 정리해야 한다면 프로세스가 모두 죽었는지 확인한 뒤에 지웁니다.

ps -ef | grep postgres   # 잔존 프로세스 확인
# 모두 없으면
sudo rm $PGDATA/postmaster.pid

정상 종료의 비용 — 큰 클러스터

종료 시점에 dirty page가 매우 많으면 flush가 수 분 걸립니다. 운영 점검 시간 잡을 때 고려.

대응:

  • 종료 전 CHECKPOINT; 명시 호출
  • checkpoint_completion_target을 평소 0.9로 두어 dirty 페이지 누적 줄임

강제 종료가 필요한 경우

  • 클러스터가 응답 없음, 핵심 무관 작업
  • 디스크 풀로 백그라운드 작업 실패
  • 백업·복구 절차의 한 단계
# 정지 못 하면 kill -9 (immediate)
sudo systemctl kill -s SIGQUIT postgresql-17
# 또는
sudo pkill -9 postgres   # 매우 위험

immediate 종료 후 재기동하면 WAL을 재생하느라 시간이 걸리지만, 일관성은 유지됩니다.

kill -9 postmaster는 마지막 수단. 데이터 손상은 안 되지만 이후 재기동이 한참 걸리고, 인덱스·통계가 일시 불일치 상태일 수 있습니다.

정리

시작·정지는 RHEL에서는 systemctl, Debian에서는 pg_ctlcluster가 표준이고, 정지 모드는 fast를 씁니다. smart는 클라이언트가 모두 끊길 때까지 기다리다 운영에서는 사실상 끝나지 않습니다. reload와 restart 중 무엇이 필요한지는 pg_settings.pending_restart로 판단하고, OOM 보호나 timeout은 systemd 오버라이드로 조절합니다.

  • 시작 실패 진단은 journalctl + PostgreSQL 로그
  • 비정상 종료 후 남은 postmaster.pid는 잔존 프로세스 확인 후 수동 정리