Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f6a0863

Browse files
committed
Allow transactions that don't write WAL to commit asynchronously.
This case can arise if a transaction has written data, but only to temporary tables. Loss of the commit record in case of a crash won't matter, because the temporary tables will be lost anyway. Reviewed by Heikki Linnakangas and Simon Riggs.
1 parent f9e9763 commit f6a0863

File tree

1 file changed

+23
-10
lines changed
  • src/backend/access/transam

1 file changed

+23
-10
lines changed

src/backend/access/transam/xact.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)