5.10. Required Maintenance Processes

PostgreSQL’s concurrency control mechanism requires the following maintenance processes:

  1. Remove dead tuples and index tuples that point to corresponding dead tuples.
  2. Remove unnecessary parts of the clog.
  3. Freeze old txids.
  4. Update FSM, VM, and the statistics.

The need for the first and second processes have been explained in Sections Section 5.3.2 and Section 5.4.3, respectively. The third process is related to the transaction id wraparound problem, which is briefly described in the following subsection.

In PostgreSQL, VACUUM processing is responsible for these processes, and it is described in Chapter 6.

5.10.1. FREEZE Processing

5.10.1.1. Transaction Wraparound Problem

Assume that tuple Tuple_1 is inserted with a txid of 100, i.e. the t_xmin of Tuple_1 is 100.

The server has been running for a very long period and Tuple_1 has not been modified. The current txid is 2.1 billion + 100 and a SELECT command is executed. At this time, Tuple_1 is visible because txid 100 is in the past. Then, the same SELECT command is executed; thus, the current txid is 2.1 billion + 101. However, Tuple_1 is no longer visible because txid 100 is in the future (Fig. 5.20).

This is the so called transaction wraparound problem in PostgreSQL.

Fig. 5.20. Wraparound problem.
5.10.1.2. Freeze Processing

To deal with this problem, PostgreSQL introduced a concept called frozen txid, and implemented a process called FREEZE.

In PostgreSQL, a frozen txid, which is a special reserved txid 2, is defined such that it is always older than all other txids. In other words, the frozen txid is always inactive and visible.

The freeze process is invoked by the vacuum process. The freeze process scans all table files and rewrites the t_xmin of tuples to the frozen txid(2) if the t_xmin value is older than the current txid minus the vacuum_freeze_min_age (the default is 50 million). This is explained in more detail in Chapter 6.

For example, as can be seen in Fig. 5.21 a), the current txid is 50 million and the freeze process is invoked by the VACUUM command. In this case, the t_xmin of both Tuple_1 and Tuple_2 are rewritten to 2.

In versions 9.4 or later, the XMIN_FROZEN bit is set to the t_infomask field of tuples rather than rewriting the t_xmin of tuples to the frozen txid (Fig. 5.21 b).

Fig. 5.21. Freeze process.