diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-15 19:20:47 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-15 19:20:47 +0000 |
commit | 94a41d132631f31646b81e3307c3c8d28682a4e9 (patch) | |
tree | 21ffd89a598105920d4fd0f19ce79f7faea5e5ca /src/backend/access/transam/xact.c | |
parent | 44d7f153aeec5f7e541c2d56e2c2a13e72ec3ea8 (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.c | 76 |
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; |