Replication Slot 탄생
PostgreSQL에서 안정적인 Replication 유지를 위한 WAL 파일의 관리는 항상 어려운 문제였습니다. Standby Server의 연결이 끊어진 상태에서 Main Server의 WAL 파일이 재사용(Overwrite) 되면 Replication 상태를 유지할 수 없으므로 다음과 같은 에러를 마주하게 됩니다.
그리고 이러한 상황이 발생하기까지 적절한 조치를 취하지 못했다면, Replication을 지속하기 위해 Standby Server를 다시 구성해야 합니다. 물론, 이를 피하기 위해 운영자는
max_wal_size (PostgreSQL 9.5 버전 까지는 max_keep_segments) 파라미터를 조정하는 등, WAL 파일 보관 정책을 세워 관리했을 것입니다.PostgreSQL 9.4 버전부터 도입된 Replication Slot은 Standby Server와의 연결이 끊어져도 필요한 WAL 파일이 Main Server에 유지되도록 하는 기능을 말합니다. Replication Slot을 통해 WAL 파일(또는 Record)이 Standby Server에 전달되면, WAL 파일을 삭제/재사용합니다.
Replication Slot 사용 장점
- Slot을 사용한 Replication의 경우 Standby Server의 연결이 끊어진 경우에도 다시 연결이 될 때 필요한 WAL 파일을 유지할 수 있습니다.
- Standby Server가 필요한 WAL 파일에 대한 보관을 자동으로 관리하기 때문에 운영자가 WAL 파일 보관 설정에 대한 고민을 할 필요가 없습니다.
Replication Slot 사용 단점
- Standby Server가 연결이 끊긴 경우 WAL 파일이 재사용되지 않고 유지되어 Main Server의 Disk Full을 발생시킬 수 있습니다.(pg_wal Directory)
- Replication Slot은 자동으로 삭제되지 않기 때문에 Replication을 유지하지 않을 경우 위와 같은 이유로 Replication Slot을 운영자가 삭제해야 합니다.
Replication Slot은 Physical Replication Slot과 Logical Replication Slot으로 구분됩니다.
Physical Replication Slot
Physical Replication Slot은 Streaming Replication에서 사용할 수 있습니다. Main Server에서 발생하는 변경 사항들은 WAL 파일에 기록됩니다. Physical Replication Slot은 WAL 파일에 기록된 내용을 읽어 Standby Server와 동기화를 유지할 수 있습니다.
Physical Replication Slot 생성
Physical Replication Slot 확인
pg_replication_slots Catalog를 통해서 Replication Slot에 대한 정보를 확인할 수 있습니다. 위 예시에서 pslot은
restart_lsn컬럼을 통해 0/A000060 이전의 WAL 파일은 제거하지 않을 것임을 확인할 수 있습니다.Logical Replication Slot
Logical Replication Slot은 Physical Replication Slot과 달리 논리적 디코딩이라는 메커니즘을 통해 디코딩된 메시지를 통해 복제를 합니다. 논리적인 변경 사항을 기반으로 복제를 수행하므로 Physical Replication Slot보다 유연한 데이터 복제(특정 스키마, 테이블 등)가 가능합니다.
Logical Replication Slot 생성
Logical Replication Slot은 Physical Replication Slot과 달리
pgoutput 모듈을 사용하여 복제를 수행합니다. pgoutput 모듈은 PostgreSQL 10 버전부터 기본으로 제공되며, 변경 사항을 출력하는 데 사용됩니다. Logical Replication Slot 생성 시 현재 트랜잭션의 로그 위치가 반환되며(0/A000650), 이 위치부터 논리적으로 디코딩된 WAL Record가 Standby Server로 전송됩니다.Logical Replication Slot 확인
Logical Replication Slot Plugin 종류
- pgoutput : Logical Replication에서 사용되는 표준 출력 Plugin입니다. Database의 변경 사항을 이전형식(Binary)으로 제공합니다.
- test_decoding : Database의 변경 사항을 사람이 읽을 수 있는 형식으로 제공하여, 주로 테스트 및 개발목적으로 사용됩니다.
- wal2json : Database의 변경 사항을 JSON 형식으로 제공합니다.(3rd-party Plugin)
Replication Slot의 위험성
Replication Slot은 서버 장애 상황에서도 Replication이 유지되기 위해 설계되었지만, Slot을 사용하는 응용프로그램의 상태는 알 수 없습니다. 따라서, 생성된 Slot이 사용되지 않는 경우도 있을 수 있습니다. 이러한 경우, 아직 반영되지 않은 WAL 파일을 계속 보관해야 하기 때문에 VACUUM에 의해서 정리되지 않습니다. 이러한 상태가 계속 유지될 경우 극단적으로 XID Wraparound를 방지하기 위해 PostgreSQL가 종료될 수 있으므로, 더 이상 필요하지 않은 Slot은 삭제해야 합니다.
Replication Slot 유무에 따른 pg_wal 사이즈 변화
테스트 테이블을 생성하고 WAL 파일들의 합이 1GB가 되도록 데이터를 입력합니다. 본 테스트에서는 약 17만건 데이터 입력 시 하나의 WAL파일(16MB)이 생성되며, 총 64개의 WAL 파일이 생성되도록 데이터를 입력합니다. (16MB * 64 = 1024MB)
실제로 pg_wal 디렉토리에 64개의 WAL 파일이 생성되었고 그 크기가 1009 MB인 것을 알 수 있습니다.
Main Server에서 생성된 WAL 파일의 내용을 Standby Server에서 전부 수신했다면, Main Server의 pg_wal 디렉토리는
max_wal_size에 설정된 1GB 안에서 WAL 파일이 재사용됩니다.max_wal_size 파라미터의 기본값은 1GB입니다.Standby Server 종료
Standby Server가 종료된 상태에서 Main Server에 대량의 트랜잭션이 발생했다고 가정해 보겠습니다. 이때 Replication Slot의 존재 유무에 따라 pg_wal 디렉토리의 크기는 전혀 다른 모습을 보입니다.
Replication Slot을 사용하지 않을 경우 Main Server는 Standby Server의 WAL 파일 수신 여부를 고려하지 않으므로,
max_wal_size로 설정된 크기를 유지하기 위해 기존의 WAL 파일을 재사용(Overwrite)합니다.반면, Replication Slot을 사용 중이라면 Standby Server의 WAL 파일 수신 여부를 체크한 후, 수신이 불가한 상태라면
max_wal_size크기 이상으로 pg_wal 공간이 증가할 수 있습니다. 이는 Standby Server가 WAL 파일을 수신할 때까지 파일을 보관하기 때문인데, 별다른 조치가 없다면 Main Server의 Disk Full 혹은 XID Wraparound 방지를 위한 PostgreSQL 종료등의 문제가 발생할 수 있습니다.Replication Slot Parameter
PostgreSQL Replication Slot을 사용하기 위해서는
max_replication_slots과 wal_level 파라미터를 확인해야 합니다.max_replication_slots파라미터는 PostgreSQL이 사용할 수 있는 Replication Slot의 개수를 지정할 수 있으며, 최소 Standby Server 개수만큼 지정해야 합니다.
Main Server의 내용을 복제하는데 pg_basebackup 등을 사용할 경우 Standby Server의 수 + 1 로 설정해야 합니다.(선택사항)
wal_level파라미터는 WAL 파일에 기록되는 양을 제어하는 파라미터로 기본값replica이며 Physical Replication Slot을 사용합니다.logical로 사용하는 경우 Logical Replication Slot을 사용합니다.
max_replication_slots은 PostgreSQL 10 버전부터 기본값이 10입니다. PostgreSQL 9.6 버전까지는 기본값이 0입니다.max_replication_slots < 1로 설정되어 있을 경우 Replication Slot은 생성되지 않습니다.
함께 보면 좋은 아티클
