29.5. WAL 인터널

WAL은 자동으로 활성화된다. WAL 로그에 대한 디스크 공간 요구사항을 맞춰야 할 때 및 필수 튜닝이 완료되었을 때 외에는 관리자의 개입이 불필요하다(29.4절 참조).

WAL records are appended to the WAL logs as each new record is written. The insert position is described by a Log Sequence Number (LSN) that is a byte offset into the logs, increasing monotonically with each new record. LSN values are returned as the datatype pg_lsn. Values can be compared to calculate the volume of WAL data that separates them, so they are used to measure the progress of replication and recovery.

WAL logs are stored in the directory pg_wal under the data directory, as a set of segment files, normally each 16 MB in size (but the size can be changed by altering the --wal-segsize initdb option). Each segment is divided into pages, normally 8 kB each (this size can be changed via the --with-wal-blocksize configure option). The log record headers are described in access/xlogrecord.h; the record content is dependent on the type of event that is being logged. Segment files are given ever-increasing numbers as names, starting at 000000010000000000000001. The numbers do not wrap, but it will take a very, very long time to exhaust the available stock of numbers.

로그가 메인 데이터베이스 파일이 아닌 다른 디스크에 위치한 경우에 이것은 장점이 된다. 서버가 종료된 상태에서 pg_wal 디렉터리를 다른 위치로 옮기고, 메인 데이터 디렉터리의 원래 위치로부터 새 위치로 심볼릭 링크를 생성하면 된다.

WAL의 목적은 데이터베이스 레코드가 변경되기 전에 로그가 기록되도록 하는 것이지만, 사실은 데이터를 캐싱만하고 디스크에 미처 저장하지 못한 경우 디스크 드라이브가 커널에 쓰기를 성공했단 내용을 잘못 리포트해 엉망이 될 수 있다. 이러한 상황에서 정전이 발생하면 복구 불가능한 데이터 손상이 발생하게 된다. 관리자는 PostgreSQLWAL 로그 파일이 저장되는 디스크가 이런 잘못된 리포트를 하지 않도록 해야 한다. (29.1절 참조.)

checkpoint가 설정되고 로그가 쓰기된 후 checkpoint의 위치는 pg_control 파일에 저장된다. 그러므로, 복구 시작 시 서버는 먼저 pg_control을 읽은 다음, checkpoint 레코드를 읽는다. 그러고 나서 chekcpoint 레코드에 표시된 로그 위치에서 순방향으로 스캔하여 REDO 명령을 수행한다. 데이터 페이지의 전체 내용은 checkpoint 이후의 첫 번째 페이지 수정에 대한 로그에 저장되므로 (full_page_writes는 비활성화되었다고 가정) checkpoint 이후의 모든 페이지 변경은 일관된 상태로 복원된다.

pg_control가 손상된 경우를 처리하려면 최신 checkpoint를 찾기 위해 역순(가장 최신- 가장 과거 순)으로 기존 로그 세그먼트를 스캐닝 해봐야 한다. 이는 아직 구현되지 않았다. pg_control은 충분히 작아서(디스크 페이지 1개 미만) partial-write 문제에 해당되지 않으며, 현재까지, pg_control 자체가 읽지 못하는 것만으로 데이터베이스 오류가 난 적은 없었다. 따라서, 이론적으론 고쳐야 할 부분이지만 pg_control이 실제로 문제가 되는 것은 아니다.