From ebe5867d1773ae49f0e436639d9777a63a7121a2 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Sat, 21 Oct 2017 15:50:22 +0900 Subject: [PATCH 1/3] Keep track of local writes. --- src/backend/access/heap/heapam.c | 9 +++++++++ src/backend/access/transam/xact.c | 27 +++++++++++++++++++++++++++ src/include/access/xact.h | 4 ++++ 3 files changed, 40 insertions(+), 0 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 54f1100..0e28e1d 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2453,6 +2453,9 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, */ CheckForSerializableConflictIn(relation, NULL, InvalidBuffer); + /* Remember to write on local node */ + RememberTransactionDidWrite(); + /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); @@ -3262,6 +3265,9 @@ l1: */ MultiXactIdSetOldestMember(); + /* Remember to write on local node */ + RememberTransactionDidWrite(); + compute_new_xmax_infomask(HeapTupleHeaderGetRawXmax(tp.t_data), tp.t_data->t_infomask, tp.t_data->t_infomask2, xid, LockTupleExclusive, true, @@ -4167,6 +4173,9 @@ l2: */ CheckForSerializableConflictIn(relation, &oldtup, buffer); + /* Remember to write on local node */ + RememberTransactionDidWrite(); + /* * At this point newbuf and buffer are both pinned and locked, and newbuf * has enough space for the new tuple. If they are the same buffer, only diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index b37510c..e795a2f 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -117,6 +117,9 @@ TransactionId *ParallelCurrentXids; */ int MyXactFlags; +/* True means transaction did any writes */ +bool TransactionDidWrite = false; + /* * transaction states - transaction state from server perspective */ @@ -2151,6 +2154,8 @@ CommitTransaction(void) XactTopTransactionId = InvalidTransactionId; nParallelCurrentXids = 0; + ForgetTransactionDidWrite(); + /* * done with commit processing, set current transaction state back to * default @@ -2428,6 +2433,8 @@ PrepareTransaction(void) XactTopTransactionId = InvalidTransactionId; nParallelCurrentXids = 0; + ForgetTransactionDidWrite(); + /* * done with 1st phase commit processing, set current transaction state * back to default @@ -2612,6 +2619,8 @@ AbortTransaction(void) pgstat_report_xact_timestamp(0); } + ForgetTransactionDidWrite(); + /* * State remains TRANS_ABORT until CleanupTransaction(). */ @@ -4442,6 +4451,24 @@ AbortOutOfAnyTransaction(void) } /* + * RememberTransactionDidWrite --- remember a transaction did any writes + */ +void +RememberTransactionDidWrite(void) +{ + TransactionDidWrite = true; +} + +/* + * ForgetTransactionDidWrite --- Forget a transaction did any writes + */ +void +ForgetTransactionDidWrite(void) +{ + TransactionDidWrite = false; +} + +/* * IsTransactionBlock --- are we within a transaction block? */ bool diff --git a/src/include/access/xact.h b/src/include/access/xact.h index 118b0a8..63491de 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -91,6 +91,8 @@ extern int MyXactFlags; */ #define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK (1U << 1) +/* True means transaction did any writes */ +extern bool TransactionDidWrite; /* * start- and end-of-transaction callbacks for dynamically loaded modules @@ -377,6 +379,8 @@ extern void RegisterXactCallback(XactCallback callback, void *arg); extern void UnregisterXactCallback(XactCallback callback, void *arg); extern void RegisterSubXactCallback(SubXactCallback callback, void *arg); extern void UnregisterSubXactCallback(SubXactCallback callback, void *arg); +extern void RememberTransactionDidWrite(void); +extern void ForgetTransactionDidWrite(void); extern int xactGetCommittedChildren(TransactionId **ptr); -- 1.7.1