aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2016-11-24 15:39:55 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2016-11-24 15:39:55 -0300
commit7816d13563b74379c9db618e46883c6db5fc0680 (patch)
tree0bbdb718da67abb6f55669689f56dc0ec8ad4874
parente0375d77b691f6cab70934c63d3212a4713f66df (diff)
downloadpostgresql-7816d13563b74379c9db618e46883c6db5fc0680.tar.gz
postgresql-7816d13563b74379c9db618e46883c6db5fc0680.zip
Fix commit_ts for FrozenXid and BootstrapXid
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
-rw-r--r--src/backend/access/transam/commit_ts.c11
-rw-r--r--src/test/modules/commit_ts/expected/commit_timestamp.out12
-rw-r--r--src/test/modules/commit_ts/expected/commit_timestamp_1.out12
3 files changed, 29 insertions, 6 deletions
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 38dba8cef41..eec7377975c 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -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);
diff --git a/src/test/modules/commit_ts/expected/commit_timestamp.out b/src/test/modules/commit_ts/expected/commit_timestamp.out
index 99f3322c421..5b7783b58f3 100644
--- a/src/test/modules/commit_ts/expected/commit_timestamp.out
+++ b/src/test/modules/commit_ts/expected/commit_timestamp.out
@@ -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?
----------+----------+----------
diff --git a/src/test/modules/commit_ts/expected/commit_timestamp_1.out b/src/test/modules/commit_ts/expected/commit_timestamp_1.out
index 2f1f41d2099..c10b0abc2b7 100644
--- a/src/test/modules/commit_ts/expected/commit_timestamp_1.out
+++ b/src/test/modules/commit_ts/expected/commit_timestamp_1.out
@@ -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.