18.5. Write Ahead 로그

이 설정의 조정에 대한 자세한 내용은 29.4절을 참조 바란다.

18.5.1. 설정

wal_level (enum)

wal_level은 WAL에 기록되는 정보의 양을 결정한다. 기본값은 충돌 또는 즉시 셧다운으로부터 복구하기 위해 필요한 정보만 기록하는 minimal이다. archive는 WAL 아카이브에 필요한 로깅만 추가한다. hot_standby는 대기 서버에서 읽기 전용 쿼리에 필요한 정보를 좀 더 추가한다. logical은 논리적 디코딩을 지원하는 데 필요한 정보를 추가한다. 각 레벨에는 모두 저수준에서 로깅된 정보가 포함된다. 이 매개변수는 서버 시작 시에만 설정 가능하다.

minimal 레벨에서, 일부 벌크 실행 WAL 로깅은 안전하게 건너뛸 수 있다. 그러면 실행이 빨라진다(14.4.7절 참조). 이러한 최적화를 적용할 수 있는 실행에는 다음이 포함된다.

CREATE TABLE AS
CREATE INDEX
CLUSTER
COPY 상기는 동일 트랜잭션에서 생성되었거나 또는 레코드가 지워진 테이블에 적용된다.into tables that were created or truncated in the same transaction

그러나 최소 WAL에는 베이스 백업 및 WAL 로그로부터 데이터를 재구성하는 데 필요한 정보가 충분하지 않으므로 WAL 아카이빙(archive_mode) 및 스트리밍 복제를 하려면 archive 이상을 사용해야 한다.

hot_standby 레벨에서 archive와 동일한 정보 및 WAL로부터 실행 트랜잭션의 상태 재구성에 필요한 정보가 로깅된다. 대기 서버에서 읽기 전용 쿼리를 사용하려면, 운영 서버에서 wal_levelhot_standby 이상으로 설정하고 hot_standby는 대기 서버에서 활성화해야 한다. hot_standbyarchive 레벨 사용시 측정 가능한 성능 차이는 거의 없는 것으로 생각되므로 운영상 눈에 띄는 변화가 있을 경우 피드백을 주기 바란다.

logical 레벨에서 hot_standby를 사용하는 것과 동일한 정보 및 WAL로부터 논리적 변경 집합을 사용하는 데 필요한 정보가 로깅된다. logical 레벨을 사용하면 WAL 볼륨이 증가한다. 특히 여러 개의 테이블을 REPLICA IDENTITY FULL로 환경 설정하고 UPDATEDELETE 문을 여러 개 실행하는 경우 그렇다.

fsync (boolean)

이 매개변수가 on인 경우 PostgreSQL 서버는 업데이트가 물리적으로 디스크에 기록되었는지를 fsync() 시스템 호출 또는 상응하는 다양한 메서드(wal_sync_method 참조)를 사용하여 확인하려고 한다. 이로써 운영 체제 또는 하드웨어 충돌 후에 데이터베이스 클러스터를 일정한 상태로 복구할 수 있다.

fsync를 해제하는 것은 성능상 장점이 있지만, 결과적으로는 정전 또는 시스템 충돌의 경우에 데이터 손상이 복구 불가능할 수 있다. 따라서 외부 데이터로 전체 데이터베이스를 손쉽게 재생성할 수 있는 경우에만 fsync를 해제하는 것이 바람직하다.

데이터베이스를 사용한 후에 데이터베이스를 폐기 및 재생성하는 데이터 일괄 처리용이거나, 빈번하게 재생성되고 장애처리(failover)용으로 사용되지 않는 읽기 전용 데이터베이스 클론인 경우에 백업 파일로부터 새 데이터베이스 클러스터를 처음 로딩하는 것을 fsync의 해제가 안전한 환경의 예시로 볼 수 있다. 고성능 하드웨어 단독으로는 fsync를 해제하는 합당한 이유가 될 수 없다.

fsync를 해제했다가 다시 설정하는 경우 복구 신뢰도를 위해 커널에서 변경된 모든 버퍼를 내구성이 좋은 저장소로 강제 이동하는 것이 필요하다. 이것은 클러스터가 셧다운 중이거나 fsync가 on일 때 initdb --sync-only를 실행하거나, sync를 실행하거나, 파일 시스템의 마운트를 해제하거나, 서버를 리부팅함으로써 가능하다.

