commit bdd697e5f0a16db2a672e5e14d11744958364101 Author: Robert Haas Date: Sat Nov 13 09:52:11 2010 -0500 Assume synchronous_commit=off for transactions that don't write WAL. This is advantageous for transactions that write only to temporary or unlogged tables, where loss of the transaction commit record is not critical. diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index d2e2e11..088daa0 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -907,6 +907,7 @@ RecordTransactionCommit(void) int nmsgs = 0; SharedInvalidationMessage *invalMessages = NULL; bool RelcacheInitFileInval = false; + bool wrote_xlog; /* Get data needed for commit record */ nrels = smgrGetPendingDeletes(true, &rels); @@ -914,6 +915,7 @@ RecordTransactionCommit(void) if (XLogStandbyInfoActive()) nmsgs = xactGetCommittedInvalidationMessages(&invalMessages, &RelcacheInitFileInval); + wrote_xlog = (XactLastRecEnd.xrecoff != 0); /* * If we haven't been assigned an XID yet, we neither can, nor do we want @@ -940,7 +942,7 @@ RecordTransactionCommit(void) * assigned is a sequence advance record due to nextval() --- we want * to flush that to disk before reporting commit.) */ - if (XactLastRecEnd.xrecoff == 0) + if (!wrote_xlog) goto cleanup; } else @@ -1028,16 +1030,21 @@ RecordTransactionCommit(void) } /* - * Check if we want to commit asynchronously. If the user has set - * synchronous_commit = off, and we're not doing cleanup of any non-temp - * rels nor committing any command that wanted to force sync commit, then - * we can defer flushing XLOG. (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.) + * Check if we want to commit asynchronously. 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.) Otherwise, + * we can defer the flush if either (1) the user has set synchronous_commit + * = off, or (2) the current transaction has not performed any WAL-logged + * operation. This latter case can arise if the only writes performed by + * the current transaction target temporary or unlogged relations. Loss + * of such a transaction won't matter anyway, because temp tables will be + * lost after a crash anyway, and unlogged ones will be truncated. */ - if (XactSyncCommit || forceSyncCommit || nrels > 0) + if ((wrote_xlog && XactSyncCommit) || forceSyncCommit || nrels > 0) { /* * Synchronous commit case: