Evidence ledger
One row per claim in When maintenance loses the race: the vacuum PostgreSQL will not let you skip: who published it, what grade it carries, when it was written, when the link was last checked, and the quote or figure it rests on. Nothing in the guide is cited from memory, so anything not in this table is not in the guide.
Field guide: When maintenance loses the race: transaction-ID wraparound and the vacuum you cannot skip.
Research date 2026-10-16. Every artefact below was retrieved in this session: PostgreSQL source and
commits from an anonymous git clone --filter=blob:none of github.com/postgres/postgres (HEAD
af090508018be5ace443ba6e2814500c10842a4d) and from raw.githubusercontent.com; GitLab issues,
merge requests and commits through the public gitlab.com/api/v4 endpoints; GitLab's runbooks from
a shallow clone of gitlab.com/gitlab-com/runbooks (HEAD 844a2b882687492cf117cc2fc553f7fbf9a02197);
GitHub issue and pull-request pages by HTTP fetch; pganalyze's collector history from a clone.
Corpus boundary. This session's egress policy resolved github.com, raw.githubusercontent.com
and gitlab.com. postgresql.org (documentation, mailing lists, commitfest), blog.sentry.io,
mailchimp.com, web.archive.org, youtube.com, usenix.org and arxiv.org were unreachable.
The PostgreSQL documentation is therefore cited from its SGML source in the repository, the
three best-known wraparound postmortems (Sentry 2015, Joyent 2015, Mandrill 2019) are cited only
as entries in an index whose one-line summaries were read, never for their content, and the guide
has no paper or talk evidence. GitLab issue descriptions were read; issue comments require
authentication on the API and were not read.
| # | Org | Artefact | Tier | Published | Checked | URL | Claim taken from it | Supporting quote or figure |
|---|---|---|---|---|---|---|---|---|
| 1 | PostgreSQL | varsup.c at HEAD af09050, SetTransactionIdLimit |
source | 2026-10 (HEAD) | 2026-10-16 | https://raw.githubusercontent.com/postgres/postgres/af090508018be5ace443ba6e2814500c10842a4d/src/backend/access/transam/varsup.c | The hard limit is half the 32-bit space from the oldest unfrozen XID; warnings start 100M before it, XID assignment stops 3M before it | "xidWrapLimit = oldest_datfrozenxid + (MaxTransactionId >> 1)"; "xidStopLimit = xidWrapLimit - 3000000"; "xidWarnLimit = xidWrapLimit - 100000000" |
| 2 | PostgreSQL | Same file, comment on the warning threshold | source | 2026-10 (HEAD) | 2026-10-16 | https://raw.githubusercontent.com/postgres/postgres/af090508018be5ace443ba6e2814500c10842a4d/src/backend/access/transam/varsup.c | The warning margin is deliberately not configurable and is aimed at clients that ignore warnings | "if you let your gas gauge get down to 5% of full, would you be looking for the next gas station?"; "(No, we're not gonna make this configurable. If you know enough to configure it, you know enough to not get in this kind of trouble in the first place.)" |
| 3 | PostgreSQL | varsup.c on REL_13_STABLE and REL_14_STABLE |
source | branches | 2026-10-16 | https://raw.githubusercontent.com/postgres/postgres/REL_14_STABLE/src/backend/access/transam/varsup.c | The stop margin grew from 1M to 3M between 13 and 14 | REL_13: "xidStopLimit = xidWrapLimit - 1000000"; REL_14: "xidStopLimit = xidWrapLimit - 3000000" |
| 4 | PostgreSQL | proc.c at HEAD af09050, deadlock-check path |
source | 2026-10 (HEAD) | 2026-10-16 | https://raw.githubusercontent.com/postgres/postgres/af090508018be5ace443ba6e2814500c10842a4d/src/backend/storage/lmgr/proc.c | A waiter cancels a blocking autovacuum only when that autovacuum is not working to prevent wraparound | "Only do it if the worker is not working to protect against Xid wraparound."; !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND) |
| 5 | PostgreSQL | guc_parameters.dat at HEAD af09050 |
source | 2026-10 (HEAD) | 2026-10-16 | https://raw.githubusercontent.com/postgres/postgres/af090508018be5ace443ba6e2814500c10842a4d/src/backend/utils/misc/guc_parameters.dat | Defaults: freeze_max_age 200M (restart-only), failsafe 1.6B, freeze_min_age 50M | autovacuum_freeze_max_age ... PGC_POSTMASTER ... boot_val => '200000000'; vacuum_failsafe_age ... boot_val => '1600000000'; vacuum_freeze_min_age ... boot_val => '50000000' |
| 6 | PostgreSQL | maintenance.sgml at HEAD af09050, "Preventing Transaction ID Wraparound Failures" |
vendor | 2026-10 (HEAD) | 2026-10-16 | https://raw.githubusercontent.com/postgres/postgres/af090508018be5ace443ba6e2814500c10842a4d/doc/src/sgml/maintenance.sgml | At the stop limit only read-only transactions can start; single-user mode is no longer advised; the recovery order is prepared xacts, long transactions, slots, then VACUUM | "only read-only transactions can be started"; "it is not necessary or desirable to stop the postmaster or enter single user-mode"; "It is also riskier, since it disables transaction ID wraparound safeguards"; "Do not use VACUUM FREEZE either, because it will do more than the minimum amount of work" |
| 7 | PostgreSQL | Same file, storage cost of the freeze horizon | vendor | 2026-10 (HEAD) | 2026-10-16 | https://raw.githubusercontent.com/postgres/postgres/af090508018be5ace443ba6e2814500c10842a4d/doc/src/sgml/maintenance.sgml | Raising freeze_max_age costs commit-log storage | "(The default, 200 million transactions, translates to about 50MB of pg_xact storage and about 2GB of pg_commit_ts storage.)" |
| 8 | PostgreSQL | Commit 1e55e7d, "Add wraparound failsafe to VACUUM." (Sawada, Geoghegan) | source | 2021-04-07 | 2026-10-16 | https://github.com/postgres/postgres/commit/1e55e7d1755cefbb44982fbacc7da461fa8684e6 | The engine's answer to slow anti-wraparound vacuums: drop cost delay and skip index vacuuming once the table is dangerously old | "VACUUM will stop applying any cost-based delay"; "It is expected that the failsafe will almost always trigger within an autovacuum to prevent wraparound, long after the autovacuum began."; "both default to 1.6 billion" |
| 9 | PostgreSQL | Commit 2406c4e, "Reword messages about impending (M)XID exhaustion." (Haas) | adr | 2023-10-17 | 2026-10-16 | https://github.com/postgres/postgres/commit/2406c4e34ccca697bd5a221f8375f335b5841dea | The single-user-mode advice was withdrawn as harmful, on master only | "we shouldn't recommend switching to single-user mode, because that's terrible advice"; "The database doesn't shut down, nor does it refuse all commands."; "No back-patch." |
| 10 | PostgreSQL | Commit 2aa6e33, "Skip redundant anti-wraparound vacuums" | source | 2019-03-31 | 2026-10-16 | https://github.com/postgres/postgres/commit/2aa6e331ead7f3ad080561495ad4bd3bc7cd8913 | An optimisation that skipped non-aggressive anti-wraparound jobs | "This commit makes such vacuums to be skipped." |
| 11 | PostgreSQL | Commit dd9ac7d, revert of 2aa6e33 | source | 2020-03-31 | 2026-10-16 | https://github.com/postgres/postgres/commit/dd9ac7d5d80608a640bb82cffb6a805ce84cf112 | Skipping wraparound work locked autovacuum into retrying the same relations; reverted a year later | "this could cause autovacuum to lock down, with autovacuum workers attempting repeatedly those jobs on the same relations for the same database, that just kept being skipped"; "Backpatch-through: 12" |
| 12 | PostgreSQL | Commit b07642d, "Trigger autovacuum based on number of INSERTs" | source | 2020-03-28 | 2026-10-16 | https://github.com/postgres/postgres/commit/b07642dbcd8d5de05f0ee1dbb72dd6760dd30436 | Insert-only tables used to get their first vacuum as an anti-wraparound vacuum, often many at once | "anti-wraparound vacuums could be the first vacuum that the table ever receives"; "may have the same relfrozenxid, which could result in large numbers of tables requiring an anti-wraparound vacuum all at once" |
| 13 | PostgreSQL | Commit 06eae9e, "Trigger more frequent autovacuums with relallfrozen" (Plageman) | source | 2025-03-03 | 2026-10-16 | https://github.com/postgres/postgres/commit/06eae9e6218ab2acf64ea497bad0360e4c90e32d | The engine now deliberately moves freezing out of anti-wraparound vacuums because those cannot be cancelled | "We prefer to freeze these pages during insert-triggered autovacuums, as anti-wraparound vacuums are not automatically canceled by conflicting lock requests." |
| 14 | PostgreSQL | Commit a892234, all-frozen visibility-map bit (Haas, Sawada) | source | 2016-03-01 | 2026-10-16 | https://github.com/postgres/postgres/commit/a892234f830e832110f63fc0a2afce2fb21d1584 | Before 9.6, every wraparound vacuum rescanned the whole table | "optimize away full-table scans that would otherwise be triggered by XID wraparound considerations" |
| 15 | PostgreSQL | Commit d7965d6, "Add rudimentary table prioritization to autovacuum." (Bossart) | source | 2026-03-27 | 2026-10-16 | https://github.com/postgres/postgres/commit/d7965d65fc5bb2139bc51c051c11428414c65160 | Until v19 autovacuum processed tables in catalogue order; a table near wraparound had no priority | "it processes the tables in the same order as the list"; "a table nearing transaction ID wraparound should be vacuumed first" |
| 16 | PostgreSQL | Commit e646450, "Add percentage of available IDs to wraparound warnings." | source | 2026-03-20 | 2026-10-16 | https://github.com/postgres/postgres/commit/e646450e609d690ced30d9e8e3fdc27ee6c3ff4c | Warnings now state remaining space as a percentage | "The hope is that this more clearly expresses the urgency of the situation." |
| 17 | PostgreSQL | Commit 4ed8f09, "Index SLRUs by 64-bit integers" | source | 2023-11-29 | 2026-10-16 | https://github.com/postgres/postgres/commit/4ed8f0913bfdb5f3551de3c27fc2c2e880abc5a2 | Wraparound-handling code has caused data loss; the widening is incremental | "We've had repeated bugs in the area of handling SLRU wraparound in the past, some of which have caused data loss." |
| 18 | PostgreSQL | Commit bd8d9c9, "Widen MultiXactOffset to 64 bits" (Orlov, Linnakangas) | source | 2025-12-09 | 2026-10-16 | https://github.com/postgres/postgres/commit/bd8d9c9bdfa0c2168bb37edca6fa88168cacbbaa | One counter was widened; XIDs and multixids themselves stay 32-bit | "This eliminates MultiXactOffset wraparound"; "Multixids are still limited to 2^31" |
| 19 | PostgreSQL | Commit cb29861, "Widen Object ID counter to 8 bytes" (Paquier) | source | 2026-09-10 | 2026-10-16 | https://github.com/postgres/postgres/commit/cb298616463d6e4f2c360e8d07b83b526fad375f | The widening campaign reached OIDs in September 2026 | "This commit adds a new routine called GetNewObjectId8()" |
| 20 | GitLab | Production incident #22642, "Wraparound prevention vacuum in Postgres blocking PDMs" | postmortem | 2026-08-05 | 2026-10-16 | https://gitlab.com/gitlab-com/gl-infra/production/-/issues/22642 | An anti-wraparound vacuum on deployments failed post-deploy migrations and blocked deploys |
"The PDM pipeline in production has been failing repeatedly since 2026-08-05T03:17Z, which is blocking deployments."; labels Deploys-blocked-gprd::5hr, severity::3; "After that we marked the migration as complete." |
| 21 | GitLab | Production incident #4633, "Long-running CREATE INDEX blocking vacuum" | postmortem | 2021-05-18 | 2026-10-16 | https://gitlab.com/gitlab-com/gl-infra/production/-/issues/4633 | A migration held the xmin horizon for 11 hours; on-call first estimated 12 hours to shutdown, later found 27 days | "a CREATE statement that had been running for 5h30m"; "a maximum of 15 minutes warning before the database shut down" (struck through); "the transaction wrap around time was still 27 days out"; corrective action "Wraparound transaction monitoring and alerting" |
| 22 | GitLab | gitlab-cookbooks/gitlab-exporters MR !224, "add TXID wraparound monitoring" | source | 2021-05-21 (merged 2021-05-24) | 2026-10-16 | https://gitlab.com/gitlab-cookbooks/gitlab-exporters/-/merge_requests/224 | The wraparound metric already existed, unwatched and computed with the wrong function for multixacts | "the old metric was not consumed in any dashboards, alerts or recording rules"; "Switch from age(datminmxid) to mxid_age(datminmxid) to correct the age calculation"; gitlabhq_production age_datfrozenxid 199895030 |
| 23 | GitLab | runbooks commit 4ef250e, "pg txid wraparond resource saturation monitoring" | source | 2021-05-27 | 2026-10-16 | https://gitlab.com/gitlab-com/runbooks/-/commit/4ef250e4eb3a7d788a369406ce817809320bcbea | Wraparound became a severity-1 saturation point with 60%/70% SLOs | severity: 's1'; wraparoundValue: '2^31 - 3000000'; soft: 0.60, hard: 0.70 (file at HEAD) |
| 24 | GitLab | runbooks commit 9f15781, "monitor total vacuum capacity" | source | 2021-06-02 | 2026-10-16 | https://gitlab.com/gitlab-com/runbooks/-/commit/9f15781b7cf5a99d0aa287f447115c95a623d008 | GitLab measures autovacuum time per worker against the time left to the wraparound horizon | "It measures the total time spent in vacuum operations, over a 24 hour period divided the maximum number of autovacuum processes"; soft: 0.20, hard: 0.33 |
| 25 | GitLab | runbooks pg_xid_wraparound_alert.md at HEAD 844a2b8 |
adr | 2021-05-27, last edited 2026-07-04 | 2026-10-16 | https://gitlab.com/gitlab-com/runbooks/-/blob/844a2b882687492cf117cc2fc553f7fbf9a02197/docs/patroni/pg_xid_wraparound_alert.md | The runbook still predicts shutdown and single-user recovery, which upstream withdrew in 2023 | "When wraparound occurs, the database will automatically shutdown"; "Recovery would require entering single-user mode to run vacuum"; "Find and terminate any very old transactions ... Do this first." |
| 26 | GitLab | runbooks postgresql-vacuum.md at HEAD 844a2b8 (started 2022-01-25) |
adr | 2022-01-25 | 2026-10-16 | https://gitlab.com/gitlab-com/runbooks/-/blob/844a2b882687492cf117cc2fc553f7fbf9a02197/docs/patroni/postgresql-vacuum.md | GitLab.com reached the 200M freeze threshold in under three days; the proposal to raise it was argued down | "we are reaching the autovacuum_freeze_max_age threshold of 200000000 in less than 3 days on average"; "If cleaning your house hurts and takes forever, do it more often, not less"; settings autovacuum_max_workers: 6, autovacuum_vacuum_cost_delay: 5ms, autovacuum_vacuum_cost_limit: 6000 |
| 27 | GitLab | runbooks pg_repack.md at HEAD 844a2b8 |
adr | 2020-06-25, last edited 2026-10-12 | 2026-10-16 | https://gitlab.com/gitlab-com/runbooks/-/blob/844a2b882687492cf117cc2fc553f7fbf9a02197/docs/patroni/pg_repack.md | Heavy maintenance is gated on freeze age because anti-wraparound vacuum does not yield | "will force an anti-wraparound vacuum, which (unlike routine autovacuum) cannot be deferred or skipped"; "VACUUM running in the "transaction wraparound prevention mode" blocks pg_repack and doesn't yield" |
| 28 | GitLab | gitlab-org/gitlab issue #381443, "Detect and react to imminent PostgreSQL transaction ID exhaustion" | postmortem | 2022-11-03 | 2026-10-16 | https://gitlab.com/gitlab-org/gitlab/-/issues/381443 | A self-managed customer's database went read-only because a corrupt index made every vacuum of ci_builds abort before freezing |
"exhaust the ~2 billion transaction IDs and for the database to go read-only"; "This was the root cause of a customer emergency"; "ERROR: failed to re-find parent key in index"; "We suspect this had been running in a loop since the corruption occurred, and that nothing is logged."; still open |
| 29 | GitLab | gitlab-org/gitlab issue #377720, "Automatic reindexing can block vacuum progress" | postmortem | 2022-10-12 | 2026-10-16 | https://gitlab.com/gitlab-org/gitlab/-/issues/377720 | A weekend reindex blocked the wraparound vacuum on ci_builds for over 18 hours |
"blocked wraparound-prevention autovacuum on gitlab.com while reindexing ... for over 18 hours"; closed by auto-close 2025-06-30, label SLO::Missed |
| 30 | GitLab | Production #3967, "Investigate the PG shutdown and no failover" | postmortem | 2021-03-15 | 2026-10-16 | https://gitlab.com/gitlab-com/gl-infra/production/-/issues/3967 | The primary shut down under load while several anti-wraparound vacuums and a reindex ran | "The database was under a load over 90%."; "Several auto vacuums to prevent wraparound were in place." |
| 31 | GitLab | Production #3498, "Remove cron jobs created during incident" | postmortem | 2021-02-03 | 2026-10-16 | https://gitlab.com/gitlab-com/gl-infra/production/-/issues/3498 | Manual ANALYZE cron jobs added in an incident pushed GitLab.com near emergency autovacuum | "As Ongres recognized we are near emergency autovacuum to prevent wraparound" |
| 32 | GitLab | Production change #2095, per-table autovacuum_freeze_max_age before PG upgrade |
casestudy | 2020-05-08 | 2026-10-16 | https://gitlab.com/gitlab-com/gl-infra/production/-/issues/2095 | Raising the freeze threshold per table to keep wraparound vacuums out of an upgrade window | "set up the autovacuum_freeze_max_age on the tables that are over 95% of the threshold"; ALTER TABLE ci_pipelines SET (autovacuum_freeze_max_age = '500000000') |
| 33 | GitLab | Production change #4215, VACUUM FREEZE before the PG12 upgrade | casestudy | 2021-04-13 (done 2021-05-08) | 2026-10-16 | https://gitlab.com/gitlab-com/gl-infra/production/-/issues/4215 | Pre-freezing on a schedule because terminating the anti-wraparound vacuum does not work | "even if we terminate it it will restart in seconds, since it is a mechanism to keep the database integrity"; "execute this procedure 24 hours before the upgrade"; time tracking ~6h |
| 34 | GitLab | Production #7297, "Long-lived transaction in primary db" | postmortem | 2022-06-21 | 2026-10-16 | https://gitlab.com/gitlab-com/gl-infra/production/-/issues/7297 | Autovacuum's own throttled ANALYZE held the xmin horizon for 39 minutes | "autovacuum's work is not constrained by statement_timeout"; "Autovacuum's very limited cost budget (a self-throttling mechanism) caused its ANALYZE to run for 39 minutes." |
| 35 | GitLab | gitlab-org/gitlab issue #600630, "Unoptimized auto-vacuum configuration on self-managed PostgreSQL" | casestudy | 2026-05-20 | 2026-10-16 | https://gitlab.com/gitlab-org/gitlab/-/issues/600630 | Customers on default settings see anti-wraparound vacuums running for days | "autovacuum: VACUUM <table> (to prevent wraparound) holding a lock for 5+ days"; "a customer's manual ANALYZE was blocked for 2 days behind a wraparound autovacuum that had already been running for 5"; "customers only discover the issue after it has caused an incident" |
| 36 | GitLab | gitlab-org/gitlab issue #602137, "Transaction-ID wraparound & freeze-age monitoring" | adr | 2026-06-04 | 2026-10-16 | https://gitlab.com/gitlab-org/gitlab/-/issues/602137 | GitLab proposes shipping freeze-age monitoring inside the product, including MultiXact | "which cannot be skipped and won't auto-cancel"; "Age approaching the hard wraparound limit (e.g. > ~1.5 billion) - escalate" |
| 37 | reorg (pg_repack) | Issue #371, "All target table reads & writes blocked because of autovacuum on repack temporary table" | postmortem | 2023-11-09 | 2026-10-16 | https://github.com/reorg/pg_repack/issues/371 | On RDS Postgres 14, an anti-wraparound vacuum on a repack temp table plus repack's drop blocked all reads and writes for over half an hour | "autovacuum: VACUUM ANALYZE repack.table_36175838 (to prevent wraparound)"; "all reads and writes to the table were failing"; cancelled with pg_cancel_backend |
| 38 | reorg (pg_repack) | Issue #247, "Wraparound vacuum prevention sanity check" | postmortem | 2020-09-24 | 2026-10-16 | https://github.com/reorg/pg_repack/issues/247 | The same interaction, reported three years earlier, never answered | "The combination of the two made the database inaccessible."; issue still open, no replies |
| 39 | Joyent / Triton | pgstatsmon issue #28 | source | 2019-07-31 | 2026-10-16 | https://github.com/TritonDataCenter/pgstatsmon/issues/28 | The operator of Manta, after its 2015 outage, wanted wraparound vacuums labelled distinctly from other aggressive vacuums | title: ""aggressive" vacuum mode should be something like "wraparound" instead" (body read through a summarising fetch, so not quoted; it links Mandrill's postmortem); CHANGES.md entry "#25 distinguish between vacuum and vacuum to prevent wraparound" |
| 40 | pganalyze | collector commit 86aa0da / PR #879, "Match with non-aggressive anti-wraparound vacuum with log" | source | 2026-09-23 | 2026-10-16 | https://github.com/pganalyze/collector/pull/879 | A monitoring vendor's parser missed one class of anti-wraparound vacuum log line until September 2026 | git log: 86aa0da 2026-09-23 Keiko Oda Match with non-aggressive anti-wraparound vacuum with log (#879); earlier 6b6b24f 2019-08-11 ... Ignore "(to prevent wraparound)" in query text |
| 41 | Postgres.ai | postgres-howtos 0044, "How to monitor transaction ID wraparound risks" | blog | undated (repo) | 2026-10-16 | https://github.com/postgres-ai/postgres-howtos/blob/main/0044_how_to_monitor_transaction_id_wraparound_risks.md | Practitioner thresholds and the MultiXact blind spot | "Values above 1B have to be considered dangerous, requiring urgent mitigation actions."; MultiXact "usually missing in observability tools" |
| 42 | Dan Luu (index) | post-mortems README | blog | living document | 2026-10-16 | https://github.com/danluu/post-mortems | The three best-known wraparound outages exist; their own pages were unreachable | "Transaction ID Wraparound in Postgres caused Sentry to go down for most of a working day."; Mandrill "partial outage lasting a day and a half"; Joyent "PostgreSQL's transaction wraparound maintenance taking a lock on something, and a Joyent query that unnecessarily tried to take a global lock" |
| 43 | OrioleDB | README | vendor | 2026 | 2026-10-16 | https://github.com/orioledb/orioledb | The 64-bit alternative exists as a storage engine, not yet for production | "eliminating the well-known and painful wraparound problem"; "not recommended for production usage" |
| 45 | PostgreSQL | Commit cd5e822, "Change XID and mxact limits to warn at 40M and stop at 3M." (Misch) | source | 2020-08-01 | 2026-10-16 | https://github.com/postgres/postgres/commit/cd5e82256de5895595cdd99ecb03aea15b346f71 | The stop margin was widened because the last pages before the wrap limit had edge-case bugs; REL_12 warned 10M before the stop and stopped 1M before the wrap | "We have edge-case bugs when assigning values in the last few dozen pages before the wrap limit."; REL_12_STABLE varsup.c: "xidWarnLimit = xidStopLimit - 10000000" |
| 46 | PostgreSQL | Commit 48f11bf, "Bump transaction/multixact ID warning limits to 100M." (Bossart) | source | 2026-03-20 | 2026-10-16 | https://github.com/postgres/postgres/commit/48f11bfa06c6bc15369a2a0c89f7594392e02e2d | The warning margin went from 40M to 100M for fast-burning workloads | "For the benefit of workloads that rapidly consume transactions or multixacts, this commit bumps the limits to 100M. This will hopefully give users enough time to react." |
| 44 | Oracle (MySQL) | data0type.h on branch 8.4 |
source | 8.4 branch | 2026-10-16 | https://raw.githubusercontent.com/mysql/mysql-server/8.4/storage/innobase/include/data0type.h | InnoDB stores a 6-byte (48-bit) transaction ID per row | constexpr size_t DATA_TRX_ID_LEN = 6; |
| 47 | PostgreSQL | mvcc.sgml at HEAD af09050, table-level lock modes |
vendor | 2026-10 (HEAD) | 2026-10-16 | https://raw.githubusercontent.com/postgres/postgres/af090508018be5ace443ba6e2814500c10842a4d/doc/src/sgml/mvcc.sgml | Plain VACUUM takes SHARE UPDATE EXCLUSIVE, which conflicts with the locks schema changes need | "SHARE UPDATE EXCLUSIVE ... Conflicts with the SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes."; "Acquired by VACUUM (without FULL), ANALYZE, CREATE INDEX CONCURRENTLY" |
| 48 | GitLab | Production incident #3464, "Monthly CI budget reset triggers series of db performance regressions" | postmortem | 2021-02-01 | 2026-10-16 | https://gitlab.com/gitlab-com/gl-infra/production/-/issues/3464 | The incident whose ANALYZE workaround (crons) was later removed for wraparound reasons; root cause redesigned | "updates numerous rows in the database, spreading this work across a 24-hour timespan"; corrective action "enabled a feature flag that tracks CI minutes on a monthly basis with an automatic/lazy reset" |
| 49 | PostgreSQL | Commit e255b64, "Add tests for XID wraparound." (Sawada et al.) | source | 2023-11-30 | 2026-10-16 | https://github.com/postgres/postgres/commit/e255b646a16b45823c338dadf787813fc9e191dc | The xid_wraparound test module can burn XIDs quickly for manual experiments | "helper functions to quickly burn through lots of XIDs ... also handy for manually testing XID wraparound" |
Derived figures (arithmetic shown in the guide)
- GitLab.com XID burn: 200,000,000 XIDs in under 3 days [26] is more than about 67M XIDs per day; the usable space before the stop limit, 2^31 − 3,000,000 ≈ 2.144 billion [1], is therefore at most about 32 days of headroom from a fully frozen database if freezing stopped completely. Estimate.
- InnoDB's 48-bit space [44] at a sustained 1,000,000 transactions per second lasts about 2^48 / 10^6 s ≈ 2.8 × 10^8 s ≈ 8.9 years. Estimate; illustrative rate, not a measured one.
Not read
- Sentry, "Transaction ID Wraparound in Postgres" (2015), blog.sentry.io: unreachable.
- Mailchimp, "What we learned from the recent Mandrill outage" (2019), mailchimp.com: unreachable.
- Joyent, Manta postmortem 2015-07-27, web.archive.org copy: unreachable.
- PostgreSQL commitfest entries for 64-bit XIDs (2017-2025), commitfest.postgresql.org: unreachable; the guide states only what the repository shows (no 64-bit XID commit at HEAD).
- GitLab issue comments (API requires authentication).