]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix commit_ts for FrozenXid and BootstrapXid
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 24 Nov 2016 18:39:55 +0000 (15:39 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 24 Nov 2016 18:39:55 +0000 (15:39 -0300)
Previously, requesting commit timestamp for transactions
FrozenTransactionId and BootstrapTransactionId resulted in an error.
But since those values can validly appear in committed tuples' Xmin,
this behavior is unhelpful and error prone: each caller would have to
special-case those values before requesting timestamp data for an Xid.
We already have a perfectly good interface for returning "the Xid you
requested is too old for us to have commit TS data for it", so let's use
that instead.

Backpatch to 9.5, where commit timestamps appeared.

Author: Craig Ringer
Discussion: https://www.postgresql.org/message-id/CAMsr+YFM5Q=+ry3mKvWEqRTxrB0iU3qUSRnS28nz6FJYtBwhJg@mail.gmail.com

src/backend/access/transam/commit_ts.c
src/test/modules/commit_ts/expected/commit_timestamp.out
src/test/modules/commit_ts/expected/commit_timestamp_1.out

index 38dba8cef410dbdf13406bcd6ceac3a8163c7315..eec7377975cb14f5e3e7760d043c9c73c269681b 100644 (file)
@@ -288,11 +288,18 @@ TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts,
        TransactionId oldestCommitTsXid;
        TransactionId newestCommitTsXid;
 
-       /* error if the given Xid doesn't normally commit */
-       if (!TransactionIdIsNormal(xid))
+       if (!TransactionIdIsValid(xid))
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                errmsg("cannot retrieve commit timestamp for transaction %u", xid)));
+       else if (!TransactionIdIsNormal(xid))
+       {
+               /* frozen and bootstrap xids are always committed far in the past */
+               *ts = 0;
+               if (nodeid)
+                       *nodeid = 0;
+               return false;
+       }
 
        LWLockAcquire(CommitTsLock, LW_SHARED);
 
index 99f3322c42139977c871e82ac9cf493cc94a85e7..5b7783b58f3d8d4b1699e4236ec39daf82339e86 100644 (file)
@@ -28,9 +28,17 @@ DROP TABLE committs_test;
 SELECT pg_xact_commit_timestamp('0'::xid);
 ERROR:  cannot retrieve commit timestamp for transaction 0
 SELECT pg_xact_commit_timestamp('1'::xid);
-ERROR:  cannot retrieve commit timestamp for transaction 1
+ pg_xact_commit_timestamp 
+--------------------------
+(1 row)
+
 SELECT pg_xact_commit_timestamp('2'::xid);
-ERROR:  cannot retrieve commit timestamp for transaction 2
+ pg_xact_commit_timestamp 
+--------------------------
+(1 row)
+
 SELECT x.xid::text::bigint > 0, x.timestamp > '-infinity'::timestamptz, x.timestamp <= now() FROM pg_last_committed_xact() x;
  ?column? | ?column? | ?column? 
 ----------+----------+----------
index 2f1f41d209946b72f64d76352935446acb5e4d28..c10b0abc2b75d3630515a17492f1bcbbeab50c41 100644 (file)
@@ -23,9 +23,17 @@ DROP TABLE committs_test;
 SELECT pg_xact_commit_timestamp('0'::xid);
 ERROR:  cannot retrieve commit timestamp for transaction 0
 SELECT pg_xact_commit_timestamp('1'::xid);
-ERROR:  cannot retrieve commit timestamp for transaction 1
+ pg_xact_commit_timestamp 
+--------------------------
+(1 row)
+
 SELECT pg_xact_commit_timestamp('2'::xid);
-ERROR:  cannot retrieve commit timestamp for transaction 2
+ pg_xact_commit_timestamp 
+--------------------------
+(1 row)
+
 SELECT x.xid::text::bigint > 0, x.timestamp > '-infinity'::timestamptz, x.timestamp <= now() FROM pg_last_committed_xact() x;
 ERROR:  could not get commit timestamp data
 HINT:  Make sure the configuration parameter "track_commit_timestamp" is set.