@@ -907,13 +907,15 @@ RecordTransactionCommit(void)
907
907
int nmsgs = 0 ;
908
908
SharedInvalidationMessage * invalMessages = NULL ;
909
909
bool RelcacheInitFileInval = false;
910
+ bool wrote_xlog ;
910
911
911
912
/* Get data needed for commit record */
912
913
nrels = smgrGetPendingDeletes (true, & rels );
913
914
nchildren = xactGetCommittedChildren (& children );
914
915
if (XLogStandbyInfoActive ())
915
916
nmsgs = xactGetCommittedInvalidationMessages (& invalMessages ,
916
917
& RelcacheInitFileInval );
918
+ wrote_xlog = (XactLastRecEnd .xrecoff != 0 );
917
919
918
920
/*
919
921
* If we haven't been assigned an XID yet, we neither can, nor do we want
@@ -940,7 +942,7 @@ RecordTransactionCommit(void)
940
942
* assigned is a sequence advance record due to nextval() --- we want
941
943
* to flush that to disk before reporting commit.)
942
944
*/
943
- if (XactLastRecEnd . xrecoff == 0 )
945
+ if (! wrote_xlog )
944
946
goto cleanup ;
945
947
}
946
948
else
@@ -1028,16 +1030,27 @@ RecordTransactionCommit(void)
1028
1030
}
1029
1031
1030
1032
/*
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.)
1039
1052
*/
1040
- if (XactSyncCommit || forceSyncCommit || nrels > 0 )
1053
+ if (( wrote_xlog && XactSyncCommit ) || forceSyncCommit || nrels > 0 )
1041
1054
{
1042
1055
/*
1043
1056
* Synchronous commit case:
0 commit comments