aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/sequence.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-03-15 19:20:36 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-03-15 19:20:36 +0000
commit01747692fe133305b03ccd7505e92b1d18c3ea1b (patch)
tree8ce3874c350868ed1d0054acb93919bb52aba2de /src/backend/commands/sequence.c
parent0b73fe14f18126d534d4dfb83b8317da8a951fae (diff)
downloadpostgresql-01747692fe133305b03ccd7505e92b1d18c3ea1b.tar.gz
postgresql-01747692fe133305b03ccd7505e92b1d18c3ea1b.zip
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/commands/sequence.c')
-rw-r--r--src/backend/commands/sequence.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 6b2161a2b17..0e57d90dfbc 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.70 2002/03/06 06:09:35 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.71 2002/03/15 19:20:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -286,6 +286,7 @@ nextval(PG_FUNCTION_ARGS)
char *seqname = get_seq_name(seqin);
SeqTable elm;
Buffer buf;
+ Page page;
Form_pg_sequence seq;
int64 incby,
maxv,
@@ -316,6 +317,7 @@ nextval(PG_FUNCTION_ARGS)
seq = read_info("nextval", elm, &buf); /* lock page' buffer and
* read tuple */
+ page = BufferGetPage(buf);
last = next = result = seq->last_value;
incby = seq->increment_by;
@@ -331,11 +333,33 @@ nextval(PG_FUNCTION_ARGS)
log--;
}
+ /*
+ * Decide whether we should emit a WAL log record. If so, force up
+ * the fetch count to grab SEQ_LOG_VALS more values than we actually
+ * need to cache. (These will then be usable without logging.)
+ *
+ * If this is the first nextval after a checkpoint, we must force
+ * a new WAL record to be written anyway, else replay starting from the
+ * checkpoint would fail to advance the sequence past the logged
+ * values. In this case we may as well fetch extra values.
+ */
if (log < fetch)
{
- fetch = log = fetch - log + SEQ_LOG_VALS;
+ /* forced log to satisfy local demand for values */
+ fetch = log = fetch + SEQ_LOG_VALS;
logit = true;
}
+ else
+ {
+ XLogRecPtr redoptr = GetRedoRecPtr();
+
+ if (XLByteLE(PageGetLSN(page), redoptr))
+ {
+ /* last update of seq was before checkpoint */
+ fetch = log = fetch + SEQ_LOG_VALS;
+ logit = true;
+ }
+ }
while (fetch) /* try to fetch cache [+ log ] numbers */
{
@@ -386,6 +410,9 @@ nextval(PG_FUNCTION_ARGS)
}
}
+ log -= fetch; /* adjust for any unfetched numbers */
+ Assert(log >= 0);
+
/* save info in local cache */
elm->last = result; /* last returned number */
elm->cached = last; /* last fetched number */
@@ -396,7 +423,6 @@ nextval(PG_FUNCTION_ARGS)
xl_seq_rec xlrec;
XLogRecPtr recptr;
XLogRecData rdata[2];
- Page page = BufferGetPage(buf);
xlrec.node = elm->rel->rd_node;
rdata[0].buffer = InvalidBuffer;
@@ -417,15 +443,11 @@ nextval(PG_FUNCTION_ARGS)
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
-
- if (fetch) /* not all numbers were fetched */
- log -= fetch;
}
/* update on-disk data */
seq->last_value = last; /* last fetched number */
seq->is_called = true;
- Assert(log >= 0);
seq->log_cnt = log; /* how much is logged */
END_CRIT_SECTION();