diff options
author | Pavan Deolasee | 2017-03-09 08:03:54 +0000 |
---|---|---|
committer | Pavan Deolasee | 2017-05-05 04:59:34 +0000 |
commit | d0b6ee233d9b62f564b7051a4a7f4f61e960fc6f (patch) | |
tree | 45da43bfac5a0fb1d8733770dbf22542578af4eb | |
parent | 77e5c18763be07607c7f1b1ec1ac14eb034f4eb4 (diff) |
Extend CommitTS properly, filling in any holes, just like ExtendCLOG.
Postgres-XL may have gaps in assigned transaction IDs, especially because not
all XIDs may be activated on a given node. So we must ensure that CommitTS is
extended properly when we see a new XID. This is same as CLOG, but we never
properly added support for CommitTS.
-rw-r--r-- | src/backend/access/transam/commit_ts.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c index e330105217..35b7451e6f 100644 --- a/src/backend/access/transam/commit_ts.c +++ b/src/backend/access/transam/commit_ts.c @@ -765,6 +765,7 @@ void ExtendCommitTs(TransactionId newestXact) { int pageno; + TransactionId latestXid; /* * Nothing to do if module not enabled. Note we do an unlocked read of @@ -776,19 +777,45 @@ ExtendCommitTs(TransactionId newestXact) return; /* - * No work except at first XID of a page. But beware: just after - * wraparound, the first XID of page zero is FirstNormalTransactionId. + * See ExtendCLOG for comments about why in Postgres-XL we may not see + * contiguous XIDs and why it's important to deal with them. The same + * principles apply here too. */ - if (TransactionIdToCTsEntry(newestXact) != 0 && - !TransactionIdEquals(newestXact, FirstNormalTransactionId)) - return; - pageno = TransactionIdToCTsPage(newestXact); + /* + * Note that this value can change and we are not holding a lock, so we + * repeat the check below. We do it this way instead of grabbing the lock + * to avoid lock contention. + */ + latestXid = (CommitTsCtl->shared->latest_page_number * + COMMIT_TS_XACTS_PER_PAGE) + COMMIT_TS_XACTS_PER_PAGE - 1; + + if (TransactionIdPrecedesOrEquals(newestXact, latestXid)) + return; + LWLockAcquire(CommitTsControlLock, LW_EXCLUSIVE); - /* Zero the page and make an XLOG entry about it */ - ZeroCommitTsPage(pageno, !InRecovery); + latestXid = (CommitTsCtl->shared->latest_page_number * + COMMIT_TS_XACTS_PER_PAGE) + COMMIT_TS_XACTS_PER_PAGE - 1; + + if (TransactionIdPrecedesOrEquals(newestXact, latestXid)) + { + LWLockRelease(CommitTsControlLock); + return; + } + + for (;;) + { + /* Zero the page and make an XLOG entry about it */ + int target_pageno = + CommitTsCtl->shared->latest_page_number + 1; + if (target_pageno > TransactionIdToCTsPage(MaxTransactionId)) + target_pageno = 0; + ZeroCommitTsPage(target_pageno, !InRecovery); + if (target_pageno == pageno) + break; + } LWLockRelease(CommitTsControlLock); } |