XID wraparound metrics are unclear
-
10-10-2020 - |
Question
Recently, I had an issue with one of my database which got XID wraparound issue. So, I have started with single-user
mode and ran vacuum
. Everything was fine. But, when I checked datfrozenxid
its ~1.5billon where as my txid_current
is ~70billon. I feel like, its huge different and something is wrong.
The below query, I have used to see the datfrozenxid
from pg_database
select datname, datfrozenxid, age(datfrozenxid) from pg_database order by datname;
I have read a XID wraparound scenario from http://www.rummandba.com/2014/02/understanding-xid-wrap-around.html
It make sense to me as per the Example given in above link. But, I have calculated xidWrapLimit
, xidStopLimit
, xidWarnLimit
, xidVacLimit
with my statistics.
xidWrapLimit = oldest_datfrozenxid + (MaxTransactionId >> 1);
xidStopLimit = xidWrapLimit - 1000000;
xidWarnLimit = xidStopLimit - 10000000;
(I haven't given all the values here since I am looking only for xidWarnLimit)
So, the xidWarnLimit
is 3.747 billon where my current txid_current
>70 billion. And strange thing is txid_current
is greater than xidWrapLimit
which is 3.758 billon.
How to find out, when it will raise the Warning about wraparound warn limit.
(using Pg9.5)
Solution
So, the xidWarnLimit is 3.747 billon where my current txid_current>70 billion. And strange thing is txid_current is greater than xidWrapLimit which is 3.758 billon.
You are presumably looking at the raw return of txid_current()
, which is not a 32-bit value like the XID Limits you are looking at. Instead, it is
a 64-bit format that is extended with an "epoch" counter so it will not wrap around during the life of an installation.
(ref). You can coax a 32-bit value out of txid_current()
which you can compare against your xidWrapLimit
, xidStopLimit
, etc. like this:
SELECT txid_current() % (2^32)::bigint;
H/T to Erwin for this tip. Remember that these XID values wrap around at 2^32.
For what it's worth, I think that blog post you linked to is excessively complicating this topic. To watch out for XID wraparound, you really just need to check:
SELECT max(age(datfrozenxid)) FROM pg_database;
and raise an alarm if that max. age is over 1 Billion or so. And if it gets close to 2 Billion you are in imminent danger! You can use a tool like check_postgres.pl which will handle this check for you with some configurable thresholds.