This article summarizes information I have about this problem. I know that this is not all but I did not find such a summarization anywhere therefore I place it here. Maybe it could help to someone.
- Transaction ID has 32 bits. It means that after ID 2147483648 will be transaction ID reseted.
- There are 2 special IDs: 1 and 2
- ID 1 = BootstrapXID
- ID 2 = FrozenXID
- FrozenXID is special ID
- FrozenXID exists for database (pg_database) and every table (pg_class)
- Freeze is done by “vacuum freeze” command
- Freeze makes this:
- Takes biggest transaction ID (on table, on database), saves it into system catalog table (for table in pg_class, for database in pg_database)
- All XID are then replaced by “2”
- In overrun of XID new XIDs starts with 3
- Database has these parameters for vacuum and autovacuum:
name | setting | unit | short_desc |
autovacuum | off | Starts the autovacuum subprocess. | |
autovacuum_analyze_scale_factor | 0.1 | Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples. | |
autovacuum_analyze_threshold | 50 | Minimum number of tuple inserts, updates or deletes prior to analyze. | |
autovacuum_freeze_max_age | 200000000 | Age at which to autovacuum a table to prevent transaction ID wraparound. | |
autovacuum_max_workers | 3 | Sets the maximum number of simultaneously running autovacuum worker processes. | |
autovacuum_naptime | 60 | s | Time to sleep between autovacuum runs. |
autovacuum_vacuum_cost_delay | 20 | ms | Vacuum cost delay in milliseconds, for autovacuum. |
autovacuum_vacuum_cost_limit | -1 | Vacuum cost amount available before napping, for autovacuum. | |
autovacuum_vacuum_scale_factor | 0.2 | Number of tuple updates or deletes prior to vacuum as a fraction of reltuples. | |
autovacuum_vacuum_threshold | 50 | Minimum number of tuple updates or deletes prior to vacuum. | |
log_autovacuum_min_duration | -1 | ms | Sets the minimum execution time above which autovacuum actions will be logged. |
vacuum_cost_delay | 0 | ms | Vacuum cost delay in milliseconds. |
vacuum_cost_limit | 200 | Vacuum cost amount available before napping. | |
vacuum_cost_page_dirty | 20 | Vacuum cost for a page dirtied by vacuum. | |
vacuum_cost_page_hit | 1 | Vacuum cost for a page found in the buffer cache. | |
vacuum_cost_page_miss | 10 | Vacuum cost for a page not found in the buffer cache. | |
vacuum_freeze_min_age | 30000000 | Minimum age at which VACUUM should freeze a table row. | |
vacuum_freeze_table_age | 150000000 | Age at which VACUUM should scan whole table to freeze tuples. |
- If transaction ID overrun is imminent then autovacuum on table is triggered automatically even if autovacuum is switched off. This is PostgreSQL safety mechanism to prevent data loss which could be caused by this trans ID overrun.
- Basically it makes “vacuum freeze”. Which means that the biggest existing XID is stored in special column pg_class.relfrozenXID and this XID and all lower XIDs in particular table are replaced with special value “2”.XID=2 is “frozen XID”. The same happens if we run “vacuum freeze” on table manually.
- This can happen even if danger of total overrun of XID is not eminent, there are parameters in postgresql.conf for vacuum freeze on table.
- If XID overrun is eminent then all XIDs on database can be frozen the same way. In that case frozen XID for database is stored in column pg_database.datfrozenXID and all XIDs on database are replaced with value “2”. The same happens if we run “vacuum freeze” on database manually.
- After XID overrun new XID starts with value “3”. This way old XIDs are thanks to freeze always all older so data loss cannot happen.
- This automatic safety autovacuum process can be triggered unexpectedly any time which can cause problems with responses and also lock the table. It could also explain for example some highly “illogical deadlocks” – table was locked by autovacuum process.
- This mechanism was introduced in PG 7.2 and it is the same still in version 9.3.