diff options
| -rw-r--r-- | src/backend/access/transam/clog.c | 17 | ||||
| -rw-r--r-- | src/backend/access/transam/subtrans.c | 20 |
2 files changed, 35 insertions, 2 deletions
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 8dc23f7039..b975ac1d27 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -590,6 +590,9 @@ ExtendCLOG(TransactionId newestXact) /* * The first condition makes sure we did not wrap around * The second checks if we are still using the same page + * 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. */ if (ClogCtl->shared->latest_page_number - pageno <= CLOG_WRAP_CHECK_DELTA && pageno <= ClogCtl->shared->latest_page_number) @@ -604,6 +607,20 @@ ExtendCLOG(TransactionId newestXact) LWLockAcquire(CLogControlLock, LW_EXCLUSIVE); +#ifdef PGXC + /* + * We repeat the check. Another process may have written + * out the page already and advanced the latest_page_number + * while we were waiting for the lock. + */ + if (ClogCtl->shared->latest_page_number - pageno <= CLOG_WRAP_CHECK_DELTA + && pageno <= ClogCtl->shared->latest_page_number) + { + LWLockRelease(CLogControlLock); + return; + } +#endif + /* Zero the page and make an XLOG entry about it */ ZeroCLOGPage(pageno, true); diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c index 2695085be3..c468c631f3 100644 --- a/src/backend/access/transam/subtrans.c +++ b/src/backend/access/transam/subtrans.c @@ -294,7 +294,6 @@ CheckPointSUBTRANS(void) TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true); } - /* * Make sure that SUBTRANS has room for a newly-allocated XID. * @@ -325,7 +324,10 @@ ExtendSUBTRANS(TransactionId newestXact) /* * The first condition makes sure we did not wrap around - * The second checks if we are still using the same page + * The second checks if we are still using the same page. + * 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. */ if (SubTransCtl->shared->latest_page_number - pageno <= SUBTRANS_WRAP_CHECK_DELTA && pageno <= SubTransCtl->shared->latest_page_number) @@ -340,6 +342,20 @@ ExtendSUBTRANS(TransactionId newestXact) LWLockAcquire(SubtransControlLock, LW_EXCLUSIVE); +#ifdef PGXC + /* + * We repeat the check. Another process may have written + * out the page already and advanced the latest_page_number + * while we were waiting for the lock. + */ + if (SubTransCtl->shared->latest_page_number - pageno <= SUBTRANS_WRAP_CHECK_DELTA + && pageno <= SubTransCtl->shared->latest_page_number) + { + LWLockRelease(SubtransControlLock); + return; + } +#endif + /* Zero the page */ ZeroSUBTRANSPage(pageno); |
