diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 72bfdc07a4..38cd55b81a 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -37,6 +37,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "parser/parse_type.h" +#include "replication/syncrep.h" #include "storage/lmgr.h" #include "storage/proc.h" #include "storage/smgr.h" @@ -676,8 +677,9 @@ nextval_internal(Oid relid, bool check_permissions) else { XLogRecPtr redoptr = GetRedoRecPtr(); + XLogRecPtr pagelsn = PageGetLSN(page); - if (PageGetLSN(page) <= redoptr) + if (pagelsn <= redoptr || SyncRepNeedsWait(pagelsn)) { /* last update of seq was before checkpoint */ fetch = log = fetch + SEQ_LOG_VALS; diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index bdbc9ef844..589364cb58 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -130,6 +130,34 @@ static bool SyncRepQueueIsOrderedByLSN(int mode); * =========================================================== */ +bool +SyncRepNeedsWait(XLogRecPtr lsn) +{ + int mode; + + if (!SyncRepRequested() || + !((volatile WalSndCtlData *) WalSndCtl)->sync_standbys_defined) + return false; + + mode = Min(SyncRepWaitMode, SYNC_REP_WAIT_FLUSH); + + Assert(SHMQueueIsDetached(&(MyProc->syncRepLinks))); + Assert(WalSndCtl != NULL); + + LWLockAcquire(SyncRepLock, LW_SHARED); + Assert(MyProc->syncRepState == SYNC_REP_NOT_WAITING); + + if (!WalSndCtl->sync_standbys_defined || + lsn <= WalSndCtl->lsn[mode]) + { + LWLockRelease(SyncRepLock); + return false; + } + + LWLockRelease(SyncRepLock); + return true; +} + /* * Wait for synchronous replication, if requested by user. * diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h index 4266afde8b..b08f3f32d1 100644 --- a/src/include/replication/syncrep.h +++ b/src/include/replication/syncrep.h @@ -82,6 +82,7 @@ extern char *syncrep_parse_error_msg; extern char *SyncRepStandbyNames; /* called by user backend */ +extern bool SyncRepNeedsWait(XLogRecPtr lsn); extern void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit); /* called at backend exit */