diff options
Diffstat (limited to 'src/backend/storage/buffer')
-rw-r--r-- | src/backend/storage/buffer/buf_init.c | 27 | ||||
-rw-r--r-- | src/backend/storage/buffer/buf_table.c | 41 | ||||
-rw-r--r-- | src/backend/storage/buffer/freelist.c | 74 |
3 files changed, 114 insertions, 28 deletions
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c index 6b6a8289ad8..b413c2ab131 100644 --- a/src/backend/storage/buffer/buf_init.c +++ b/src/backend/storage/buffer/buf_init.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.70 2004/12/31 22:00:49 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.70.4.1 2005/02/03 23:30:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -73,7 +73,6 @@ long int LocalBufferFlushCount; * aborts, it should only unpin the buffers exactly the number of times it * has pinned them, so that it will not blow away buffers of another * backend. - * */ @@ -120,14 +119,17 @@ InitBufferPool(void) block = BufferBlocks; /* - * link the buffers into a single linked list. This will become - * the LIFO list of unused buffers returned by - * StrategyGetBuffer(). + * Initialize all the buffer headers. */ for (i = 0; i < NBuffers; block += BLCKSZ, buf++, i++) { Assert(ShmemIsValid((unsigned long) block)); + /* + * The bufNext fields link together all totally-unused buffers. + * Subsequent management of this list is done by + * StrategyGetBuffer(). + */ buf->bufNext = i + 1; CLEAR_BUFFERTAG(buf->tag); @@ -142,7 +144,7 @@ InitBufferPool(void) buf->wait_backend_id = 0; } - /* Correct last entry */ + /* Correct last entry of linked list */ BufferDescriptors[NBuffers - 1].bufNext = -1; LWLockRelease(BufMgrLock); @@ -178,7 +180,8 @@ InitBufferPoolAccess(void) /* * Convert shmem offsets into addresses as seen by this process. This - * is just to speed up the BufferGetBlock() macro. + * is just to speed up the BufferGetBlock() macro. It is OK to do this + * without any lock since the data pointers never change. */ for (i = 0; i < NBuffers; i++) BufferBlockPointers[i] = (Block) MAKE_PTR(BufferDescriptors[i].data); @@ -201,14 +204,8 @@ BufferShmemSize(void) /* size of data pages */ size += NBuffers * MAXALIGN(BLCKSZ); - /* size of buffer hash table */ - size += hash_estimate_size(NBuffers * 2, sizeof(BufferLookupEnt)); - - /* size of the shared replacement strategy control block */ - size += MAXALIGN(sizeof(BufferStrategyControl)); - - /* size of the ARC directory blocks */ - size += MAXALIGN(NBuffers * 2 * sizeof(BufferStrategyCDB)); + /* size of stuff controlled by freelist.c */ + size += StrategyShmemSize(); return size; } diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c index 12ac6aba886..8a437f6f01a 100644 --- a/src/backend/storage/buffer/buf_table.c +++ b/src/backend/storage/buffer/buf_table.c @@ -1,11 +1,11 @@ /*------------------------------------------------------------------------- * * buf_table.c - * routines for finding buffers in the buffer pool. + * routines for mapping BufferTags to buffer indexes. * - * NOTE: these days, what this table actually provides is a mapping from - * BufferTags to CDB indexes, not directly to buffers. The function names - * are thus slight misnomers. + * NOTE: this module is called only by freelist.c, and the "buffer IDs" + * it deals with are whatever freelist.c needs them to be; they may not be + * directly equivalent to Buffer numbers. * * Note: all routines in this file assume that the BufMgrLock is held * by the caller, so no synchronization is needed. @@ -16,7 +16,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_table.c,v 1.38 2004/12/31 22:00:49 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_table.c,v 1.38.4.1 2005/02/03 23:30:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,12 +26,29 @@ #include "storage/bufmgr.h" +/* entry for buffer lookup hashtable */ +typedef struct +{ + BufferTag key; /* Tag of a disk page */ + int id; /* Associated buffer ID */ +} BufferLookupEnt; + static HTAB *SharedBufHash; /* + * Estimate space needed for mapping hashtable + * size is the desired hash table size (possibly more than NBuffers) + */ +int +BufTableShmemSize(int size) +{ + return hash_estimate_size(size, sizeof(BufferLookupEnt)); +} + +/* * Initialize shmem hash table for mapping buffers - * size is the desired hash table size (2*NBuffers for ARC algorithm) + * size is the desired hash table size (possibly more than NBuffers) */ void InitBufTable(int size) @@ -56,7 +73,7 @@ InitBufTable(int size) /* * BufTableLookup - * Lookup the given BufferTag; return CDB index, or -1 if not found + * Lookup the given BufferTag; return buffer ID, or -1 if not found */ int BufTableLookup(BufferTag *tagPtr) @@ -76,10 +93,10 @@ BufTableLookup(BufferTag *tagPtr) /* * BufTableInsert - * Insert a hashtable entry for given tag and CDB index + * Insert a hashtable entry for given tag and buffer ID */ void -BufTableInsert(BufferTag *tagPtr, int cdb_id) +BufTableInsert(BufferTag *tagPtr, int buf_id) { BufferLookupEnt *result; bool found; @@ -92,15 +109,15 @@ BufTableInsert(BufferTag *tagPtr, int cdb_id) (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); - if (found) /* found something else in the table? */ + if (found) /* found something already in the table? */ elog(ERROR, "shared buffer hash table corrupted"); - result->id = cdb_id; + result->id = buf_id; } /* * BufTableDelete - * Delete the hashtable entry for given tag + * Delete the hashtable entry for given tag (which must exist) */ void BufTableDelete(BufferTag *tagPtr) diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c index eb38fcf21af..fe1a2eab519 100644 --- a/src/backend/storage/buffer/freelist.c +++ b/src/backend/storage/buffer/freelist.c @@ -3,6 +3,11 @@ * freelist.c * routines for manipulating the buffer pool's replacement strategy. * + * The name "freelist.c" is now a bit of a misnomer, since this module + * controls not only the list of free buffers per se, but the entire + * mechanism for looking up existing shared buffers and the strategy + * for choosing replacement victims when needed. + * * Note: all routines in this file assume that the BufMgrLock is held * by the caller, so no synchronization is needed. * @@ -12,7 +17,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.49 2004/12/31 22:00:49 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.49.4.1 2005/02/03 23:30:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,6 +30,51 @@ #include "storage/bufmgr.h" +/* + * Definitions for the buffer replacement strategy + */ +#define STRAT_LIST_UNUSED (-1) +#define STRAT_LIST_B1 0 +#define STRAT_LIST_T1 1 +#define STRAT_LIST_T2 2 +#define STRAT_LIST_B2 3 +#define STRAT_NUM_LISTS 4 + +/* + * The Cache Directory Block (CDB) of the Adaptive Replacement Cache (ARC) + */ +typedef struct +{ + int prev; /* list links */ + int next; + short list; /* ID of list it is currently in */ + bool t1_vacuum; /* t => present only because of VACUUM */ + TransactionId t1_xid; /* the xid this entry went onto T1 */ + BufferTag buf_tag; /* page identifier */ + int buf_id; /* currently assigned data buffer, or -1 */ +} BufferStrategyCDB; + +/* + * The shared ARC control information. + */ +typedef struct +{ + int target_T1_size; /* What T1 size are we aiming for */ + int listUnusedCDB; /* All unused StrategyCDB */ + int listHead[STRAT_NUM_LISTS]; /* ARC lists B1, T1, T2 + * and B2 */ + int listTail[STRAT_NUM_LISTS]; + int listSize[STRAT_NUM_LISTS]; + Buffer listFreeBuffers; /* List of unused buffers */ + + long num_lookup; /* Some hit statistics */ + long num_hit[STRAT_NUM_LISTS]; + time_t stat_report; + + /* Array of CDB's starts here */ + BufferStrategyCDB cdb[1]; /* VARIABLE SIZE ARRAY */ +} BufferStrategyControl; + /* GUC variable: time in seconds between statistics reports */ int DebugSharedBuffers = 0; @@ -813,6 +863,28 @@ StrategyDirtyBufferList(BufferDesc **buffers, BufferTag *buftags, /* + * StrategyShmemSize + * + * estimate the size of shared memory used by the freelist-related structures. + */ +int +StrategyShmemSize(void) +{ + int size = 0; + + /* size of CDB lookup hash table */ + size += BufTableShmemSize(NBuffers * 2); + + /* size of the shared replacement strategy control block */ + size += MAXALIGN(sizeof(BufferStrategyControl)); + + /* size of the ARC directory blocks */ + size += MAXALIGN(NBuffers * 2 * sizeof(BufferStrategyCDB)); + + return size; +} + +/* * StrategyInitialize -- initialize the buffer cache replacement * strategy. * |