Commit f6a0863e authored by Robert Haas's avatar Robert Haas

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.
parent f9e9763b
...@@ -907,6 +907,7 @@ RecordTransactionCommit(void) ...@@ -907,6 +907,7 @@ RecordTransactionCommit(void)
int nmsgs = 0; int nmsgs = 0;
SharedInvalidationMessage *invalMessages = NULL; SharedInvalidationMessage *invalMessages = NULL;
bool RelcacheInitFileInval = false; bool RelcacheInitFileInval = false;
bool wrote_xlog;
/* Get data needed for commit record */ /* Get data needed for commit record */
nrels = smgrGetPendingDeletes(true, &rels); nrels = smgrGetPendingDeletes(true, &rels);
...@@ -914,6 +915,7 @@ RecordTransactionCommit(void) ...@@ -914,6 +915,7 @@ RecordTransactionCommit(void)
if (XLogStandbyInfoActive()) if (XLogStandbyInfoActive())
nmsgs = xactGetCommittedInvalidationMessages(&invalMessages, nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
&RelcacheInitFileInval); &RelcacheInitFileInval);
wrote_xlog = (XactLastRecEnd.xrecoff != 0);
/* /*
* If we haven't been assigned an XID yet, we neither can, nor do we want * If we haven't been assigned an XID yet, we neither can, nor do we want
...@@ -940,7 +942,7 @@ RecordTransactionCommit(void) ...@@ -940,7 +942,7 @@ RecordTransactionCommit(void)
* assigned is a sequence advance record due to nextval() --- we want * assigned is a sequence advance record due to nextval() --- we want
* to flush that to disk before reporting commit.) * to flush that to disk before reporting commit.)
*/ */
if (XactLastRecEnd.xrecoff == 0) if (!wrote_xlog)
goto cleanup; goto cleanup;
} }
else else
...@@ -1028,16 +1030,27 @@ RecordTransactionCommit(void) ...@@ -1028,16 +1030,27 @@ RecordTransactionCommit(void)
} }
/* /*
* Check if we want to commit asynchronously. If the user has set * Check if we want to commit asynchronously. We can allow the XLOG flush
* synchronous_commit = off, and we're not doing cleanup of any non-temp * to happen asynchronously if synchronous_commit=off, or if the current
* rels nor committing any command that wanted to force sync commit, then * transaction has not performed any WAL-logged operation. The latter case
* we can defer flushing XLOG. (We must not allow asynchronous commit if * can arise if the current transaction wrote only to temporary tables.
* there are any non-temp tables to be deleted, because we might delete * In case of a crash, the loss of such a transaction will be irrelevant
* the files before the COMMIT record is flushed to disk. We do allow * since temp tables will be lost anyway. (Given the foregoing, you might
* asynchronous commit if all to-be-deleted tables are temporary though, * think that it would be unnecessary to emit the XLOG record at all in
* since they are lost anyway if we crash.) * this case, but we don't currently try to do that. It would certainly
* cause problems at least in Hot Standby mode, where the KnownAssignedXids
* machinery requires tracking every XID assignment. It might be OK to
* skip it only when wal_level < hot_standby, but for now we don't.)
*
* However, if we're doing cleanup of any non-temp rels or committing any
* command that wanted to force sync commit, then we must flush XLOG
* immediately. (We must not allow asynchronous commit if there are any
* non-temp tables to be deleted, because we might delete the files before
* the COMMIT record is flushed to disk. We do allow asynchronous commit
* if all to-be-deleted tables are temporary though, since they are lost
* anyway if we crash.)
*/ */
if (XactSyncCommit || forceSyncCommit || nrels > 0) if ((wrote_xlog && XactSyncCommit) || forceSyncCommit || nrels > 0)
{ {
/* /*
* Synchronous commit case: * Synchronous commit case:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment