2

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)

András Váczi
  • 31,778
  • 13
  • 102
  • 151
RBB
  • 815
  • 2
  • 15
  • 37

1 Answers1

7

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.

Josh Kupershmidt
  • 2,516
  • 16
  • 19