19.5. Write Ahead 로그

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

19.5.1. 설정

wal_level (enum)

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

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

CREATE TABLE AS
CREATE INDEX
CLUSTER
동일 트랜잭션에서 만들어지고 삭제된 테이블 대상 COPY

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

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

9.6 이전 버전에서는 이 설정값으로 archive, hot_standby 두 값을 쓸 수 있었다. 하위 호환성을 위에 이 설정값을 사용할 수 있으며, 이들은 모두 replica로 처리된다.

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 값이 쓰여질 때까지 트랜잭션 커밋을 대기시킬 것인지 여부를 설정하는 변수이다. on, remote_apply, remote_write, local, off 중 하나로 설정할 수 있고, 기본값은 on이다. off로 설정할 경우 클라이언트에게 success를 반환하는 시점과 서버 crash에 대해 트랜잭션의 안전이 보장되는 시점 사이에 지연이 발생할 수 있다. (최장 지연은 wal_writer_delay의 3배) 하지만 fsync 설정과 달리 이 설정값을 off로 설정해도 DB 불일치가 발생하진 않는다: OS나 DB crash로 인해 커밋된 트랜잭션 일부가 손실될 수 있지만, DB는 해당 트랜잭션이 정상적으로 종료된 것과 같은 상태이다. 따라서 트랜잭션의 내구성보다 성능이 우선시되는 경우에 synchronous_commit을 끄면(off) 유용하다. (30.3절 참조)

만약 synchronous_standby_names가 설정되어있다면, 이 설정은 대기 서버로 WAL 값이 복제될 때까지 트랜잭션 커밋을 기다릴 것인지도 제어한다. 값을 on으로 설정하면, 현재 동기화된 대기 서버가 트랜잭션의 커밋 레코드를 받았고, 그것을 디스크에 flush했음을 나타낼 때까지 커밋은 대기한다. 이 경우 대기 서버의 스토리지가 손상되지 않는 한 트랜잭션은 손실되지 않는다. remote_apply로 설정하면, 대기 서버가 트랜잭션의 커밋 레코드를 받고 그것을 적용시켰다는 응답이 올 때까지 커밋은 대기한다. 따라서 대기 서버에서 쿼리를 확인할 수 있다. remote_write로 설정된 경우, 대기 서버가 트랜잭션의 커밋 레코드를 받아서 OS에 기록했다는 응답이 올 때까지 커밋은 대기한다. 이 설정에선 데이터가 아직 스토리지에 도달하지 않았기 때문에 대기 서버의 DB 인스턴스가 죽더라도 데이터는 보존된다. 하지만 대기 서버의 OS 레벨에서 문제가 발생한 경우엔 데이터가 보존되지 않는다. 마지막으로, local로 설정하면 로컬에선 디스크로 flush될 때까지 기다리지만 복제에선 기다리지 않는다. 바람직하진 않은 설정이지만 완전성을 위해 제공하고 있다.

synchronous_standby_names 값이 없을 경우엔 on, remote_apply, remote_write, local 모두 같은 동기화 레벨을 갖는다: 트랜잭션 커밋은 로컬에서 디스크로 flush하는 작업만 대기한다.

이 설정은 아무 때나 변경 가능하다; 한 트랜잭션에 대한 동작은 트랜잭션이 커밋될 때 적용되는 설정에 따른다. 따라서 일부 트랜잭션은 동기적으로, 다른 트랜잭션은 비동기적으로 커밋하는 것이 가능하다. 예를 들어, 기본 값이 반대일 때 비동기적으로 단일 multistatement 트랜잭션을 커밋하려면 세션 단에서 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가 기본값이다. 기본값이 반드시 이상적인 것은 아니다. 충돌로부터 안전한 환경 설정을 만들거나 성능을 최적화하려면 값을 변경하거나 시스템 환경 설정의 다른 측면을 변경하는 것이 필요할 수도 있다. 이러한 측면은 30.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 아카이빙의 사용에는 영향을 미치지 않는다(25.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)

Specifies how often the WAL writer flushes WAL. After flushing WAL it sleeps for wal_writer_delay milliseconds, unless woken up by an asynchronously committing transaction. If the last flush happened less than wal_writer_delay milliseconds ago and less than wal_writer_flush_after bytes of WAL have been produced since, then WAL is only written to the operating system, not flushed to disk. The default value is 200 milliseconds (200ms). Note that on many systems, the effective resolution of sleep delays is 10 milliseconds; setting wal_writer_delay to a value that is not a multiple of 10 might have the same results as setting it to the next higher multiple of 10. 이 매개변수는 postgresql.conf 파일 또는 서버 커맨드 라인에서만 설정 가능하다.

wal_writer_flush_after (integer)

Specifies how often the WAL writer flushes WAL. If the last flush happened less than wal_writer_delay milliseconds ago and less than wal_writer_flush_after bytes of WAL have been produced since, then WAL is only written to the operating system, not flushed to disk. If wal_writer_flush_after is set to 0 then WAL data is flushed immediately. The default is 1MB. 이 매개변수는 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개 트랜잭션이다.

19.5.2. 체크포인트

checkpoint_timeout (integer)

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

checkpoint_completion_target (floating point)

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

checkpoint_flush_after (integer)

Whenever more than checkpoint_flush_after bytes have been written while performing a checkpoint, attempt to force the OS to issue these writes to the underlying storage. Doing so will limit the amount of dirty data in the kernel's page cache, reducing the likelihood of stalls when an fsync is issued at the end of the checkpoint, or when the OS writes data back in larger batches in the background. Often that will result in greatly reduced transaction latency, but there also are some cases, especially with workloads that are bigger than shared_buffers, but smaller than the OS's page cache, where performance might degrade. This setting may have no effect on some platforms. The valid range is between 0, which disables controlled writeback, and 2MB. The default is 256kB on Linux, 0 elsewhere. (If BLCKSZ is not 8kB, the default and maximum values scale proportionally to it.) This parameter can only be set in the postgresql.conf file or on the server command line.

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에서 지정하거나, 서버 실행 명령행 옵션으로만 지정할 수 있다.

19.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) 상태를 리턴하는 것이 중요하다. 자세한 내용은 25.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 파일 또는 서버 커맨드 라인에서만 설정 가능하다.