*** a/src/backend/access/transam/twophase.c --- b/src/backend/access/transam/twophase.c *************** *** 1041,1053 **** EndPrepare(GlobalTransaction gxact) /* If we crash now, we have prepared: WAL replay will fix things */ - /* - * Wake up all walsenders to send WAL up to the PREPARE record immediately - * if replication is enabled - */ - if (max_wal_senders > 0) - WalSndWakeup(); - /* write correct CRC and close file */ if ((write(fd, &statefile_crc, sizeof(pg_crc32))) != sizeof(pg_crc32)) { --- 1041,1046 ---- *************** *** 1086,1091 **** EndPrepare(GlobalTransaction gxact) --- 1079,1091 ---- END_CRIT_SECTION(); /* + * Wake up all walsenders to send WAL up to the PREPARE record immediately + * outside a critical section if replication is enabled + */ + if (max_wal_senders > 0) + WalSndWakeup(); + + /* * Wait for synchronous replication, if required. * * Note that at this stage we have marked the prepare, but still show as *************** *** 2048,2060 **** RecordTransactionCommitPrepared(TransactionId xid, /* Flush XLOG to disk */ XLogFlush(recptr); - /* - * Wake up all walsenders to send WAL up to the COMMIT PREPARED record - * immediately if replication is enabled - */ - if (max_wal_senders > 0) - WalSndWakeup(); - /* Mark the transaction committed in pg_clog */ TransactionIdCommitTree(xid, nchildren, children); --- 2048,2053 ---- *************** *** 2064,2069 **** RecordTransactionCommitPrepared(TransactionId xid, --- 2057,2069 ---- END_CRIT_SECTION(); /* + * Wake up all walsenders to send WAL up to the COMMIT PREPARED record + * immediately outside a critical section if replication is enabled + */ + if (max_wal_senders > 0) + WalSndWakeup(); + + /* * Wait for synchronous replication, if required. * * Note that at this stage we have marked clog, but still show as running *************** *** 2136,2148 **** RecordTransactionAbortPrepared(TransactionId xid, XLogFlush(recptr); /* - * Wake up all walsenders to send WAL up to the ABORT PREPARED record - * immediately if replication is enabled - */ - if (max_wal_senders > 0) - WalSndWakeup(); - - /* * Mark the transaction aborted in clog. This is not absolutely necessary * but we may as well do it while we are here. */ --- 2136,2141 ---- *************** *** 2151,2156 **** RecordTransactionAbortPrepared(TransactionId xid, --- 2144,2156 ---- END_CRIT_SECTION(); /* + * Wake up all walsenders to send WAL up to the ABORT PREPARED record + * immediately outside a critical section if replication is enabled + */ + if (max_wal_senders > 0) + WalSndWakeup(); + + /* * Wait for synchronous replication, if required. * * Note that at this stage we have marked clog, but still show as running *** a/src/backend/access/transam/xact.c --- b/src/backend/access/transam/xact.c *************** *** 942,947 **** RecordTransactionCommit(void) --- 942,948 ---- SharedInvalidationMessage *invalMessages = NULL; bool RelcacheInitFileInval = false; bool wrote_xlog; + bool wakeup = false; /* Get data needed for commit record */ nrels = smgrGetPendingDeletes(true, &rels); *************** *** 1135,1147 **** RecordTransactionCommit(void) pg_usleep(CommitDelay); XLogFlush(XactLastRecEnd); ! ! /* ! * Wake up all walsenders to send WAL up to the COMMIT record ! * immediately if replication is enabled ! */ ! if (max_wal_senders > 0) ! WalSndWakeup(); /* * Now we may update the CLOG, if we wrote a COMMIT record above --- 1136,1142 ---- pg_usleep(CommitDelay); XLogFlush(XactLastRecEnd); ! wakeup = true; /* * Now we may update the CLOG, if we wrote a COMMIT record above *************** *** 1183,1188 **** RecordTransactionCommit(void) --- 1178,1190 ---- END_CRIT_SECTION(); } + /* + * Wake up all walsenders to send WAL up to the COMMIT record + * immediately outside a critical section if replication is enabled + */ + if (max_wal_senders > 0 && wakeup) + WalSndWakeup(); + /* Compute latestXid while we have the child XIDs handy */ latestXid = TransactionIdLatest(xid, nchildren, children); *** a/src/backend/access/transam/xlog.c --- b/src/backend/access/transam/xlog.c *************** *** 2271,2276 **** XLogBackgroundFlush(void) --- 2271,2283 ---- END_CRIT_SECTION(); + /* + * Wake up all walsenders to send WAL up to the async commit record + * immediately outside a critical section is replication is enabled + */ + if (max_wal_senders > 0 && !flexible && wrote_something) + WalSndWakeup(); + return wrote_something; }