diff --git a/src/backend/access/transam/rmgr.c b/src/backend/access/transam/rmgr.c
index 31a9a1a39d7193dc054f59df917f95d23f803685..ca8b77de573533f2e8d8d6ecc604f4d1ab8555b1 100644
--- a/src/backend/access/transam/rmgr.c
+++ b/src/backend/access/transam/rmgr.c
@@ -7,8 +7,7 @@
 #include "access/xact.h"
 #include "access/xlog.h"
 #include "storage/smgr.h"
-
-#ifdef XLOG
+#include "commands/sequence.h"
 
 RmgrData   RmgrTable[] = {
 {"XLOG", xlog_redo, xlog_undo, xlog_desc},
@@ -25,15 +24,7 @@ RmgrData   RmgrTable[] = {
 {"Btree", btree_redo, btree_undo, btree_desc},
 {"Hash", hash_redo, hash_undo, hash_desc},
 {"Rtree", rtree_redo, rtree_undo, rtree_desc},
-{"Gist", gist_redo, gist_undo, gist_desc}
+{"Gist", gist_redo, gist_undo, gist_desc},
+{"Sequence", seq_redo, seq_undo, seq_desc}
 };
 
-#else /* not XLOG */
-
-/*
- * This is a dummy, but don't write RmgrTable[] = {} here,
- * that's not accepted by some compilers. -- petere
- */
-RmgrData   RmgrTable[1];
-
-#endif /* not XLOG */
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index f1d264f130d43b92d9aadc4322d04064167becca..df679d277de75391a8cfff7ad347408a6ed2767c 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.84 2000/11/21 21:15:57 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.85 2000/11/30 01:47:31 vadim Exp $
  *
  * NOTES
  *		Transaction aborts can now occur two ways:
@@ -222,7 +222,7 @@ int			XactIsoLevel;
 #ifdef XLOG
 #include "access/xlogutils.h"
 
-int			CommitDelay = 5;	/* 1/200 sec */
+int			CommitDelay = 5;	/* 1/200000 sec */
 
 static void (*_RollbackFunc)(void*) = NULL;
 static void *_RollbackData = NULL;
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index c70dbc7b4fbe8edef792a7ab01f1a542c52a10bf..b96159b41446f3d687c4c1147dcbdb1b2894a93e 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.36 2000/11/28 23:27:54 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.37 2000/11/30 01:47:31 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -240,17 +240,26 @@ static bool InRedo = false;
 XLogRecPtr
 XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
 {
-	XLogCtlInsert *Insert = &XLogCtl->Insert;
-	XLogRecord *record;
-	XLogSubRecord *subrecord;
-	XLogRecPtr	RecPtr;
-	uint32		len = hdrlen + buflen,
-				freespace,
-				wlen;
-	uint16		curridx;
-	bool		updrqst = false;
+	XLogCtlInsert  *Insert = &XLogCtl->Insert;
+	XLogRecord	   *record;
+	XLogSubRecord  *subrecord;
+	XLogRecPtr		RecPtr;
+	uint32			len = hdrlen + buflen,
+					freespace,
+					wlen;
+	uint16			curridx;
+	bool			updrqst = false;
+	bool			no_tran = (rmid == RM_XLOG_ID) ? true : false;
+
+	if (info & XLR_INFO_MASK)
+	{
+		if ((info & XLR_INFO_MASK) != XLOG_NO_TRAN)
+			elog(STOP, "XLogInsert: invalid info mask %02X", 
+				(info & XLR_INFO_MASK));
+		no_tran = true;
+		info &= ~XLR_INFO_MASK;
+	}
 
-	Assert(!(info & XLR_INFO_MASK));
 	if (len == 0 || len > MAXLOGRECSZ)
 		elog(STOP, "XLogInsert: invalid record len %u", len);
 
@@ -324,13 +333,14 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32
 	freespace -= SizeOfXLogRecord;
 	record = (XLogRecord *) Insert->currpos;
 	record->xl_prev = Insert->PrevRecord;
-	if (rmid != RM_XLOG_ID)
-		record->xl_xact_prev = MyLastRecPtr;
-	else
+	if (no_tran)
 	{
 		record->xl_xact_prev.xlogid = 0;
 		record->xl_xact_prev.xrecoff = 0;
 	}
+	else
+		record->xl_xact_prev = MyLastRecPtr;
+
 	record->xl_xid = GetCurrentTransactionId();
 	record->xl_len = (len > freespace) ? freespace : len;
 	record->xl_info = (len > freespace) ? 
@@ -340,7 +350,7 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32
 	RecPtr.xrecoff =
 		XLogCtl->xlblocks[curridx].xrecoff - BLCKSZ +
 		Insert->currpos - ((char *) Insert->currpage);
-	if (MyLastRecPtr.xrecoff == 0 && rmid != RM_XLOG_ID)
+	if (MyLastRecPtr.xrecoff == 0 && !no_tran)
 	{
 		SpinAcquire(SInvalLock);
 		MyProc->logRec = RecPtr;
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index d6a6b1b4300cdaa526d25dd3d68311224c625e61..210657cdf067900ec2f527d258c37b828e3e5b36 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -22,19 +22,12 @@
 #define SEQ_MAXVALUE	((int4)0x7FFFFFFF)
 #define SEQ_MINVALUE	-(SEQ_MAXVALUE)
 
-typedef struct FormData_pg_sequence
-{
-	NameData	sequence_name;
-	int4		last_value;
-	int4		increment_by;
-	int4		max_value;
-	int4		min_value;
-	int4		cache_value;
-	char		is_cycled;
-	char		is_called;
-} FormData_pg_sequence;
-
-typedef FormData_pg_sequence *Form_pg_sequence;
+/*
+ * We don't want to log each fetching values from sequences,
+ * so we pre-log a few fetches in advance. In the event of
+ * crash we can lose as much as we pre-logged.
+ */
+#define	SEQ_LOG_VALS	32
 
 typedef struct sequence_magic
 {
@@ -138,6 +131,11 @@ DefineSequence(CreateSeqStmt *seq)
 				coldef->colname = "cache_value";
 				value[i - 1] = Int32GetDatum(new.cache_value);
 				break;
+			case SEQ_COL_LOG:
+				typnam->name = "int4";
+				coldef->colname = "log_cnt";
+				value[i - 1] = Int32GetDatum((int32)1);
+				break;
 			case SEQ_COL_CYCLE:
 				typnam->name = "char";
 				coldef->colname = "is_cycled";
@@ -196,10 +194,14 @@ nextval(PG_FUNCTION_ARGS)
 	int32		incby,
 				maxv,
 				minv,
-				cache;
+				cache,
+				log,
+				fetch,
+				last;
 	int32		result,
 				next,
 				rescnt = 0;
+	bool		logit = false;
 
 	if (pg_aclcheck(seqname, GetUserId(), ACL_WR) != ACLCHECK_OK)
 		elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
@@ -219,16 +221,27 @@ nextval(PG_FUNCTION_ARGS)
 	seq = read_info("nextval", elm, &buf);		/* lock page' buffer and
 												 * read tuple */
 
-	next = result = seq->last_value;
+	last = next = result = seq->last_value;
 	incby = seq->increment_by;
 	maxv = seq->max_value;
 	minv = seq->min_value;
-	cache = seq->cache_value;
+	fetch = cache = seq->cache_value;
+	log = seq->log_cnt;
 
 	if (seq->is_called != 't')
+	{
 		rescnt++;				/* last_value if not called */
+		fetch--;
+		log--;
+	}
 
-	while (rescnt < cache)		/* try to fetch cache numbers */
+	if (log < fetch)
+	{
+		fetch = log = fetch - log + SEQ_LOG_VALS;
+		logit = true;
+	}
+
+	while (fetch)		/* try to fetch cache [+ log ] numbers */
 	{
 
 		/*
@@ -242,7 +255,7 @@ nextval(PG_FUNCTION_ARGS)
 				(maxv < 0 && next + incby > maxv))
 			{
 				if (rescnt > 0)
-					break;		/* stop caching */
+					break;		/* stop fetching */
 				if (seq->is_cycled != 't')
 					elog(ERROR, "%s.nextval: got MAXVALUE (%d)",
 						 elm->name, maxv);
@@ -258,7 +271,7 @@ nextval(PG_FUNCTION_ARGS)
 				(minv >= 0 && next + incby < minv))
 			{
 				if (rescnt > 0)
-					break;		/* stop caching */
+					break;		/* stop fetching */
 				if (seq->is_cycled != 't')
 					elog(ERROR, "%s.nextval: got MINVALUE (%d)",
 						 elm->name, minv);
@@ -267,17 +280,43 @@ nextval(PG_FUNCTION_ARGS)
 			else
 				next += incby;
 		}
-		rescnt++;				/* got result */
-		if (rescnt == 1)		/* if it's first one - */
-			result = next;		/* it's what to return */
+		fetch--;
+		if (rescnt < cache)
+		{
+			log--;
+			rescnt++;
+			last = next;
+			if (rescnt == 1)		/* if it's first result - */
+				result = next;		/* it's what to return */
+		}
 	}
 
 	/* save info in local cache */
 	elm->last = result;			/* last returned number */
-	elm->cached = next;			/* last cached number */
+	elm->cached = last;			/* last fetched number */
+
+	if (logit)
+	{
+		xl_seq_rec	xlrec;
+		XLogRecPtr	recptr;
+
+		if (fetch)		/* not all numbers were fetched */
+			log -= fetch;
+
+		xlrec.node = elm->rel->rd_node;
+		xlrec.value = next;
+
+		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG|XLOG_NO_TRAN,
+					(char*) &xlrec, sizeof(xlrec), NULL, 0);
+
+		PageSetLSN(BufferGetPage(buf), recptr);
+		PageSetSUI(BufferGetPage(buf), ThisStartUpID);
+	}
 
 	/* save info in sequence relation */
-	seq->last_value = next;		/* last fetched number */
+	seq->last_value = last;		/* last fetched number */
+	Assert(log >= 0);
+	seq->log_cnt = log;			/* how much is logged */
 	seq->is_called = 't';
 
 	LockBuffer(buf, BUFFER_LOCK_UNLOCK);
@@ -349,6 +388,21 @@ do_setval(char *seqname, int32 next, bool iscalled)
 	/* save info in sequence relation */
 	seq->last_value = next;		/* last fetched number */
 	seq->is_called = iscalled ? 't' : 'f';
+	seq->log_cnt = (iscalled) ? 0 : 1;
+
+	{
+		xl_seq_rec	xlrec;
+		XLogRecPtr	recptr;
+
+		xlrec.node = elm->rel->rd_node;
+		xlrec.value = next;
+
+		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_SET|XLOG_NO_TRAN,
+					(char*) &xlrec, sizeof(xlrec), NULL, 0);
+
+		PageSetLSN(BufferGetPage(buf), recptr);
+		PageSetSUI(BufferGetPage(buf), ThisStartUpID);
+	}
 
 	LockBuffer(buf, BUFFER_LOCK_UNLOCK);
 
@@ -638,7 +692,6 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
 
 }
 
