📢 In this post, we look at Age, an extension of the XID concept. We first cover ① what Age is and why it was introduced, then ② what Age means for tables and rows and how the two differ.
What is Age?
Age = Current XID - XID at creation time
When we explained Data Freezing earlier, we said that before the value "Current XID - XID at creation (insert) time" exceeds 2.1 billion, the row must be changed to
Frozen XID to avoid XID wraparound.So to select Data Freezing targets, we needed a way to measure how long ago a row was inserted (created) rather than looking at the XID value itself, and Age was introduced as the concept for this.
Age has the following characteristics.
- Age is measured for DBs, tables, and rows.
- The Age of an object is 1 when it is created.
- The Age of a row is 1 when it is inserted.
- Each Age increases as transactions occur.
- The Age of an object is greater than or equal to the Age of its rows.
- Objects and rows with a high Age become Vacuum targets.
- Age drops after Vacuum runs.
The Age of tables and rows can be calculated with the
age function. The Age calculated this way serves as the reference point for selecting Vacuum targets and for deciding how Vacuum works internally. We will look at the internal behavior that uses Age in more detail later, when we cover Manual Vacuum.Age of tables and rows
Age cannot be separated from XID. Age itself means the difference between the XID at creation time and the Current XID, and for the same reason Age is used in the same places as XID: databases, tables, and rows. Let's start with the Age of a row.
Row Age
The Age of a row can be calculated using
XMIN.In the example above, the XID at insert time is set as
XMIN, and applying the Age function to XMIN gives the Age of the row.The "row" itself is the target of Data Freezing, while the "Age of the row" is the criterion for Data Freezing. As transactions occur after a row is inserted, its Age naturally increases, and when the Age of the row reaches
VACUUM_FREEZE_MIN_AGE, the row becomes a Data Freezing target. The actual Data Freezing then happens during the next Vacuum.📌 vacuum_freeze_min_age
This is the minimum Age of a row that Vacuum will freeze. The default is 50 million (50,000,000).
Before version 9.4, Data Freezing worked by actually changing the
XMIN value to Frozen XID. Starting with version 9.4, instead of changing XMIN directly, it sets the 10th bit of t_infomask to 1.
Let's force Data Freezing with the VACUUM FREEZE command and look at what changes. After running the command, the XMIN value is unchanged, but the t_infomask value has changed.📌 The example above requires the pageinspect extension to be installed.
If you convert that
t_infomask value to bits, you can see that the 10th bit changed from 0 to 1, as shown below, meaning Data Freezing actually happened.Table Age
Now let's look at the Age of a table. The Age of a table can be calculated using
pg_class.relfrozenxid.The Age of an object is greater than or equal to (older than) the Age of its rows.
Unlike rows, tables are not Freezing targets, and they do not need to be. Some may wonder why we need the Age of a table if it is not even a Freezing target. But because of the Age property above, the Age of a table can represent the Age of its rows, and its value lies in serving as an easy way to tell whether any rows need Data Freezing.
In fact, the
relfrozenxid used to calculate a table's Age can also change when certain conditions are met, which can lower the table's Age as well. This condition refers to the point at which the need for Data Freezing has been checked across the entire table, and understanding it requires knowing how Vacuum works in Eager Mode, so we will come back to it when we cover Manual Vacuum.So far, starting with PostgreSQL's MVCC model, we have covered XID-related topics such as Transaction ID and Age. In the next post, we will look at the Visibility Map, which is essential for understanding how Vacuum works.
Related articles
