Implement COMMIT_SIBLINGS parameter to allow pre-commit delay to occur

only if at least N other backends currently have open transactions.  This
is not a great deal of intelligence about whether a delay might be
profitable ... but it beats no intelligence at all.  Note that the default
COMMIT_DELAY is still zero --- this new code does nothing unless that
setting is changed.
Also, mark ENABLEFSYNC as a system-wide setting.  It's no longer safe to
allow that to be set per-backend, since we may be relying on some other
backend's fsync to have synced the WAL log.
This commit is contained in:
Tom Lane 2001-02-26 00:50:08 +00:00
parent 60774e8210
commit 9c9936587c
10 changed files with 94 additions and 31 deletions

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/wal.sgml,v 1.2 2001/02/18 04:50:43 tgl Exp $ -->
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/wal.sgml,v 1.3 2001/02/26 00:50:07 tgl Exp $ -->
<chapter id="wal">
<title>Write-Ahead Logging (<acronym>WAL</acronym>)</title>
@ -295,10 +295,13 @@
record to the log with <function>LogInsert</function> but before
performing a <function>LogFlush</function>. This delay allows other
backends to add their commit records to the log so as to have all
of them flushed with a single log sync. Unfortunately, this
mechanism is not fully implemented at release 7.1, so there is at
present usually no benefit to be gained from increasing this parameter
above its default value of zero.
of them flushed with a single log sync. No sleep will occur if fsync
is not enabled or if fewer than <varname>COMMIT_SIBLINGS</varname>
other backends are not currently in active transactions; this avoids
sleeping when it's unlikely that any other backend will commit soon.
Note that on most platforms, the resolution of a sleep request is
ten milliseconds, so that any nonzero <varname>COMMIT_DELAY</varname>
setting between 1 and 10000 microseconds will have the same effect.
</para>
</sect1>
</chapter>

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.97 2001/02/18 04:50:43 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.98 2001/02/26 00:50:07 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@ -157,6 +157,7 @@
#include <sys/time.h>
#include "access/nbtree.h"
#include "access/xact.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "commands/async.h"
@ -177,8 +178,6 @@
extern bool SharedBufferChanged;
void RecordTransactionCommit(void);
static void AbortTransaction(void);
static void AtAbort_Cache(void);
static void AtAbort_Locks(void);
@ -216,12 +215,14 @@ TransactionStateData CurrentTransactionStateData = {
TransactionState CurrentTransactionState = &CurrentTransactionStateData;
/*
* User-tweakable parameters
*/
int DefaultXactIsoLevel = XACT_READ_COMMITTED;
int XactIsoLevel;
#include "access/xlogutils.h"
int CommitDelay = 0; /* in microseconds */
int CommitDelay = 0; /* precommit delay in microseconds */
int CommitSiblings = 5; /* number of concurrent xacts needed to sleep */
static void (*_RollbackFunc)(void*) = NULL;
static void *_RollbackData = NULL;
@ -687,10 +688,15 @@ RecordTransactionCommit()
* Sleep before commit! 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 however, because on most Unixen, the minimum
* needs work still, because on most Unixen, the minimum
* select() delay is 10msec or more, which is way too long.)
*
* We do not sleep if enableFsync is not turned on, nor if there
* are fewer than CommitSiblings other backends with active
* transactions.
*/
if (CommitDelay > 0)
if (CommitDelay > 0 && enableFsync &&
CountActiveBackends() >= CommitSiblings)
{
struct timeval delay;

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.54 2001/02/18 04:39:42 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.55 2001/02/26 00:50:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -2096,8 +2096,6 @@ ShutdownXLOG()
elog(LOG, "database system is shut down");
}
extern XLogRecPtr GetUndoRecPtr(void);
void
CreateCheckPoint(bool shutdown)
{

View File

@ -8,16 +8,14 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.25 2001/01/24 19:43:07 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.26 2001/02/26 00:50:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* #define INVALIDDEBUG 1 */
#include "postgres.h"
#include <sys/types.h>
#include "postgres.h"
#include "storage/backendid.h"
#include "storage/proc.h"
#include "storage/sinval.h"
@ -347,11 +345,54 @@ GetSnapshotData(bool serializable)
return snapshot;
}
/*
* CountActiveBackends --- count backends (other than myself) that are in
* active transactions. This is used as a heuristic to decide if
* a pre-XLOG-flush delay is worthwhile during commit.
*
* An active transaction is something that has written at least one XLOG
* record; read-only transactions don't count. Also, do not count backends
* that are blocked waiting for locks, since they are not going to get to
* run until someone else commits.
*/
int
CountActiveBackends(void)
{
SISeg *segP = shmInvalBuffer;
ProcState *stateP = segP->procState;
int count = 0;
int index;
/*
* Note: for speed, we don't acquire SInvalLock. This is a little bit
* bogus, but since we are only testing xrecoff for zero or nonzero,
* it should be OK. The result is only used for heuristic purposes
* anyway...
*/
for (index = 0; index < segP->lastBackend; index++)
{
SHMEM_OFFSET pOffset = stateP[index].procStruct;
if (pOffset != INVALID_OFFSET)
{
PROC *proc = (PROC *) MAKE_PTR(pOffset);
if (proc == MyProc)
continue; /* do not count myself */
if (proc->logRec.xrecoff == 0)
continue; /* do not count if not in a transaction */
if (proc->waitLock != NULL)
continue; /* do not count if blocked on a lock */
count++;
}
}
return count;
}
/*
* GetUndoRecPtr -- returns oldest PROC->logRec.
*/
XLogRecPtr GetUndoRecPtr(void);
XLogRecPtr
GetUndoRecPtr(void)
{

View File

@ -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.30 2001/02/18 04:50:43 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.31 2001/02/26 00:50:07 tgl Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
@ -41,6 +41,7 @@ extern int XLOGbuffers;
extern int XLOGfiles;
extern int XLOG_DEBUG;
extern int CommitDelay;
extern int CommitSiblings;
extern bool FixBTree;
@ -181,7 +182,7 @@ ConfigureNamesBool[] =
{"tcpip_socket", PGC_POSTMASTER, &NetServer, false},
{"ssl", PGC_POSTMASTER, &EnableSSL, false},
{"fsync", PGC_USERSET, &enableFsync, true},
{"fsync", PGC_SIGHUP, &enableFsync, true},
{"silent_mode", PGC_POSTMASTER, &SilentMode, false},
{"log_connections", PGC_SIGHUP, &Log_connections, false},
@ -279,7 +280,7 @@ ConfigureNamesInt[] =
0777, 0000, 0777},
{"checkpoint_timeout", PGC_POSTMASTER, &CheckPointTimeout,
300, 30, 1800},
300, 30, 3600},
{"wal_buffers", PGC_POSTMASTER, &XLOGbuffers,
8, 4, INT_MAX},
@ -293,6 +294,9 @@ ConfigureNamesInt[] =
{"commit_delay", PGC_USERSET, &CommitDelay,
0, 0, 100000},
{"commit_siblings", PGC_USERSET, &CommitSiblings,
5, 1, 1000},
{NULL, 0, NULL, 0, 0, 0}
};

