]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Get rid of slru.c's hardwired insistence on a fixed number of slots per
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 6 Dec 2005 23:08:34 +0000 (23:08 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 6 Dec 2005 23:08:34 +0000 (23:08 +0000)
SLRU area.  The number of slots is still a compile-time constant (someday
we might want to change that), but at least it's a different constant for
each SLRU area.  Increase number of subtrans buffers to 32 based on
experimentation with a heavily subtrans-bashing test case, and increase
number of multixact member buffers to 16, since it's obviously silly for
it not to be at least twice the number of multixact offset buffers.

src/backend/access/transam/clog.c
src/backend/access/transam/multixact.c
src/backend/access/transam/slru.c
src/backend/access/transam/subtrans.c
src/backend/storage/lmgr/lwlock.c
src/include/access/clog.h
src/include/access/multixact.h
src/include/access/slru.h
src/include/access/subtrans.h

index 22e2c0541e1f1a5a4522a5d06b3901d04875598a..a3ab916bd63b74398768285963eac52cd3913771 100644 (file)
@@ -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");
 }
 
 /*
index 3e8f86818f3dc76ddbff795ce648d9048c9b5fe9..1862d188b371ccf8873c733083787de441f69bc0 100644 (file)
@@ -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 */
index 901a5e57da727dd9f90f9b29429b6d57dcc7f7b2..d1bfd9570c1088832d3b91f343026c14259aa2db 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
  * 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;
index bb32550cfc4101a8e569ac2b1270d0f005626b5b..03d0543686d16ee77920b4d75fba64d8092746f4 100644 (file)
@@ -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;
index 5526c77a676298ab8890a17f074f42c8f22afbbe..a215a65285511dca9c7ca6f26145d1bcacd67a12 100644 (file)
  * 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;
index f04eb02a58d4aaeebc36e9284a99bef17dbd36bd..3eda52a12ab83ccff12e1bd7db67a99717c5ca91 100644 (file)
@@ -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);
 
index 02f2d601c50383aa7403a35e490f69a04e1b7e3c..feee079fd0c5a3e599b538b78a947748369ab68b 100644 (file)
@@ -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
 
 #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
  * ----------------
index 62acb43c4e913e1ed82dd23533e213b427890f17..66d65c7bedc8a365d1e9d85b98b0c0541c66cf91 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #include "storage/lwlock.h"
 
 
-/*
- * 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;
@@ -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);
index cdd16e90cbd6500ad7859227ca69ff9818e87e26..e9f55963c960dfd5ded783b005e42dae9f183108 100644 (file)
@@ -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);