[PATCH] bigint txids vs 'xid' type, new txid_recent(bigint) => xid - Mailing list pgsql-hackers

From Craig Ringer
Subject [PATCH] bigint txids vs 'xid' type, new txid_recent(bigint) => xid
Date
Msg-id CAMsr+YFDZMN_iZ7KrRoe+j0KVLQvFVgvZxbcVxR-MLjgtoZugA@mail.gmail.com
Whole thread Raw
Responses Re: [PATCH] bigint txids vs 'xid' type, new txid_recent(bigint) => xid  (Greg Stark <stark@mit.edu>)
Re: [PATCH] bigint txids vs 'xid' type, new txid_recent(bigint) => xid  (Amit Kapila <amit.kapila16@gmail.com>)
List pgsql-hackers
Hi all

While implementing support for traceable transactions (finding out after the fact whether an xact committed or aborted), I've found that Pg is very inconsistent with what it considers a transaction ID from a user facing point of view, to the point where I think it's hard for users to write correct queries.

txid_current() returns a 64-bit xid in which the higher 32 bits are the xid epoch. This providers users with wraparound protection and means they don't have to deal with the moving xid threshold. 

Many other functions accept and return 'xid', the 32-bit type that isn't wraparound protected. Presumably they assume you'll only use them with recent transaction IDs, but there are a couple of problems with this:

* We can't ensure they're only used with recent XIDs and can't detect if they're passed a wrapped around xid

* There's no good way to _get_ a 32-bit xid for the current xact since txid_current() returns a 64-bit bigint xid.

(I have to admit that in the past I always blindly assumed that txid_current() returned bigint for historical reasons, because we don't have a uint32 type and the xid type didn't exist yet. So I'd do things like get the value of txid_current() and pass it to pg_xact_commit_timestamp() later on. This turns out to be wrong, it just happens to work until the epoch counter increments for the first time. Similarly, working around the seeming oversight of a missing bigint to xid cast with ::text::xid is wrong but will seem fine at first.)

I'm surprised the 32-bit xid was ever exposed to the user, rather than a 64-bit epoch-extended xid.

It's not clear to me how a user is supposed to correctly pass the result of txid_current() to anything like pg_xact_commit_timestamp(xid). They'd have to get the epoch from a new txid_current() call, split both into two 32-bit values, and do wraparound checking. Exceedingly unwieldy and hard to get right.

Since I don't think we can get rid of the 32-bit xid, I think we need a function to get the 32-bit xid from a 64-bit epoch-and-xid with wraparound protection. 

Here's a patch for that, adding a function txid_recent(bigint) => xid that returns the low 32 bits of a 64-bit xid like that returned from txid_current if the xid isn't wrapped around. If it's past the wraparound threshold the function returns null, since most functions that take xid are strict and will in turn return null. The alternative, an ERROR, seems harder for users to handle without resorting to plpgsql. It does ERROR on XIDs in the future though, since there's no good reason to see those. The epoch is ignored for permanent XIDs.

I don't like the name much, but haven't come up with a better one yet.

Thoughts?


IMO some functions that take 'xid' should be considered for a bigint variant:

 age    (as txid_age(bigint))
 pg_xact_commit_timestamp

[ select proname from pg_proc where 'xid'::regtype = ANY (proargtypes::regtype[]) ; ]

and most or all the system views that expose xid should switch to bigint for 10.0:

 pg_class.relfrozenxid
 pg_class.relminmxid
 pg_database.datfrozenxid
 pg_database.datminmxid
 pg_locks.transactionid
 pg_prepared_xacts.transaction
 pg_stat_activity.backend_xid
 pg_stat_activity.backend_xmin
 pg_stat_replication.backend_xmin
 pg_replication_slots.xmin
 pg_replication_slots.catalog_xmin

[ select attrelid::regclass || '.' || attname from pg_attribute  where atttypid = 'xid'::regtype AND attnum >= 0; ]

... or if folks find using bigint too ugly, a new xid64 type. "bigxid"? 


--
 Craig Ringer                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
Attachment

pgsql-hackers by date:

Previous
From: Michael Paquier
Date:
Subject: Re: Anyone want to update our Windows timezone map?
Next
From: Magnus Hagander
Date:
Subject: Re: Anyone want to update our Windows timezone map?