Avoiding auto-freezing
In the life cycle of a row, there are two routes that a row can take in PostgreSQL – a row version dies and needs to be removed by VACUUM
, or a row version gets old enough and needs to be frozen, a task that is also performed by the VACUUM
process. The removal of dead rows is easy to understand, while the second seems strange and surprising because many PostgreSQL users will not be familiar with the concept of freezing. Freezing is necessary for the proper operation of PostgreSQL’s Multiversion Concurrency Control (MVCC) for the following reason.
PostgreSQL uses internal transaction identifiers that are 4 bytes long, so we only have 232 transaction IDs (about 4 billion). PostgreSQL starts again from the beginning when that wraps around, circularly allocating new identifiers. The reason we do this is that moving to an 8-byte identifier has various other negative effects and costs that we would rather not pay for, so we keep the 4-byte transaction...