여러 가지 상황에서 중요하지 않은 트랜잭션에 대해 synchronous_commit를 해제하면 데이터 충돌 위험 없이 fsync를 해제함으로써 잠재적인 성능상 장점을 다수 얻을 수 있다.

fsyncpostgresql.conf 파일 또는 서버 커맨드 라인에서만 설정할 수 있다. 이 매개변수를 해제할 경우 full_page_writes의 해제도 고려해야 한다.

synchronous_commit (enum)

명령이 "success" 표시를 클라이언트에 리턴하기 전에 WAL 레코드가 디스크에 기록될 때까지 트랜잭션 커밋이 기다릴지 여부를 지정한다. 유효 값은 onremote_write, local, off이다. 기본값 및 안전 설정은 on이다. off인 경우 success표시가 클라이언트에 전달되는 시간과 서버 충돌 없이 트랜잭션이 정말로 안전하다는 것이 보장되는 시간 사이에 지연이 생길 수 있다. (최대 지연은 wal_writer_delay의 3배이다.) fsync와 달리, 이 매개변수를 off로 설정하면 데이터베이스 불일치 위험이 발생하지 않는다. 운영 체제 또는 데이터베이스 충돌은 이른바 최근에 커밋된 트랜잭션이 일부 분실되는 결과가 발생하지만 데이터베이스 상태는 해당 트랜잭션이 깔끔하게 중단된 것과 같다. 따라서, 트랜잭션 영속성에 대해 정확한 확실성보다는 성능이 더 중요한 경우에 synchronous_commit를 해제하는 것이 유용한 대안일 수 있다. 자세한 내용은 29.3절을 참조 바란다.

synchronous_standby_names가 설정되면, 트랜잭션의 WAL 레코드가 대기 서버로 복제될 때까지 트랜잭션 커밋이 기다릴지의 여부를 이 매개변수로도 제어한다. on으로 설정되면, 트랜잭션의 커밋 레코드를 수신했고 디스크에 쓰기 되었다는 응답이 현재의 동기 대기 서버로부터 올 때까지 커밋이 대기한다. 이것은 운영 서버 및 대기 서버 양쪽에서 데이터베이스 저장소의 손상이 없는 경우에 트랜잭션이 분실되지 않았음을 보장한다. remote_write로 설정되면, 트랜잭션의 커밋 레코드를 수신했고 대기 서버의 운영 체제에 쓰기 되었지만, 대기 서버의 안정된 저장소에 데이터가 도착했는지는 확실하지 않다는 응답이 현재의 동기 대기 서버로부터 올 때까지 커밋이 대기한다. 데이터 보존을 위해서는 PostgreSQL의 대기 서버 인스턴스가 충돌한 경우에도 이 설정으로 충분하지만 대기 서버가 운영 체제 수준에서 충돌이 발생한 경우는 그렇지 않다.

동기 복제를 사용 중인 경우 일반적으로 디스크에 로컬로 쓰기 되도록 기다리거나, WAL 레코드의 복제를 기다리거나, 트랜잭션이 비동기적으로 커밋되게 하는 것이 합리적이다. 그러나, local 설정은 디스크에 로컬로 쓰기 되도록 기다리지만 동기 복제는 기다리지 않는 트랜잭션에 사용할 수 있다. synchronous_standby_names를 설정하지 않으면 onremote_write, local 설정 모두 동일한 동기화 레벨을 제공하며 트랜잭션 커밋은 로컬로 디스크에 쓰기만을 기다린다.

이 매개변수는 언제든 변경할 수 있다. 모든 트랜잭션의 동작은 사실상 커밋되었을 때의 설정에 따라 결정된다. 따라서 일부 트랜잭션 커밋은 동기적으로, 그 외에는 비동기적으로 만드는 것이 가능하고 유용하다. 예를 들면, 기본값이 반대인 경우 다중 문 트랜잭션 커밋 하나를 비동기적으로 만들려면 트랜잭션 내에서 SET LOCAL synchronous_commit TO OFF를 실행해야 한다.

wal_sync_method (enum)

디스크에 WAL을 강제로 업데이트할 때 사용되는 메서드. fsync가 off인 경우 WAL 파일을 일절 강제로 업데이트하지 않기 때문에 이 설정은 무관하다. 가능한 값은 다음과 같다.

  • open_datasync (open() 옵션 O_DSYNC를 사용하여 WAL 파일 쓰기)

  • fdatasync (커밋마다 fdatasync() 호출)

  • fsync (커밋마다 fsync() 호출)

  • fsync_writethrough (커밋마다 fsync() 호출, 모든 디스크 쓰기 캐시에서 write-through 강제)

  • open_sync (open() 옵션 O_SYNC를 사용하여 WAL 파일 쓰기)

