Autovacuum to prevent wraparound tries to consume xid
Alexander Korotkov <a.korotkov@postgrespro.ru>
From: Alexander Korotkov <a.korotkov@postgrespro.ru>
To: pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2016-03-28T11:05:12Z
Lists: pgsql-hackers
Attachments
- fix_vac_truncate_clog_xid_consume.patch (application/octet-stream) patch
Hackers, one our customer meet near xid wraparound situation. xid counter reached xidStopLimit value. So, no transactions could be executed in normal mode. But what I noticed is strange behaviour of autovacuum to prevent wraparound. It vacuums tables, updates pg_class and pg_database, but then falls with "database is not accepting commands to avoid wraparound data loss in database" message. We end up with situation that according to pg_database maximum age of database was less than 200 mln., but transactions couldn't be executed, because ShmemVariableCache wasn't updated (checked by gdb). I've reproduced this situation on my laptop as following: 1) Connect gdb, do "set ShmemVariableCache->nextXid = ShmemVariableCache->xidStopLimit" 2) Stop postgres 3) Make some fake clog: "dd bs=1m if=/dev/zero of=/usr/local/pgsql/data/pg_clog/07FF count=1024" 4) Start postgres Then I found the same situation as in customer database. Autovacuum to prevent wraparound regularly produced following messages in the log: ERROR: database is not accepting commands to avoid wraparound data loss in database "template1" HINT: Stop the postmaster and vacuum that database in single-user mode. You might also need to commit or roll back old prepared transactions. Finally all databases was frozen # SELECT datname, age(datfrozenxid) FROM pg_database; datname │ age ───────────┼────────── template1 │ 0 template0 │ 0 postgres │ 50000000 (3 rows) but no transactions could be executed (ShmemVariableCache wasn't updated). After some debugging I found that vac_truncate_clog consumes xid just to produce warning. I wrote simple patch which replaces GetCurrentTransactionId() with ShmemVariableCache->nextXid. That completely fixes this situation for me: ShmemVariableCache was successfully updated. ------ Alexander Korotkov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company
Commits
-
Avoid repeating loads of frozen ID values.
- dd0183469bb7 17.0 landed
-
Close race condition between datfrozen and relfrozen updates.
- f222349c4ec0 12.19 landed
- 70cadfba0c70 13.15 landed
- 2ca19aa8165c 14.12 landed
- 92685c389d54 16.3 landed
- 7c5915c4b16c 15.7 landed
- f65ab862e3b8 17.0 landed
-
Fetch XIDs atomically during vac_truncate_clog().
- 2d2e40e3befd 9.6.0 cited