-
 static int
 get_param(DefElem *def)
 {
@@ -651,3 +704,80 @@ get_param(DefElem *def)
 	elog(ERROR, "DefineSequence: \"%s\" is to be integer", def->defname);
 	return -1;
 }
+
+void seq_redo(XLogRecPtr lsn, XLogRecord *record)
+{
+	uint8				info = record->xl_info & ~XLR_INFO_MASK;
+	Relation			reln;
+	Buffer				buffer;
+	Page				page;
+	ItemId				lp;
+	HeapTupleData		tuple;
+	Form_pg_sequence	seq;
+	xl_seq_rec		   *xlrec;
+
+	if (info != XLOG_SEQ_LOG && info != XLOG_SEQ_SET)
+		elog(STOP, "seq_redo: unknown op code %u", info);
+
+	xlrec = (xl_seq_rec*) XLogRecGetData(record);
+
+	reln = XLogOpenRelation(true, RM_SEQ_ID, xlrec->node);
+	if (!RelationIsValid(reln))
+		return;
+
+	buffer = XLogReadBuffer(false, reln, 0);
+	if (!BufferIsValid(buffer))
+		elog(STOP, "seq_redo: can't read block of %u/%u", 
+			xlrec->node.tblNode, xlrec->node.relNode);
+
+	page = (Page) BufferGetPage(buffer);
+	if (PageIsNew((PageHeader) page) ||
+		((sequence_magic *) PageGetSpecialPointer(page))->magic != SEQ_MAGIC)
+		elog(STOP, "seq_redo: uninitialized page of %u/%u",
+			xlrec->node.tblNode, xlrec->node.relNode);
+
+	if (XLByteLE(lsn, PageGetLSN(page)))
+	{
+		UnlockAndReleaseBuffer(buffer);
+		return;
+	}
+
+	lp = PageGetItemId(page, FirstOffsetNumber);
+	Assert(ItemIdIsUsed(lp));
+	tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);
+
+	seq = (Form_pg_sequence) GETSTRUCT(&tuple);
+
+	seq->last_value = xlrec->value;		/* last logged value */
+	seq->is_called = 't';
+	seq->log_cnt = 0;
+
+	PageSetLSN(page, lsn);
+	PageSetSUI(page, ThisStartUpID);
+	UnlockAndWriteBuffer(buffer);
+
+	return;
+}
+
+void seq_undo(XLogRecPtr lsn, XLogRecord *record)
+{
+}
+
+void seq_desc(char *buf, uint8 xl_info, char* rec)
+{
+	uint8				info = xl_info & ~XLR_INFO_MASK;
+	xl_seq_rec		   *xlrec = (xl_seq_rec*) rec;
+
+	if (info == XLOG_SEQ_LOG)
+		strcat(buf, "log: ");
+	else if (info == XLOG_SEQ_SET)
+		strcat(buf, "set: ");
+	else
+	{
+		strcat(buf, "UNKNOWN");
+		return;
+	}
+
+	sprintf(buf + strlen(buf), "node %u/%u; value %d",
+		xlrec->node.tblNode, xlrec->node.relNode, xlrec->value);
+}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 398fb25bf6818d7fb7eb9cb946f45a562c767383..046c304e24d99bc2a2055648c277033a53a561f0 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4,7 +4,7 @@
  * Support for grand unified configuration scheme, including SET
  * command, configuration file, and command line options.
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.24 2000/11/29 20:59:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.25 2000/11/30 01:47:32 vadim Exp $
  *
  * Copyright 2000 by PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -39,6 +39,8 @@ extern bool Log_connections;
 extern int CheckPointTimeout;
 extern int XLOGbuffers;
 extern int XLOG_DEBUG;
