aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/clog.c7
-rw-r--r--src/backend/access/transam/multixact.c12
-rw-r--r--src/backend/access/transam/slru.c92
-rw-r--r--src/backend/access/transam/subtrans.c6
-rw-r--r--src/backend/storage/lmgr/lwlock.c17
-rw-r--r--src/include/access/clog.h6
-rw-r--r--src/include/access/multixact.h6
-rw-r--r--src/include/access/slru.h32
-rw-r--r--src/include/access/subtrans.h5
9 files changed, 118 insertions, 65 deletions
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 22e2c0541e1..a3ab916bd63 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -24,7 +24,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.35 2005/12/06 18:10:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.36 2005/12/06 23:08:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -147,14 +147,15 @@ TransactionIdGetStatus(TransactionId xid)
Size
CLOGShmemSize(void)
{
- return SimpleLruShmemSize();
+ return SimpleLruShmemSize(NUM_CLOG_BUFFERS);
}
void
CLOGShmemInit(void)
{
ClogCtl->PagePrecedes = CLOGPagePrecedes;
- SimpleLruInit(ClogCtl, "CLOG Ctl", CLogControlLock, "pg_clog");
+ SimpleLruInit(ClogCtl, "CLOG Ctl", NUM_CLOG_BUFFERS,
+ CLogControlLock, "pg_clog");
}
/*
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 3e8f86818f3..1862d188b37 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -42,7 +42,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.14 2005/12/06 18:10:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.15 2005/12/06 23:08:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1249,8 +1249,8 @@ MultiXactShmemSize(void)
mul_size(sizeof(MultiXactId) * 2, MaxBackends))
size = SHARED_MULTIXACT_STATE_SIZE;
- size = add_size(size, SimpleLruShmemSize());
- size = add_size(size, SimpleLruShmemSize());
+ size = add_size(size, SimpleLruShmemSize(NUM_MXACTOFFSET_BUFFERS));
+ size = add_size(size, SimpleLruShmemSize(NUM_MXACTMEMBER_BUFFERS));
return size;
}
@@ -1265,9 +1265,11 @@ MultiXactShmemInit(void)
MultiXactOffsetCtl->PagePrecedes = MultiXactOffsetPagePrecedes;
MultiXactMemberCtl->PagePrecedes = MultiXactMemberPagePrecedes;
- SimpleLruInit(MultiXactOffsetCtl, "MultiXactOffset Ctl",
+ SimpleLruInit(MultiXactOffsetCtl,
+ "MultiXactOffset Ctl", NUM_MXACTOFFSET_BUFFERS,
MultiXactOffsetControlLock, "pg_multixact/offsets");
- SimpleLruInit(MultiXactMemberCtl, "MultiXactMember Ctl",
+ SimpleLruInit(MultiXactMemberCtl,
+ "MultiXactMember Ctl", NUM_MXACTMEMBER_BUFFERS,
MultiXactMemberControlLock, "pg_multixact/members");
/* Initialize our shared state struct */
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 901a5e57da7..d1bfd9570c1 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -41,7 +41,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/slru.c,v 1.32 2005/12/06 18:10:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/slru.c,v 1.33 2005/12/06 23:08:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -87,11 +87,13 @@
* until control returns to SimpleLruFlush(). This data structure remembers
* which files are open.
*/
+#define MAX_FLUSH_BUFFERS 16
+
typedef struct SlruFlushData
{
- int num_files; /* # files actually open */
- int fd[NUM_SLRU_BUFFERS]; /* their FD's */
- int segno[NUM_SLRU_BUFFERS]; /* their log seg#s */
+ int num_files; /* # files actually open */
+ int fd[MAX_FLUSH_BUFFERS]; /* their FD's */
+ int segno[MAX_FLUSH_BUFFERS]; /* their log seg#s */
} SlruFlushData;
/*
@@ -150,25 +152,38 @@ static int SlruSelectLRUPage(SlruCtl ctl, int pageno);
*/
Size
-SimpleLruShmemSize(void)
+SimpleLruShmemSize(int nslots)
{
- /* we assume NUM_SLRU_BUFFERS isn't so large as to risk overflow */
- return BUFFERALIGN(sizeof(SlruSharedData)) + BLCKSZ * NUM_SLRU_BUFFERS;
+ Size sz;
+
+ /* we assume nslots isn't so large as to risk overflow */
+ sz = MAXALIGN(sizeof(SlruSharedData));
+ sz += MAXALIGN(nslots * sizeof(char *)); /* page_buffer[] */
+ sz += MAXALIGN(nslots * sizeof(SlruPageStatus)); /* page_status[] */
+ sz += MAXALIGN(nslots * sizeof(bool)); /* page_dirty[] */
+ sz += MAXALIGN(nslots * sizeof(int)); /* page_number[] */
+ sz += MAXALIGN(nslots * sizeof(int)); /* page_lru_count[] */
+ sz += MAXALIGN(nslots * sizeof(LWLockId)); /* buffer_locks[] */
+
+ return BUFFERALIGN(sz) + BLCKSZ * nslots;
}
void
-SimpleLruInit(SlruCtl ctl, const char *name,
+SimpleLruInit(SlruCtl ctl, const char *name, int nslots,
LWLockId ctllock, const char *subdir)
{
SlruShared shared;
bool found;
- shared = (SlruShared) ShmemInitStruct(name, SimpleLruShmemSize(), &found);
+ shared = (SlruShared) ShmemInitStruct(name,
+ SimpleLruShmemSize(nslots),
+ &found);
if (!IsUnderPostmaster)
{
/* Initialize locks and shared memory area */
- char *bufptr;
+ char *ptr;
+ Size offset;
int slotno;
Assert(!found);
@@ -177,19 +192,37 @@ SimpleLruInit(SlruCtl ctl, const char *name,
shared->ControlLock = ctllock;
- bufptr = (char *) shared + BUFFERALIGN(sizeof(SlruSharedData));
+ shared->num_slots = nslots;
+
+ shared->cur_lru_count = 0;
+
+ /* shared->latest_page_number will be set later */
- for (slotno = 0; slotno < NUM_SLRU_BUFFERS; slotno++)
+ ptr = (char *) shared;
+ offset = MAXALIGN(sizeof(SlruSharedData));
+ shared->page_buffer = (char **) (ptr + offset);
+ offset += MAXALIGN(nslots * sizeof(char *));
+ shared->page_status = (SlruPageStatus *) (ptr + offset);
+ offset += MAXALIGN(nslots * sizeof(SlruPageStatus));
+ shared->page_dirty = (bool *) (ptr + offset);
+ offset += MAXALIGN(nslots * sizeof(bool));
+ shared->page_number = (int *) (ptr + offset);
+ offset += MAXALIGN(nslots * sizeof(int));
+ shared->page_lru_count = (int *) (ptr + offset);
+ offset += MAXALIGN(nslots * sizeof(int));
+ shared->buffer_locks = (LWLockId *) (ptr + offset);
+ offset += MAXALIGN(nslots * sizeof(LWLockId));
+ ptr += BUFFERALIGN(offset);
+
+ for (slotno = 0; slotno < nslots; slotno++)
{
- shared->page_buffer[slotno] = bufptr;
+ shared->page_buffer[slotno] = ptr;
shared->page_status[slotno] = SLRU_PAGE_EMPTY;
shared->page_dirty[slotno] = false;
shared->page_lru_count[slotno] = 0;
shared->buffer_locks[slotno] = LWLockAssign();
- bufptr += BLCKSZ;
+ ptr += BLCKSZ;
}
-
- /* shared->latest_page_number will be set later */
}
else
Assert(found);
@@ -394,7 +427,7 @@ SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
LWLockAcquire(shared->ControlLock, LW_SHARED);
/* See if page is already in a buffer */
- for (slotno = 0; slotno < NUM_SLRU_BUFFERS; slotno++)
+ for (slotno = 0; slotno < shared->num_slots; slotno++)
{
if (shared->page_number[slotno] == pageno &&
shared->page_status[slotno] != SLRU_PAGE_EMPTY &&
@@ -643,9 +676,20 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata)
if (fdata)
{
- fdata->fd[fdata->num_files] = fd;
- fdata->segno[fdata->num_files] = segno;
- fdata->num_files++;
+ if (fdata->num_files < MAX_FLUSH_BUFFERS)
+ {
+ fdata->fd[fdata->num_files] = fd;
+ fdata->segno[fdata->num_files] = segno;
+ fdata->num_files++;
+ }
+ else
+ {
+ /*
+ * In the unlikely event that we exceed MAX_FLUSH_BUFFERS,
+ * fall back to treating it as a standalone write.
+ */
+ fdata = NULL;
+ }
}
}
@@ -797,7 +841,7 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno)
int best_page_number;
/* See if page already has a buffer assigned */
- for (slotno = 0; slotno < NUM_SLRU_BUFFERS; slotno++)
+ for (slotno = 0; slotno < shared->num_slots; slotno++)
{
if (shared->page_number[slotno] == pageno &&
shared->page_status[slotno] != SLRU_PAGE_EMPTY)
@@ -830,7 +874,7 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno)
best_delta = -1;
bestslot = 0; /* no-op, just keeps compiler quiet */
best_page_number = 0; /* ditto */
- for (slotno = 0; slotno < NUM_SLRU_BUFFERS; slotno++)
+ for (slotno = 0; slotno < shared->num_slots; slotno++)
{
int this_delta;
int this_page_number;
@@ -908,7 +952,7 @@ SimpleLruFlush(SlruCtl ctl, bool checkpoint)
LWLockAcquire(shared->ControlLock, LW_EXCLUSIVE);
- for (slotno = 0; slotno < NUM_SLRU_BUFFERS; slotno++)
+ for (slotno = 0; slotno < shared->num_slots; slotno++)
{
SimpleLruWritePage(ctl, slotno, &fdata);
@@ -990,7 +1034,7 @@ restart:;
return;
}
- for (slotno = 0; slotno < NUM_SLRU_BUFFERS; slotno++)
+ for (slotno = 0; slotno < shared->num_slots; slotno++)
{
if (shared->page_status[slotno] == SLRU_PAGE_EMPTY)
continue;
diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c
index bb32550cfc4..03d0543686d 100644
--- a/src/backend/access/transam/subtrans.c
+++ b/src/backend/access/transam/subtrans.c
@@ -22,7 +22,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.14 2005/12/06 18:10:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.15 2005/12/06 23:08:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -164,14 +164,14 @@ SubTransGetTopmostTransaction(TransactionId xid)
Size
SUBTRANSShmemSize(void)
{
- return SimpleLruShmemSize();
+ return SimpleLruShmemSize(NUM_SUBTRANS_BUFFERS);
}
void
SUBTRANSShmemInit(void)
{
SubTransCtl->PagePrecedes = SubTransPagePrecedes;
- SimpleLruInit(SubTransCtl, "SUBTRANS Ctl",
+ SimpleLruInit(SubTransCtl, "SUBTRANS Ctl", NUM_SUBTRANS_BUFFERS,
SubtransControlLock, "pg_subtrans");
/* Override default assumption that writes should be fsync'd */
SubTransCtl->do_fsync = false;
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 5526c77a676..a215a652855 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -15,13 +15,15 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.34 2005/10/15 02:49:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.35 2005/12/06 23:08:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "access/slru.h"
+#include "access/clog.h"
+#include "access/multixact.h"
+#include "access/subtrans.h"
#include "storage/lwlock.h"
#include "storage/proc.h"
#include "storage/spin.h"
@@ -129,16 +131,13 @@ NumLWLocks(void)
numLocks += 2 * NBuffers;
/* clog.c needs one per CLOG buffer */
- numLocks += NUM_SLRU_BUFFERS;
+ numLocks += NUM_CLOG_BUFFERS;
/* subtrans.c needs one per SubTrans buffer */
- numLocks += NUM_SLRU_BUFFERS;
+ numLocks += NUM_SUBTRANS_BUFFERS;
- /*
- * multixact.c needs one per MultiXact buffer, but there are two SLRU
- * areas for MultiXact
- */
- numLocks += 2 * NUM_SLRU_BUFFERS;
+ /* multixact.c needs two SLRU areas */
+ numLocks += NUM_MXACTOFFSET_BUFFERS + NUM_MXACTMEMBER_BUFFERS;
/* Leave a few extra for use by user-defined modules. */
numLocks += NUM_USER_DEFINED_LWLOCKS;
diff --git a/src/include/access/clog.h b/src/include/access/clog.h
index f04eb02a58d..3eda52a12ab 100644
--- a/src/include/access/clog.h
+++ b/src/include/access/clog.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/clog.h,v 1.14 2005/08/20 23:26:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/clog.h,v 1.15 2005/12/06 23:08:34 tgl Exp $
*/
#ifndef CLOG_H
#define CLOG_H
@@ -28,6 +28,10 @@ typedef int XidStatus;
#define TRANSACTION_STATUS_SUB_COMMITTED 0x03
+/* Number of SLRU buffers to use for clog */
+#define NUM_CLOG_BUFFERS 8
+
+
extern void TransactionIdSetStatus(TransactionId xid, XidStatus status);
extern XidStatus TransactionIdGetStatus(TransactionId xid);
diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h
index 02f2d601c50..feee079fd0c 100644
--- a/src/include/access/multixact.h
+++ b/src/include/access/multixact.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/multixact.h,v 1.7 2005/10/15 02:49:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/multixact.h,v 1.8 2005/12/06 23:08:34 tgl Exp $
*/
#ifndef MULTIXACT_H
#define MULTIXACT_H
@@ -18,6 +18,10 @@
#define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId)
+/* Number of SLRU buffers to use for multixact */
+#define NUM_MXACTOFFSET_BUFFERS 8
+#define NUM_MXACTMEMBER_BUFFERS 16
+
/* ----------------
* multixact-related XLOG entries
* ----------------
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index 62acb43c4e9..66d65c7bedc 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/slru.h,v 1.16 2005/12/06 18:10:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/slru.h,v 1.17 2005/12/06 23:08:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,13 +17,6 @@
/*
- * Number of page buffers. Ideally this could be different for CLOG and
- * SUBTRANS, but the benefit doesn't seem to be worth any additional
- * notational cruft.
- */
-#define NUM_SLRU_BUFFERS 8
-
-/*
* Page status codes. Note that these do not include the "dirty" bit.
* page_dirty can be TRUE only in the VALID or WRITE_IN_PROGRESS states;
* in the latter case it implies that the page has been re-dirtied since
@@ -44,16 +37,19 @@ typedef struct SlruSharedData
{
LWLockId ControlLock;
+ /* Number of buffers managed by this SLRU structure */
+ int num_slots;
+
/*
- * Info for each buffer slot. Page number is undefined when status is
- * EMPTY.
+ * Arrays holding info for each buffer slot. Page number is undefined
+ * when status is EMPTY, as is page_lru_count.
*/
- char *page_buffer[NUM_SLRU_BUFFERS];
- SlruPageStatus page_status[NUM_SLRU_BUFFERS];
- bool page_dirty[NUM_SLRU_BUFFERS];
- int page_number[NUM_SLRU_BUFFERS];
- int page_lru_count[NUM_SLRU_BUFFERS];
- LWLockId buffer_locks[NUM_SLRU_BUFFERS];
+ char **page_buffer;
+ SlruPageStatus *page_status;
+ bool *page_dirty;
+ int *page_number;
+ int *page_lru_count;
+ LWLockId *buffer_locks;
/*----------
* We mark a page "most recently used" by setting
@@ -110,8 +106,8 @@ typedef SlruCtlData *SlruCtl;
typedef struct SlruFlushData *SlruFlush;
-extern Size SimpleLruShmemSize(void);
-extern void SimpleLruInit(SlruCtl ctl, const char *name,
+extern Size SimpleLruShmemSize(int nslots);
+extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots,
LWLockId ctllock, const char *subdir);
extern int SimpleLruZeroPage(SlruCtl ctl, int pageno);
extern int SimpleLruReadPage(SlruCtl ctl, int pageno, TransactionId xid);
diff --git a/src/include/access/subtrans.h b/src/include/access/subtrans.h
index cdd16e90cbd..e9f55963c96 100644
--- a/src/include/access/subtrans.h
+++ b/src/include/access/subtrans.h
@@ -6,11 +6,14 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/subtrans.h,v 1.7 2005/08/20 23:26:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/subtrans.h,v 1.8 2005/12/06 23:08:34 tgl Exp $
*/
#ifndef SUBTRANS_H
#define SUBTRANS_H
+/* Number of SLRU buffers to use for subtrans */
+#define NUM_SUBTRANS_BUFFERS 32
+
extern void SubTransSetParent(TransactionId xid, TransactionId parent);
extern TransactionId SubTransGetParent(TransactionId xid);
extern TransactionId SubTransGetTopmostTransaction(TransactionId xid);