@@ -907,13 +907,15 @@ RecordTransactionCommit(void)
907907 int nmsgs = 0 ;
908908 SharedInvalidationMessage * invalMessages = NULL ;
909909 bool RelcacheInitFileInval = false;
910+ bool wrote_xlog ;
910911
911912 /* Get data needed for commit record */
912913 nrels = smgrGetPendingDeletes (true, & rels );
913914 nchildren = xactGetCommittedChildren (& children );
914915 if (XLogStandbyInfoActive ())
915916 nmsgs = xactGetCommittedInvalidationMessages (& invalMessages ,
916917 & RelcacheInitFileInval );
918+ wrote_xlog = (XactLastRecEnd .xrecoff != 0 );
917919
918920 /*
919921 * If we haven't been assigned an XID yet, we neither can, nor do we want
@@ -940,7 +942,7 @@ RecordTransactionCommit(void)
940942 * assigned is a sequence advance record due to nextval() --- we want
941943 * to flush that to disk before reporting commit.)
942944 */
943- if (XactLastRecEnd . xrecoff == 0 )
945+ if (! wrote_xlog )
944946 goto cleanup ;
945947 }
946948 else
@@ -1028,16 +1030,27 @@ RecordTransactionCommit(void)
10281030 }
10291031
10301032 /*
1031- * Check if we want to commit asynchronously. If the user has set
1032- * synchronous_commit = off, and we're not doing cleanup of any non-temp
1033- * rels nor committing any command that wanted to force sync commit, then
1034- * we can defer flushing XLOG. (We must not allow asynchronous commit if
1035- * there are any non-temp tables to be deleted, because we might delete
1036- * the files before the COMMIT record is flushed to disk. We do allow
1037- * asynchronous commit if all to-be-deleted tables are temporary though,
1038- * since they are lost anyway if we crash.)
1033+ * Check if we want to commit asynchronously. We can allow the XLOG flush
1034+ * to happen asynchronously if synchronous_commit=off, or if the current
1035+ * transaction has not performed any WAL-logged operation. The latter case
1036+ * can arise if the current transaction wrote only to temporary tables.
1037+ * In case of a crash, the loss of such a transaction will be irrelevant
1038+ * since temp tables will be lost anyway. (Given the foregoing, you might
1039+ * think that it would be unnecessary to emit the XLOG record at all in
1040+ * this case, but we don't currently try to do that. It would certainly
1041+ * cause problems at least in Hot Standby mode, where the KnownAssignedXids
1042+ * machinery requires tracking every XID assignment. It might be OK to
1043+ * skip it only when wal_level < hot_standby, but for now we don't.)
1044+ *
1045+ * However, if we're doing cleanup of any non-temp rels or committing any
1046+ * command that wanted to force sync commit, then we must flush XLOG
1047+ * immediately. (We must not allow asynchronous commit if there are any
1048+ * non-temp tables to be deleted, because we might delete the files before
1049+ * the COMMIT record is flushed to disk. We do allow asynchronous commit
1050+ * if all to-be-deleted tables are temporary though, since they are lost
1051+ * anyway if we crash.)
10391052 */
1040- if (XactSyncCommit || forceSyncCommit || nrels > 0 )
1053+ if (( wrote_xlog && XactSyncCommit ) || forceSyncCommit || nrels > 0 )
10411054 {
10421055 /*
10431056 * Synchronous commit case:
0 commit comments