View File

@ -109,7 +109,8 @@
#wal_files = 0 # range 0-64
#wal_debug = 0 # range 0-16
#commit_delay = 0 # range 0-100000
#checkpoint_timeout = 300 # range 30-1800
#commit_siblings = 5 # range 1-1000
#checkpoint_timeout = 300 # in seconds, range 30-3600
#

View File

@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.26 2001/02/10 02:31:28 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.27 2001/02/26 00:50:07 tgl Exp $
*/
/*----------------------------------------------------------------------
@ -241,6 +241,7 @@ psql_completion(char *text, int start, int end)
"debug_level",
"max_expr_depth",
"commit_delay",
"commit_siblings",
"effective_cache_size",
"random_page_cost",

View File

@ -3,7 +3,7 @@
*
* PostgreSQL transaction log manager
*
* $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.17 2001/01/14 05:08:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.18 2001/02/26 00:50:07 tgl Exp $
*/
#ifndef XLOG_H
#define XLOG_H
@ -146,4 +146,9 @@ extern void ShutdownXLOG(void);
extern void CreateCheckPoint(bool shutdown);
extern void SetThisStartUpID(void);
/* in storage/ipc/sinval.c, but don't want to declare in sinval.h because
* we'd have to include xlog.h into that ...
*/
extern XLogRecPtr GetUndoRecPtr(void);
#endif /* XLOG_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: proc.h,v 1.39 2001/01/25 03:31:16 tgl Exp $
* $Id: proc.h,v 1.40 2001/02/26 00:50:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -50,6 +50,10 @@ struct proc
* were starting our xact: vacuum must not
* remove tuples deleted by xid >= xmin ! */
/* XLOG location of first XLOG record written by this backend's current
* transaction. If backend is not in a transaction or hasn't yet modified
* anything, logRec.xrecoff is zero.
*/
XLogRecPtr logRec;
/* Info about lock the process is currently waiting for, if any. */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: sinval.h,v 1.17 2001/01/24 19:43:28 momjian Exp $
* $Id: sinval.h,v 1.18 2001/02/26 00:50:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -30,6 +30,6 @@ extern void InvalidateSharedInvalid(void (*invalFunction) (),
extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
extern bool TransactionIdIsInProgress(TransactionId xid);
extern void GetXmaxRecent(TransactionId *XmaxRecent);
extern int CountActiveBackends(void);
#endif /* SINVAL_H */