postmaster
고친 사람 github-actions[bot]
postmaster 는 영어로 우체국장, 곧 우편을 맡아 돌보는 사람입니다. 그런데 기술에서 이 이름이 붙은 대상은 둘입니다. 데이터베이스 PostgreSQL 에서는 접속이 올 때마다 그 접속을 맡을 프로세스를 새로 띄우는 감독 프로세스입니다. 메일에서는 메일 서버 담당자에게 닿도록 메일을 받는 서버가 열어 두는 주소입니다.
쉽고 빠른 이해
무슨 일을 하나 — 두 뜻 모두 관리자 노릇을 합니다. PostgreSQL 의 postmaster 는 접속이 올 때마다 그 접속만 맡을 프로그램을 하나 새로 띄웁니다. 메일의 postmaster 는 [email protected] 처럼 보내면 그 메일 서버 담당자에게 닿는 주소입니다.
왜 이렇게 하나 — 데이터베이스는 접속이 언제 몇 개 올지 모릅니다. 그래서 늘 깨어서 기다리다가 접속마다 담당 프로그램을 붙여 주는 프로세스가 있어야 합니다. 메일 서버는 문제가 생기면 바깥 관리자가 연락할 곳이 필요합니다. 담당자 이름을 몰라도 닿는 주소가 정해져 있어야 합니다.
어떻게 도나
- PostgreSQL 을 켜면 postmaster 가 가장 먼저 떠서 접속을 기다립니다
- 접속이 오면 담당 프로그램을 하나 띄워 넘깁니다. 그러고는 다음 접속을 기다립니다
- 메일 서버는
postmaster앞으로 온 메일을 대문자든 소문자든 받아서 담당자에게 넘깁니다
대가 — 이름이 같아서 문서를 읽을 때 어느 뜻인지 먼저 가려야 합니다. PostgreSQL 은 접속마다 프로그램을 하나씩 띄우므로 접속이 많아지면 그만큼 메모리를 더 씁니다.
상세
이 절은 postmaster 라는 이름이 가리키는 두 대상을 차례로 봅니다. 먼저 PostgreSQL 에서 접속을 받는 감독 프로세스를 봅니다. 다음으로 메일 서버가 반드시 받아야 하는 관리자 주소를 봅니다.
끝에서는 두 뜻을 표로 견줍니다. 문서에서 어느 뜻인지 가리는 단서도 함께 짚습니다.
영어 낱말 postmaster
postmaster 는 영어로 우체국장입니다. 우편이 오가는 곳을 맡아 돌보는 사람입니다. 두 분야 모두 관리를 맡은 대상에 이 이름을 붙였습니다. 이름만 같고 하는 일은 서로 다릅니다.
PostgreSQL 의 감독 프로세스
PostgreSQL 은 관계형 데이터베이스 서버 프로그램입니다. 이 서버는 클라이언트 접속 하나마다 프로세스를 하나씩 둡니다. 프로세스는 운영체제가 메모리를 따로 주고 돌리는 실행 단위입니다. 접속 하나를 맡는 이 프로세스를 백엔드 프로세스라고 부릅니다.
문제는 접속이 언제, 몇 개나 올지 미리 모른다는 것입니다. 그래서 늘 깨어 있으면서 접속을 기다리는 프로세스가 하나 있어야 합니다. 접속이 오면 이 프로세스가 백엔드 프로세스를 새로 띄워 그 접속을 맡깁니다. 이 감독 프로세스의 이름이 postmaster 입니다.
유닉스 계열 운영체제에서는 새 프로세스를 fork 로 띄웁니다. fork 는 지금 도는 프로세스를 복제해 자식 프로세스를 만드는 운영체제 호출입니다. postmaster 는 정해 둔 포트에서 기다리다가 접속이 오면 fork 로 자식을 하나 만듭니다. 그 뒤로 클라이언트는 postmaster 를 거치지 않고 자식과 직접 주고받습니다.
아래 그림은 접속 하나가 맺어지는 순서입니다.
sequenceDiagram
participant 클라이언트
participant postmaster
participant 백엔드 as 백엔드 프로세스
클라이언트->>postmaster: 접속 요청
postmaster->>백엔드: fork 로 새로 띄운다
Note over postmaster: 다시 다음 접속을 기다린다
클라이언트->>백엔드: 질의
백엔드-->>클라이언트: 결과
질의를 받고 결과를 돌려주는 일은 백엔드 프로세스가 혼자 맡습니다. 접속이 끝나면 그 백엔드 프로세스도 끝납니다.
접속마다 프로세스를 두는 대가
이 방식의 대가는 자원입니다. 프로세스마다 메모리를 따로 씁니다. 띄우는 데도 시간이 듭니다. 접속이 수백 개로 늘면 프로세스도 수백 개가 됩니다.
이 부담 때문에 애플리케이션은 대개 접속을 매번 새로 열지 않습니다. 커넥션 풀로 접속 몇 개를 열어 두고 돌려 씁니다. 그러면 postmaster 가 프로세스를 띄우는 횟수도 줄어듭니다.
postmaster 가 띄우는 보조 프로세스
postmaster 가 띄우는 것은 백엔드 프로세스만이 아닙니다. 서버를 켜면 postmaster 가 가장 먼저 뜹니다. 그다음 접속과 상관없이 뒤에서 늘 도는 보조 프로세스들을 띄우고 지켜봅니다.
자식 프로세스들은 공유 메모리로 데이터를 주고받습니다. 공유 메모리는 여러 프로세스가 함께 읽고 쓰는 메모리 영역입니다. 프로세스마다 메모리를 따로 쓰는 구조에서 서로 데이터를 나누려면 이런 영역이 있어야 합니다.
공유 메모리에는 디스크에서 읽어 온 데이터를 담아 두는 캐시가 있습니다. 한 백엔드 프로세스가 읽어 둔 데이터를 다른 백엔드 프로세스도 함께 씁니다. 데이터를 고칠 때도 디스크가 아니라 이 캐시에 있는 사본을 먼저 고칩니다. 그래서 바뀐 데이터는 한동안 메모리에만 있습니다.
WAL(Write-Ahead Log, 선행 기록 로그)은 데이터를 고치기 전에 무엇을 고칠지 먼저 적어 두는 로그입니다. WAL 도 처음에는 공유 메모리에 쌓입니다. 변경을 확정하는 커밋 때 디스크의 로그 파일로 내려갑니다. 덕분에 서버가 갑자기 꺼져 캐시의 변경이 사라져도 디스크의 WAL 을 읽어 되살릴 수 있습니다.
보조 프로세스들은 메모리에 있는 것을 디스크로 내려 쓰는 일을 나눠 맡습니다. 대표적인 셋을 표로 모았습니다.
| 보조 프로세스 | 하는 일 |
|---|---|
| 체크포인터 | 캐시에서 바뀐 데이터를 정해진 때에 디스크로 한꺼번에 내려 씁니다. 이 시점을 체크포인트라고 부릅니다 |
| 백그라운드 라이터 | 캐시에서 바뀐 데이터를 틈틈이 조금씩 디스크로 내려 씁니다 |
| WAL 라이터 | 공유 메모리에 쌓인 WAL 을 디스크의 로그 파일로 내려 씁니다 |
체크포인터와 백그라운드 라이터는 둘 다 바뀐 데이터를 내려 쓰지만 맡는 까닭이 다릅니다. 체크포인터가 내려 쓰고 나면 그때까지의 변경은 디스크에 다 있습니다. 서버가 꺼진 뒤 되살릴 때 마지막 체크포인트 뒤의 WAL 만 읽으면 되는 까닭입니다.
백그라운드 라이터는 캐시의 빈 칸을 마련합니다. 캐시는 크기가 정해져 있어서 새 데이터를 읽어 오려면 빈 칸이 있어야 합니다. 바뀐 데이터가 든 칸은 디스크에 내려 쓴 뒤에야 비울 수 있습니다. 백그라운드 라이터가 이 일을 미리 해 두면 질의를 처리하던 백엔드 프로세스가 직접 내려 쓰며 기다리지 않아도 됩니다.
이 프로세스들과 백엔드 프로세스는 모두 postmaster 의 자식입니다. 아래 그림은 그 관계를 보입니다. 위쪽 묶음은 접속이 오갈 때마다 생기고 사라집니다. 아래쪽 묶음은 서버가 켜져 있는 동안 늘 있습니다.
flowchart TD
P["postmaster"]
subgraph 접속["접속마다 생기는 프로세스"]
B1["백엔드 프로세스 · 접속 1"]
B2["백엔드 프로세스 · 접속 2"]
end
subgraph 보조["늘 도는 보조 프로세스"]
A1["체크포인터"]
A2["백그라운드 라이터"]
A3["WAL 라이터"]
end
P --> B1
P --> B2
P --> A1
P --> A2
P --> A3
백엔드 프로세스가 죽었을 때
공유 메모리를 함께 쓰는 탓에 백엔드 프로세스 하나의 사고가 전체로 번질 수 있습니다. 비정상으로 끝난 프로세스가 공유 메모리를 망가뜨렸을지 모르기 때문입니다. postmaster 는 이 위험을 안고 가지 않습니다. 대신 전부 다시 시작합니다.
- 백엔드 프로세스 하나가 비정상으로 끝납니다
- postmaster 가 나머지 백엔드 프로세스에 모두 끝내라고 알립니다. 이때 다른 접속도 함께 끊깁니다
- postmaster 가 공유 메모리를 새로 준비하고 크래시 복구를 돌립니다. 크래시 복구는 마지막 체크포인트 뒤의 WAL 을 읽어 커밋된 변경을 다시 적용하는 과정입니다
- 복구가 끝나면 다시 접속을 받습니다
이렇게 다시 시작하는 동작은 기본으로 켜져 있습니다. 이 동작은 restart_after_crash 설정이 정합니다. 기본값은 on 입니다. 서버를 따로 감시하는 클러스터 관리 도구가 있으면 이 설정을 끄기도 합니다. 그러면 postmaster 대신 그 도구가 다음 행동을 정합니다.
프로세스 목록과 파일에 남는 이름
postmaster 는 역할의 이름입니다. 운영체제의 프로세스 목록에서는 실행 파일 이름인 postgres 로 보입니다. 자식 프로세스들도 postgres 로 시작하는 이름으로 보입니다. 그 뒤에 맡은 일이 붙습니다.
그래서 프로세스 목록에는 postgres 가 여럿 나옵니다. 그 가운데 하나가 postmaster 입니다. 나머지는 모두 그 자식입니다. 자식들의 부모 프로세스 번호를 보면 모두 같은 하나를 가리키는데, 그 프로세스가 postmaster 입니다.
postmaster 라는 이름은 파일에 남아 있습니다. PostgreSQL 은 데이터 파일을 한 폴더에 모아 두는데, 이 폴더를 데이터 디렉터리라고 부릅니다. 서버가 뜨면 이 폴더에 postmaster.pid 라는 잠금 파일이 생깁니다.
이 파일에는 postmaster 의 프로세스 번호와 포트 번호 같은 정보가 적힙니다. 같은 데이터 디렉터리에 서버가 둘 뜨는 것을 막는 데 쓰입니다.
메일 서버가 열어 두는 관리자 주소
두 번째 뜻은 SMTP(Simple Mail Transfer Protocol, 간이 메일 전송 프로토콜)에서 나옵니다. SMTP 는 메일 서버끼리 메일을 넘겨주는 프로토콜입니다. 메일을 중계하거나 받아 주는 SMTP 서버는 postmaster 앞으로 오는 메일을 반드시 받아야 합니다.
이 주소가 있어야 다른 서버의 관리자가 연락할 수 있습니다. 어느 서버에서 이상한 메일이 계속 나오면 바깥 관리자는 그 서버 담당자에게 알려야 합니다. 그런데 그 회사의 담당자 이름을 모르는 것이 보통입니다. 그때 postmaster@그 도메인 으로 보내면 닿게 정해 둔 것입니다.
메일 주소에서 @ 앞부분을 로컬 파트라고 부릅니다. 로컬 파트는 원래 대소문자를 가립니다. Alice 와 alice 를 서로 다른 메일함으로 둘 수 있습니다. postmaster 만은 예외로, 대소문자를 가리지 않고 받아야 합니다.
도메인 없이도 받는 이름
SMTP 에서 받는 사람은 RCPT(recipient, 받는 사람) 명령으로 알립니다. 보통은 @ 뒤에 도메인까지 붙인 주소를 적습니다. 도메인을 빼면 서버가 거절해도 됩니다. postmaster 만은 도메인 없이 이름만 적어도 받아야 합니다.
아래 네 줄은 example.com 의 메일 서버에 보내는 RCPT 명령입니다. 오른쪽 주석은 서버가 이 명령을 받아야 하는지입니다.
RCPT TO:<postmaster@example.com> // 받는다
RCPT TO:<Postmaster@example.com> // 받는다
RCPT TO:<POSTMASTER@example.com> // 받는다
RCPT TO:<Postmaster> // 받는다
위의 세 줄은 대소문자만 다릅니다. 서버는 셋을 같은 메일함으로 봅니다. 마지막 줄은 도메인이 없는데도 받아야 합니다. 네 줄 모두 같은 담당자에게 닿습니다.
postmaster 를 받지 않아도 되는 경우
예외는 둘입니다. 하나는 메일을 아예 받지 않는 서버입니다. 접속이 오자마자 언제나 SMTP 554 로 거절하는 서버는 postmaster 를 두지 않아도 됩니다. 554 는 이 서버가 메일을 받지 않겠다는 응답 코드입니다.
다른 하나는 공격을 받을 때입니다. 서비스 거부 공격처럼 극단적인 상황에서는 postmaster 앞으로 오는 메일도 막을 수 있습니다. 이때도 막는 범위는 공격과 상관없는 메일에 닿지 않게 되도록 좁게 잡아야 합니다.
담당자에게 넘겨주는 별칭
postmaster 라는 사람이 따로 있는 것은 아닙니다. 대개 메일 서버에 postmaster 를 별칭으로 만들어 두고 담당자의 메일함으로 넘깁니다. 담당자가 바뀌면 별칭이 가리키는 메일함만 바꾸면 됩니다.
같은 꼴로 역할에 붙인 메일 주소가 몇 더 있습니다. 웹사이트를 맡는 webmaster, 도메인 이름 설정을 맡는 hostmaster 가 그런 주소입니다. SMTP 가 메일 서버에 받으라고 요구하는 이름은 이 가운데 postmaster 하나입니다.
두 뜻을 가르는 법
아래 표는 두 뜻을 같은 칸에 놓고 견줍니다.
| PostgreSQL 의 postmaster | 메일의 postmaster | |
|---|---|---|
| 무엇인가 | 서버의 감독 프로세스 | 메일 서버 담당자에게 닿는 주소 |
| 하는 일 | 접속을 받아 백엔드 프로세스를 띄운다 | 바깥 관리자의 연락을 받는다 |
| 주로 만나는 사람 | 데이터베이스 운영자 | 메일 서버 관리자 |
| 눈에 띄는 꼴 | postmaster.pid 파일 |
[email protected] |
문장에서는 이웃한 낱말로 가립니다. 프로세스 · 접속 · 백엔드 · 데이터 디렉터리가 함께 나오면 PostgreSQL 의 뜻입니다. 메일 · 도메인 · @ · SMTP 가 함께 나오면 메일 주소의 뜻입니다.
관련 항목
PostgreSQL 에서 postmaster 가 띄우고 지켜보는 프로세스
백엔드 프로세스 · 체크포인터 · 백그라운드 라이터 · WAL writer · autovacuum · 보조 프로세스
postmaster 가 기대는 운영체제 기능
프로세스 · fork · 공유 메모리 · 시그널 · 포트 · 세마포어
postmaster 가 속한 PostgreSQL 서버의 구성 요소
PostgreSQL · 인스턴스 · 데이터베이스 클러스터 · 데이터 디렉터리 · postmaster.pid · restart_after_crash
백엔드 프로세스가 죽은 뒤 거치는 복구 단계
접속마다 프로세스를 두는 부담을 덜어 주는 수단
커넥션 풀 · PgBouncer · 지속 연결 · 클라이언트-서버 모델 · 스레드
메일의 postmaster 가 쓰이는 SMTP 의 구성 요소
SMTP · RCPT · 메일 주소 · 로컬 파트 · 도메인 이름 · SMTP 554 · MTA
postmaster 와 같은 꼴로 역할에 붙인 메일 주소
역할 메일 주소 · 메일 별칭 · webmaster · hostmaster · MAILER-DAEMON · 반송 메일
다른 이름: Postmaster · 포스트마스터