diff options
author | Tom Lane | 2005-12-06 23:08:34 +0000 |
---|---|---|
committer | Tom Lane | 2005-12-06 23:08:34 +0000 |
commit | bc7b473668446ac69c2248d6c41ea5e9ec4c8fe7 (patch) | |
tree | dcde66c7442b3da153df699278f3a6eaabb3729e | |
parent | b19dbc6f5fe500dbb0cf4855b02ec57c21f8cfa6 (diff) |
Get rid of slru.c's hardwired insistence on a fixed number of slots per
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.
-rw-r--r-- | src/backend/access/transam/clog.c | 5 | ||||
-rw-r--r-- | src/backend/access/transam/multixact.c | 10 | ||||
-rw-r--r-- | src/backend/access/transam/slru.c | 90 | ||||
-rw-r--r-- | src/backend/access/transam/subtrans.c | 4 | ||||
-rw-r--r-- | src/backend/storage/lmgr/lwlock.c | 15 | ||||
-rw-r--r-- | src/include/access/clog.h | 4 | ||||
-rw-r--r-- | src/include/access/multixact.h | 4 | ||||
-rw-r--r-- | src/include/access/slru.h | 30 | ||||
-rw-r--r-- | src/include/access/subtrans.h | 3 |
9 files changed, 109 insertions, 56 deletions
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 03348d0d38..cb520042dc 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -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 e12d5dfde7..1b866de880 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -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 84df712847..ff84a847a8 100644 --- a/src/backend/access/transam/slru.c +++ b/src/backend/access/transam/slru.c @@ -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 a0818734d1..fc955984ac 100644 --- a/src/backend/access/transam/subtrans.c +++ b/src/backend/access/transam/subtrans.c @@ -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 74886be7a7..063877377c 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -21,7 +21,9 @@ */ #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 f9ea06b4df..8788d2ce29 100644 --- a/src/include/access/clog.h +++ b/src/include/access/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 ea8f7cbd2e..e0904eec30 100644 --- a/src/include/access/multixact.h +++ b/src/include/access/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 ecfad62a12..c6b052826d 100644 --- a/src/include/access/slru.h +++ b/src/include/access/slru.h @@ -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 fe6f1f0568..7cbdf8ab73 100644 --- a/src/include/access/subtrans.h +++ b/src/include/access/subtrans.h @@ -11,6 +11,9 @@ #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); |