dev.to

PostgreSQL 19's data checksums can now be switched on without stopping the server

PostgreSQL 19, 서버를 멈추지 않고 데이터 체크섬을 켭니다

PostgreSQL 19에는 서버를 계속 운영하면서 데이터 체크섬을 켜거나 끄는 SQL 함수가 추가됩니다. 테스트에서는 오프라인 변환보다 작업 시간이 길었지만 서비스 중단은 피했고, 체크섬을 켜면 손상된 페이지를 읽을 때 오류를 확인했습니다.

AI 요약

PostgreSQL 19 베타 3에는 서버를 멈추지 않고 기존 클러스터의 데이터 체크섬 상태를 바꾸는 함수가 추가됩니다. 작성자는 같은 위치의 데이터 16바이트를 손상시킨 뒤 체크섬을 켠 클러스터와 끈 클러스터를 비교했습니다. 손상된 페이지를 실제로 읽는 쿼리에서 체크섬을 켠 쪽은 블록 번호를 담은 오류를 냈지만, 체크섬을 끈 쪽은 정상처럼 보이는 결과를 반환했습니다.

서버를 운영하면서 체크섬 변환

PostgreSQL 19 이전에는 체크섬을 켜거나 끄려면 서버를 중단한 뒤 pg_checksums 도구를 실행해야 했습니다. 이 도구는 데이터 디렉터리의 페이지를 직접 다시 쓰기 때문입니다. PostgreSQL 19는 pg_enable_data_checksums()와 pg_disable_data_checksums() SQL 함수를 추가합니다. 함수는 백그라운드 워커를 실행해 모든 데이터베이스의 테이블 페이지를 차례로 처리하며, 작업 중에도 일반 쿼리를 받습니다.

새 클러스터의 기본값도 바뀝니다. 작성자가 postgres:19beta3 이미지에서 옵션 없이 initdb를 실행하자 데이터 체크섬이 활성화됐습니다. 문서도 PostgreSQL 19부터 기본 활성화라고 명시합니다. 필요하면 --no-data-checksums로 끌 수 있습니다. 이전 버전에서는 생성 시 체크섬을 직접 선택하거나, 나중에 오프라인 변환을 거쳐야 했습니다.

처리 시간과 서비스 영향

작성자는 pgbench -i -s 50으로 약 756MB, 98,695페이지 규모의 데이터를 만들고 변환 시간을 비교했습니다. 서버를 멈추는 기존 방식은 체크섬 활성화에 가장 빠른 기준 1.28초, 비활성화에 0.99초가 걸렸습니다. 변환 중 연결을 받지 못하므로 이 시간이 그대로 서비스 중단 시간입니다.

온라인 함수는 활성화에 약 2.8초, 비활성화에 약 1.1초에서 1.2초가 걸렸습니다. 함수 호출 자체는 약 0.12~0.14초 만에 반환했습니다. 실제 작업은 백그라운드에서 진행되며, SHOW data_checksums는 off, inprogress-on, on, inprogress-off 상태를 표시합니다. pg_stat_progress_data_checksums 뷰에서는 처리 단계와 전체 관계·블록 수, 완료 수를 확인합니다.

pgbench를 20초간 실행한 비교에서는 변환이 없을 때 초당 3,033.6건, 제한 없는 활성화 중 3,345.9건, 작업량 제한을 건 활성화 중 3,104.8건을 처리했습니다. 이 환경에서는 눈에 띄는 성능 저하가 없었습니다. 다만 로컬 오버레이 스토리지를 쓰는 여유 있는 컨테이너 테스트라서, 작성자는 디스크 대역폭을 두고 경쟁하는 운영 환경까지 같은 결과라고 주장하지 않습니다.

I/O 제한과 WAL 비용

cost_delay=20, cost_limit=100으로 변환 속도를 제한하자 46초 동안 82,525페이지 중 10,516페이지, 약 13%를 처리했습니다. 이 속도라면 전체 작업에 약 6분이 걸립니다. 제한 없이 처리할 때의 약 2.8초보다 훨씬 길지만, 전경 쿼리에 미치는 영향을 줄이는 조절 수단입니다.

체크섬을 켤 때는 776MB 데이터베이스에서 약 799MB의 WAL이 생성됐습니다. 모든 페이지를 변경하고 WAL에도 기록해 대기 서버가 같은 변경을 받도록 하기 때문입니다. 끌 때 생성된 WAL은 512바이트였습니다. 두 함수 모두 슈퍼유저 권한이 필요합니다. 활성화 작업 중 함수를 다시 호출하면 새 워커 없이 조용히 끝납니다. 반면 작업 중 비활성화 함수를 호출하면 활성화가 진행 중이어도 방향을 즉시 바꿉니다. 작성자는 이 동작이 확인한 함수 문서에 설명되지 않았다고 덧붙입니다.

손상 탐지와 테스트의 한계

손상된 페이지를 검사할 때 쿼리 선택도 중요합니다. 작성자의 첫 SELECT count(*)는 인덱스만 읽는 인덱스 전용 스캔으로 처리돼 손상을 발견하지 못했습니다. 인덱스에 없는 열을 합산해 실제 힙 페이지를 읽게 하자, 체크섬 활성화 상태에서는 block 24의 페이지 오류가 발생했고 pg_stat_database의 checksum_failures와 checksum_last_failure도 갱신됐습니다. 체크섬을 끈 상태에서는 같은 손상에도 오류가 없었습니다.

체크섬은 디스크에서 읽은 페이지를 버퍼로 가져올 때 검사합니다. 쿼리가 손상된 페이지를 읽지 않으면 탐지도 일어나지 않습니다. 작성자는 운영 환경에서 pg_stat_database의 실패 횟수와 마지막 실패 시각을 모니터링할 수 있다고 설명합니다. 비활성화 시간은 실행마다 약 0.1~1.2초로 차이가 났으며, 작성자는 활성 백엔드가 검증을 멈출 때까지 기다리는 조건이 영향을 줬을 가능성을 제시합니다.

이 기능은 PostgreSQL 19에 포함되므로 이전 버전의 클러스터에는 적용되지 않습니다. PostgreSQL 19 정식 버전은 2026년 9~10월경 출시 예정이며, 그 전까지 이전 버전은 오프라인 도구를 사용하거나 논리 덤프 후 다시 적재해야 합니다.

원문: dev.to / 번역·요약: Trawling