open_* 옵션도 필요 시 O_DIRECT를 사용한다. 이와 같은 선택이 항상 모든 플랫폼에서 가능한 것은 아니다. 기본값은 플랫폼에서 지원되는 위의 목록에서 첫 번째 메서드이다. 단, Linux에서는 fdatasync가 기본값이다. 기본값이 반드시 이상적인 것은 아니다. 충돌로부터 안전한 환경 설정을 만들거나 성능을 최적화하려면 값을 변경하거나 시스템 환경 설정의 다른 측면을 변경하는 것이 필요할 수도 있다. 이러한 측면은 29.1절에서 다룬다. 이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다.

full_page_writes (boolean)

이 매개변수가 on이면, PostgreSQL 서버는 checkpoint 이후의 각 디스크 페이지를 처음 수정하는 도중에 해당 페이지의 전체 내용을 WAL에 기록한다. 이것은, 운영 체제 충돌 시 진행 중인 페이지 쓰기가 부분적으로만 완료되어 디스크 상의 페이지에 옛날 데이터와 새 데이터가 공존할 수 있기 때문에 필요하다. 일반적으로 WAL에 저장되는 행 수준(row-level) 변경 데이터는 충돌 후 복구 중에 그러한 페이지를 완전히 복구하는 데 충분하지 않다. 전체 페이지 이미지를 저장하면 페이지의 올바른 복구가 보장되지만 WAL에 기록해야 하는 데이터량의 증가를 감수해야 한다. (WAL 리플레이는 항상 checkpoint에서 시작되므로 checkpoint 이후의 페이지별 첫 번째 변경 중에 해도 충분하다. 그러므로 전체 페이지 쓰기 비용을 줄이는 한 가지 방법은 checkpoint 간격 매개변수를 늘리는 것이다.)

이 매개변수를 해제하면 정상적인 운영 속도가 빨라지지만 시스템 장애 발생 시 손상된 데이터가 복구 불가능하게 되거나 데이터 손상이 드러나지 않을 수 있다. 이러한 위험은 규모는 작지만 fsync을 해제했을 때와 유사하며, 해당 매개변수에 대해 권장되는 것과 환경이 동일할 때만 해제해야 한다.

이 매개변수를 해제하는 것은 point-in-time recovery(PITR)용 WAL 아카이빙의 사용에는 영향을 미치지 않는다(24.3절 참조).

이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다. 기본값은 on이다.

wal_log_hints (boolean)

이 매개변수가 on이면, PostgreSQL 서버는 checkpoint 이후의 각 디스크 페이지를 처음 수정하는 도중에, 소위 힌트 비트(hint bits)의 중요하지 않은 수정에 대해서도 해당 페이지의 전체 내용을 WAL에 기록한다.

데이터 체크섬이 사용으로 설정되면 힌트 비트(hint bit) 업데이트가 항상 WAL 로깅되고 이 설정은 무시된다. 데이터베이스에서 데이터 체크섬이 사용으로 설정된 경우 이 설정을 사용하여 WAL 로깅이 추가로 얼마나 발생하는지 테스트할 수 있다.

이 매개변수는 서버 시작 시에만 설정 가능하다. 기본값은 off이다.

wal_compression (boolean)

이 설정값을 on 으로 지정하면, PostgreSQL 서버는 full_page_writes 설정을 on 으로 지정했거나, 베이스 백업을 할 때, WAL에서 페이지 전체 이미지를 압축한다. 이 압축된 내용은 WAL 재실행할 경우에 압축을 풀어서 반영한다. 기본값은 off다. 이 설정은 슈퍼유저만 변경할 수 있다.

이 설정은 자료 손실 없이 WAL 크기를 줄이는데 사용할 수 있지만, 압축과 그 해제 작업 비용이 추가로 발생된다.

wal_buffers (integer)

WAL 데이터에 사용되고 아직 디스크에 기록되지 않은 공유 메모리의 합계. 기본 설정 -1은 shared_buffers의 1/32번째(약 3%)와 동일하게 선택한다. 64kB 이상, WAL 세그먼트 1개 크기 이하여야 하며, 일반적으로 16MB이다. 이 값은 자동 선택이 너무 크거나 작은 경우에 직접 선택할 수 있으며, 32kB 미만의 양의 값은 32kB로 처리된다. 이 매개변수는 서버 시작 시에만 설정 가능하다.