+extern int CommitDelay;
+
 #ifdef ENABLE_SYSLOG
 extern char *Syslog_facility;
 extern char *Syslog_ident;
@@ -266,15 +268,18 @@ ConfigureNamesInt[] =
 	{"unix_socket_permissions", PGC_POSTMASTER,         &Unix_socket_permissions,
 	 0777, 0000, 0777},
 
-	{"checkpoint_timeout", PGC_POSTMASTER,         &CheckPointTimeout,
+	{"checkpoint_timeout",	PGC_POSTMASTER,			&CheckPointTimeout,
 	 300, 30, 1800},
 
-	{"wal_buffers", PGC_POSTMASTER,         &XLOGbuffers,
+	{"wal_buffers",			PGC_POSTMASTER,			&XLOGbuffers,
 	 8, 4, INT_MAX},
 
-	{"wal_debug", PGC_POSTMASTER,         &XLOG_DEBUG,
+	{"wal_debug",			PGC_SUSET,				&XLOG_DEBUG,
 	 0, 0, 16},
 
+	{"commit_delay",		PGC_USERSET,			&CommitDelay,
+	 5, 0, 1000},
+
     {NULL, 0, NULL, 0, 0, 0}
 };
 
diff --git a/src/include/access/htup.h b/src/include/access/htup.h
index 177176e434ab62eddb644886a727808128fcdd80..6484abf36d8eebc158df46429c1b65b7a17b1079 100644
--- a/src/include/access/htup.h
+++ b/src/include/access/htup.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: htup.h,v 1.39 2000/11/14 21:04:32 tgl Exp $
+ * $Id: htup.h,v 1.40 2000/11/30 01:47:32 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -186,9 +186,9 @@ extern long heap_sysoffset[];
  */
 typedef struct HeapTupleData
 {
-	uint32		t_len;			/* length of *t_data */
+	uint32			t_len;			/* length of *t_data */
 	ItemPointerData t_self;		/* SelfItemPointer */
-	Oid			t_tableOid;		/* table the tuple came from */
+	Oid				t_tableOid;		/* table the tuple came from */
 	MemoryContext	t_datamcxt;	/* mcxt in which allocated */
 	HeapTupleHeader	t_data;		/* -> tuple header and data */
 } HeapTupleData;
diff --git a/src/include/access/rmgr.h b/src/include/access/rmgr.h
index 221c52d2f2b5ea7bf0c9e1579a0abf74bfedfa24..af721e9fe763df848f735cc5e4d3e182a771b287 100644
--- a/src/include/access/rmgr.h
+++ b/src/include/access/rmgr.h
@@ -21,6 +21,7 @@ typedef uint8 RmgrId;
 #define RM_HASH_ID				12
 #define RM_RTREE_ID				13
 #define RM_GIST_ID				14
-#define RM_MAX_ID				RM_GIST_ID
+#define RM_SEQ_ID				15
+#define RM_MAX_ID				RM_SEQ_ID
 
 #endif	 /* RMGR_H */
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 4654296e116eefd1ef3c8ab75a9fa3b11927e3c4..785ac94c9b20a48d015dee294126dd850cdd8b00 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -3,7 +3,7 @@
  *
  * PostgreSQL transaction log manager
  *
- * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.11 2000/11/25 20:33:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.12 2000/11/30 01:47:32 vadim Exp $
  */
 #ifndef XLOG_H
 #define XLOG_H
@@ -54,6 +54,12 @@ typedef struct XLogSubRecord
 #define XLR_TO_BE_CONTINUED		0x01
 #define	XLR_INFO_MASK			0x0F
 
+/*
+ * Sometimes we log records which are out of transaction control.
+ * Rmgr may use flag below for this purpose.
+ */
+#define	XLOG_NO_TRAN			XLR_INFO_MASK
+
 #define XLOG_PAGE_MAGIC 0x17345168
 
 typedef struct XLogPageHeaderData
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 85e4c02b53317a8cb92d99a230eedb27fa3ca4e5..93958d5ec059ea0fbdda8a66f226453056fdc5f7 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.64 2000/11/25 20:33:53 tgl Exp $
+ * $Id: catversion.h,v 1.65 2000/11/30 01:47:33 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                        	yyyymmddN */
-#define CATALOG_VERSION_NO	200011251
+#define CATALOG_VERSION_NO	200011291
 
 #endif
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index 0429d2295324b28721d5cf6691a55a73d8385f5a..415364862b23190d4e37b2ddebe76b8376c8e011 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -10,6 +10,22 @@
 #define SEQUENCE_H
 
 #include "nodes/parsenodes.h"
+#include "access/xlog.h"
+
+typedef struct FormData_pg_sequence
+{
+	NameData	sequence_name;
+	int4		last_value;
+	int4		increment_by;
+	int4		max_value;
+	int4		min_value;
+	int4		cache_value;
+	int4		log_cnt;
+	char		is_cycled;
+	char		is_called;
+} FormData_pg_sequence;
+
+typedef FormData_pg_sequence *Form_pg_sequence;
 
 /*
  * Columns of a sequence relation
@@ -21,12 +37,23 @@
 #define SEQ_COL_MAXVALUE		4
 #define SEQ_COL_MINVALUE		5
 #define SEQ_COL_CACHE			6
-#define SEQ_COL_CYCLE			7
-#define SEQ_COL_CALLED			8
+#define	SEQ_COL_LOG				7
+#define SEQ_COL_CYCLE			8
+#define SEQ_COL_CALLED			9
 
 #define SEQ_COL_FIRSTCOL		SEQ_COL_NAME
 #define SEQ_COL_LASTCOL			SEQ_COL_CALLED
 
+/* XLOG stuff */
+#define	XLOG_SEQ_LOG			0x00
+#define	XLOG_SEQ_SET			0x10
+
+typedef struct xl_seq_rec
+{
+	RelFileNode				node;
+	int4					value;		/* last logged value */
+} xl_seq_rec;
+
 extern Datum nextval(PG_FUNCTION_ARGS);
 extern Datum currval(PG_FUNCTION_ARGS);
 extern Datum setval(PG_FUNCTION_ARGS);
@@ -35,4 +62,8 @@ extern Datum setval_and_iscalled(PG_FUNCTION_ARGS);
 extern void DefineSequence(CreateSeqStmt *stmt);
 extern void CloseSequences(void);
 
+extern void seq_redo(XLogRecPtr lsn, XLogRecord *rptr);
+extern void seq_undo(XLogRecPtr lsn, XLogRecord *rptr);
+extern void seq_desc(char *buf, uint8 xl_info, char* rec);
+
 #endif	 /* SEQUENCE_H */