summaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xact.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-03-15 19:20:47 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-03-15 19:20:47 +0000
commit94a41d132631f31646b81e3307c3c8d28682a4e9 (patch)
tree21ffd89a598105920d4fd0f19ce79f7faea5e5ca /src/backend/access/transam/xact.c
parent44d7f153aeec5f7e541c2d56e2c2a13e72ec3ea8 (diff)
Repair two problems with WAL logging of sequence nextvalI() ops, as
per recent pghackers discussion: force a new WAL record at first nextval after a checkpoint, and ensure that xlog is flushed to disk if a nextval record is the only thing emitted by a transaction.
Diffstat (limited to 'src/backend/access/transam/xact.c')
-rw-r--r--src/backend/access/transam/xact.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index a9bba59d378..b3d51a49ec1 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.115 2001/11/01 06:17:01 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.115.2.1 2002/03/15 19:20:43 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@@ -546,32 +546,48 @@ RecordTransactionCommit(void)
xid = GetCurrentTransactionId();
/*
- * We needn't write anything in xlog or clog if the transaction was
- * read-only, which we check by testing if it made any xlog entries.
+ * We only need to log the commit in xlog and clog if the transaction made
+ * any transaction-controlled XLOG entries. (Otherwise, its XID appears
+ * nowhere in permanent storage, so no one will ever care if it
+ * committed.) However, we must flush XLOG to disk if we made any XLOG
+ * entries, whether in or out of transaction control. For example, if we
+ * reported a nextval() result to the client, this ensures that any XLOG
+ * record generated by nextval will hit the disk before we report the
+ * transaction committed.
*/
- if (MyLastRecPtr.xrecoff != 0)
+ if (MyXactMadeXLogEntry)
{
- XLogRecData rdata;
- xl_xact_commit xlrec;
XLogRecPtr recptr;
BufmgrCommit();
- xlrec.xtime = time(NULL);
- rdata.buffer = InvalidBuffer;
- rdata.data = (char *) (&xlrec);
- rdata.len = SizeOfXactCommit;
- rdata.next = NULL;
-
START_CRIT_SECTION();
- /*
- * SHOULD SAVE ARRAY OF RELFILENODE-s TO DROP
- */
- recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, &rdata);
+ if (MyLastRecPtr.xrecoff != 0)
+ {
+ /* Need to emit a commit record */
+ XLogRecData rdata;
+ xl_xact_commit xlrec;
+
+ xlrec.xtime = time(NULL);
+ rdata.buffer = InvalidBuffer;
+ rdata.data = (char *) (&xlrec);
+ rdata.len = SizeOfXactCommit;
+ rdata.next = NULL;
+
+ /*
+ * XXX SHOULD SAVE ARRAY OF RELFILENODE-s TO DROP
+ */
+ recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, &rdata);
+ }
+ else
+ {
+ /* Just flush through last record written by me */
+ recptr = ProcLastRecEnd;
+ }
/*
- * Sleep before commit! So we can flush more than one commit
+ * Sleep before flush! So we can flush more than one commit
* records per single fsync. (The idea is some other backend may
* do the XLogFlush while we're sleeping. This needs work still,
* because on most Unixen, the minimum select() delay is 10msec or
@@ -593,15 +609,17 @@ RecordTransactionCommit(void)
XLogFlush(recptr);
- /* Break the chain of back-links in the XLOG records I output */
- MyLastRecPtr.xrecoff = 0;
-
- /* Mark the transaction committed in clog */
- TransactionIdCommit(xid);
+ /* Mark the transaction committed in clog, if needed */
+ if (MyLastRecPtr.xrecoff != 0)
+ TransactionIdCommit(xid);
END_CRIT_SECTION();
}
+ /* Break the chain of back-links in the XLOG records I output */
+ MyLastRecPtr.xrecoff = 0;
+ MyXactMadeXLogEntry = false;
+
/* Show myself as out of the transaction in PROC array */
MyProc->logRec.xrecoff = 0;
@@ -689,8 +707,11 @@ RecordTransactionAbort(void)
TransactionId xid = GetCurrentTransactionId();
/*
- * We needn't write anything in xlog or clog if the transaction was
- * read-only, which we check by testing if it made any xlog entries.
+ * We only need to log the abort in xlog and clog if the transaction made
+ * any transaction-controlled XLOG entries. (Otherwise, its XID appears
+ * nowhere in permanent storage, so no one will ever care if it
+ * committed.) We do not flush XLOG to disk in any case, since the
+ * default assumption after a crash would be that we aborted, anyway.
*
* Extra check here is to catch case that we aborted partway through
* RecordTransactionCommit ...
@@ -714,11 +735,6 @@ RecordTransactionAbort(void)
*/
recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, &rdata);
- /*
- * There's no need for XLogFlush here, since the default
- * assumption would be that we aborted, anyway.
- */
-
/* Mark the transaction aborted in clog */
TransactionIdAbort(xid);
@@ -727,6 +743,8 @@ RecordTransactionAbort(void)
/* Break the chain of back-links in the XLOG records I output */
MyLastRecPtr.xrecoff = 0;
+ MyXactMadeXLogEntry = false;
+
/* Show myself as out of the transaction in PROC array */
MyProc->logRec.xrecoff = 0;