WAL 버퍼의 내용은 모든 트랜잭션 커밋마다 디스크에 쓰기 되므로 극단적으로 큰 값은 별다른 장점이 없을 가능성이 높다. 그러나, 이 값을 최소한 몇 메가바이트로 설정하면 여러 클라이언트가 한꺼번에 커밋함으로써 busy한 서버의 쓰기 성능이 개선된다. 기본 설정 -1에 의해 선택된 자동 튜닝은 대부분의 경우 합당한 결과를 주어야 한다.

wal_writer_delay (integer)

WAL writer의 작업 라운드 사이의 지연을 지정한다. 각 라운드에서 writer는 WAL을 디스크에 기록한다. 그런 다음, wal_writer_delay밀리초 동안 슬립한 다음, 반복한다. 기본값은 200밀리초이다(200ms). 다수의 시스템에서 슬립 지연의 효율적인 설정은 10밀리초이다. wal_writer_delay를 10의 배수가 아닌 다른 값으로 설정하면 10의 배수로 값을 올림하여 설정한 것과 결과가 동일하다. 이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다.

commit_delay (integer)

commit_delay는 WAL 쓰기를 초기화하기 전에 측정된 시간 지연을 마이크로초 단위로 추가한다. 이것은 시스템 로드가 충분히 커서 주어진 간격 내에 트랜잭션을 추가로 커밋할 준비가 된 경우 단일 WAL 쓰기를 통해 대량의 트랜잭션이 커밋되게 함으로써 그룹 커밋 처리량을 개선할 수 있다. 그러나 이것은 WAL 쓰기별로 대기 시간을 최대 commit_delay 마이크로초까지 늘리기도 한다. 커밋할 준비가 된 트랜잭션이 없을 경우 지연은 낭비되는 시간이므로 최소한 commit_siblings인 경우만 지연이 수행된다. 쓰기가 곧 시작되는 경우 다른 트랜잭션이 작동된다. 또한 fsync가 비활성화되면 지연이 수행되지 않는다. 기본 commit_delay는 0이다(지연 없음). 수퍼유저만 이 설정을 변경할 수 있다.

9.3 이전의 PostgreSQL 릴리스에서 commit_delay는 동작이 다르고 효과도 떨어진다. 이것은 모든 WAL 쓰기가 아닌 커밋에만 영향을 주었고 WAL 쓰기가 곧 완료된 경우에도 환경 설정된 지연 시간 동안 대기했다. PostgreSQL 9.3 초반에, 쓸 준비가 된 첫 번째 프로세스는 환경 설정된 시간 간격을 기다리고, 후속 프로세스는 선행 프로세스의 쓰기 연산이 끝날 때까지 대기한다.

commit_siblings (integer)

commit_delay 지연을 수행하기 전에 필요한 동시 개방 트랜잭션의 최소 수. 값이 크면, 지연 간격 중에 커밋 준비가 된 다른 트랜잭션이 최소한 하나 이상일 확률이 높다. 기본값은 5개 트랜잭션이다.

18.5.2. 체크포인트

checkpoint_timeout (integer)

자동 WAL checkpoints 간의 최대 시간. 초 단위. 기본값은 5분이다(5min). 이 매개변수를 늘리면 충돌 복구에 필요한 시간을 늘릴 수 있다. 이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다.

checkpoint_completion_target (floating point)

checkpoints 간 총 시간 분할로써, checkpoints 완료 목표를 지정한다. 기본값은 0.5이다. 이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다.

checkpoint_warning (integer)

checkpoint 세그먼트 파일을 채움으로써 checkpoints가 여기에 지정된 초 수보다 근접해서 발생한 경우 서버 로그에 메시지를 기록한다(checkpoint_segments를 증가시키는 것이 권장됨). 기본값은 30초이다(30s). 0은 경고를 비활성화한다. checkpoint_timeoutcheckpoint_warning 미만이면 경고가 발생하지 않는다. 이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다.

max_wal_size (integer)

체크포인트 작업을 자동으로 진행할 WAL 최대 크기. 이 값은 유연한 최대값이다. 갑자기 많이 쌓이는 과도한 자료량이나, archive_command 작업이 계속 실패하고 있거나, wal_keep_segments 설정값을 크게 지정한 경우에는 언제든지 WAL 총 크기는 이 값을 초과할 수 있다. 기본값은 1 GB이다. 이 값이 커지면, 서버가 비정상적으로 종료된 뒤 다시 시작하려고 할 때 진행하는 트랜잭션 로그 기반 복구 작업 시간이 길어 진다. 이 설정은 postgresql.conf에서 지정하거나, 서버 실행 명령행 옵션으로만 지정할 수 있다.

min_wal_size (integer)

WAL 조각 파일들은 더 이상 보관할 필요가 없어지면, 지워지는 것이 아니라, 앞으로 사용될 파일로 그 이름을 바꾼다. 이 설정은 이렇게 남겨두는 WAL 최소값을 지정한다. 앞에서 설명한 것 처럼 배치 작업 같은 것으로 갑자기 많은 트랜잭션 로그가 쌓이게 되면 이 값 기준으로 다시 적정 수준의 디스크 공간을 사용하게 된다. 기본값은 80 MB이다. 이 설정은 postgresql.conf에서 지정하거나, 서버 실행 명령행 옵션으로만 지정할 수 있다.

18.5.3. 아카이브

archive_mode (boolean)

archive_mode을 사용하는 것으로 설정하면 완료된 WAL 세그먼트가 archive_command 설정에 의해 아카이브 저장소로 전달된다. archive_modearchive_command는 별개의 변수이므로 아카이빙 모드를 해지하지 않고도 archive_command를 변경할 수 있다. 이 매개변수는 서버 시작 시에만 설정 가능하다. wal_levelminimal로 설정된 경우 archive_mode를 사용으로 설정할 수 없다.

archive_command (string)

완료된 WAL 파일 세그먼트를 아카이브하기 위해 실행하는 로컬 쉘 명령. string에서 %p는 아카이브할 파일의 경로명으로 대체되고 %f는 파일명으로만 대체된다. (경로명은 서버(예: 클러스터의 데이터 디렉터리)의 작업 디렉터리에 상대적이다.) % 문자를 명령에 포함하려면 %%를 사용해야 한다. 성공한 경우에만 명령이 0 종료(zero exit) 상태를 리턴하는 것이 중요하다. 자세한 내용은 24.3.1절을 참조 바란다.

이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다. archive_mode가 서버 시작 시에 활성화되지 않은 경우 무시된다. archive_mode가 사용으로 설정된 상태에서 archive_command의 string이 비어 있는 경우(기본값) WAL 아카이빙이 일시적으로 비활성화되지만 서버는 명령이 곧 제시될 것이라는 기대를 갖고 WAL 세그먼트 파일을 계속 누적한다. archive_command가 true만 리턴하는 명령으로 설정하면(예: /bin/true)(Windows에서 REM), 아카이빙이 효율적으로 비활성화되지만, 아카이브 복구에 필요한 WAL 파일의 체인이 끊어지므로 특이한 환경에서만 사용되어야 한다.

archive_timeout (integer)

archive_command는 완료된 WAL 세그먼트를 호출만 한다. 그러므로, 서버에서는 WAL 트래픽이 발생되지 않아서(따라서 여유 시간이 있음) 트랜잭션의 완료 및 아카이브 저장소에서 안전한 기록 사이에 긴 지연이 발생할 수 있다. 데이터가 아카이브되지 않은 채로 방치되지 않게 하기 위해 서버가 새 WAL 세그먼트 파일로 주기적으로 전환되도록 archive_timeout을 설정할 수 있다. 이 매개변수가 0보다 큰 경우 마지막 세그먼트 파일로 전환한 이후로 여기서 지정된 초 시간을 경과할 때마다, 그리고 단일 checkpoint를 비롯한 데이터베이스 작업이 있을 때마다 서버는 새 세그먼트 파일로 전환한다. (checkpoint_timeout을 늘리면 유휴 시스템에서 불필요한 checkpoints가 줄어든다.) 강제 전환 때문에 일찌감치 폐쇄된 아카이브된 파일의 길이는 완전한 전체 파일과 동일하다는 점에 유의해야 한다. 따라서, archive_timeout를 매우 짧게 하는 것은 아카이브 저장소를 부풀게 하므로 현명하지 못하다. archive_timeout을 1분 정도로 설정하는 것이 일반적으로 합당하다. 데이터를 마스터 서버로 빠르게 복사하려면 아카이빙 대신 streaming replication의 사용을 고려해야 한다. 이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다.