9.2. Transaction Log and WAL Segment Files
Logically, PostgreSQL writes XLOG records into a virtual file with an 8-byte address space (16 Exabytes).
The transaction log capacity is effectively unlimited. While 8 bytes of address space is vast, managing a single file of this size is impossible. Therefore, PostgreSQL divides the transaction log into smaller files, typically 16 megabytes each. Each file is known as a WAL segment. See Figure 9.6.
In versions 11 or later, the size of a WAL segment file is configurable via the –wal-segsize option when the PostgreSQL cluster is created using the initdb command.
Figure 9.6. Transaction log and WAL segment files
The WAL segment filename is a 24-digit hexadecimal number. The naming rule is as follows:
$$ \begin{align} \text{WAL segment file name} = \text{timelineId} + (\text{uint32}) \frac{\text{LSN}-1}{16\text{M}*256} + ( \text{uint32})\left(\frac{\text{LSN}-1}{16\text{M}}\right) % 256 \end{align} $$
PostgreSQL’s WAL utilizes the concept of a timelineId (a 4-byte unsigned integer) for Point-in-Time Recovery (PITR), which is described in Chapter 10.
However, the timelineId remains fixed at 0x00000001 in this chapter to simplify the following descriptions.
The first WAL segment file is 000000010000000000000001. When XLOG records fill the first file, PostgreSQL provides the second file: 000000010000000000000002. Files are used in ascending order. After 0000000100000000000000FF is full, the file provided is 000000010000000100000000. In this way, the middle 8-digit number increases by one whenever the last 2 digits carry over.
Similarly, after 0000000100000001000000FF is full, PostgreSQL provides 000000010000000200000000, and so on.
The built-in function pg_xlogfile_name (versions 9.6 or earlier) or pg_walfile_name (versions 10 or later) identifies the WAL segment file name containing a specified LSN.
An example is shown below:
testdb=# SELECT pg_xlogfile_name('1/00002D3E'); # In versions 10 or later, "SELECT pg_walfile_name('1/00002D3E');"
pg_xlogfile_name
--------------------------
000000010000000100000000
(1 row)