diff options
| author | Tom Lane | 2007-05-30 20:12:03 +0000 |
|---|---|---|
| committer | Tom Lane | 2007-05-30 20:12:03 +0000 |
| commit | d526575f893c1a4e05ebd307e80203536b213a6d (patch) | |
| tree | 529be7e5571f622bad1daab0d02de0c6669e9b81 /src/include | |
| parent | 0a6f2ee84de589e14941da640fb686c7eda7be01 (diff) | |
Make large sequential scans and VACUUMs work in a limited-size "ring" of
buffers, rather than blowing out the whole shared-buffer arena. Aside from
avoiding cache spoliation, this fixes the problem that VACUUM formerly tended
to cause a WAL flush for every page it modified, because we had it hacked to
use only a single buffer. Those flushes will now occur only once per
ring-ful. The exact ring size, and the threshold for seqscans to switch into
the ring usage pattern, remain under debate; but the infrastructure seems
done. The key bit of infrastructure is a new optional BufferAccessStrategy
object that can be passed to ReadBuffer operations; this replaces the former
StrategyHintVacuum API.
This patch also changes the buffer usage-count methodology a bit: we now
advance usage_count when first pinning a buffer, rather than when last
unpinning it. To preserve the behavior that a buffer's lifetime starts to
decrease when it's released, the clock sweep code is modified to not decrement
usage_count of pinned buffers.
Work not done in this commit: teach GiST and GIN indexes to use the vacuum
BufferAccessStrategy for vacuum-driven fetches.
Original patch by Simon, reworked by Heikki and again by Tom.
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/access/genam.h | 3 | ||||
| -rw-r--r-- | src/include/access/hash.h | 11 | ||||
| -rw-r--r-- | src/include/access/relscan.h | 3 | ||||
| -rw-r--r-- | src/include/access/xlog.h | 3 | ||||
| -rw-r--r-- | src/include/commands/vacuum.h | 13 | ||||
| -rw-r--r-- | src/include/storage/buf.h | 9 | ||||
| -rw-r--r-- | src/include/storage/buf_internals.h | 13 | ||||
| -rw-r--r-- | src/include/storage/bufmgr.h | 15 |
8 files changed, 51 insertions, 19 deletions
diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 1f31baf0e45..98296e62bef 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.66 2007/01/05 22:19:50 momjian Exp $ + * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.67 2007/05/30 20:12:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -40,6 +40,7 @@ typedef struct IndexVacuumInfo bool vacuum_full; /* VACUUM FULL (we have exclusive lock) */ int message_level; /* ereport level for progress messages */ double num_heap_tuples; /* tuples remaining in heap */ + BufferAccessStrategy strategy; /* access strategy for reads */ } IndexVacuumInfo; /* diff --git a/src/include/access/hash.h b/src/include/access/hash.h index d382ee6ee91..2bd314a8aa3 100644 --- a/src/include/access/hash.h +++ b/src/include/access/hash.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.80 2007/05/03 16:45:58 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.81 2007/05/30 20:12:02 tgl Exp $ * * NOTES * modeled after Margo Seltzer's hash implementation for unix. @@ -273,11 +273,13 @@ extern void _hash_doinsert(Relation rel, IndexTuple itup); /* hashovfl.c */ extern Buffer _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf); -extern BlockNumber _hash_freeovflpage(Relation rel, Buffer ovflbuf); +extern BlockNumber _hash_freeovflpage(Relation rel, Buffer ovflbuf, + BufferAccessStrategy bstrategy); extern void _hash_initbitmap(Relation rel, HashMetaPage metap, BlockNumber blkno); extern void _hash_squeezebucket(Relation rel, - Bucket bucket, BlockNumber bucket_blkno); + Bucket bucket, BlockNumber bucket_blkno, + BufferAccessStrategy bstrategy); /* hashpage.c */ extern void _hash_getlock(Relation rel, BlockNumber whichlock, int access); @@ -287,6 +289,9 @@ extern Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags); extern Buffer _hash_getinitbuf(Relation rel, BlockNumber blkno); extern Buffer _hash_getnewbuf(Relation rel, BlockNumber blkno); +extern Buffer _hash_getbuf_with_strategy(Relation rel, BlockNumber blkno, + int access, int flags, + BufferAccessStrategy bstrategy); extern void _hash_relbuf(Relation rel, Buffer buf); extern void _hash_dropbuf(Relation rel, Buffer buf); extern void _hash_wrtbuf(Relation rel, Buffer buf); diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index 7a1ea39352a..200b45713e7 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.53 2007/05/27 03:50:39 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.54 2007/05/30 20:12:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ typedef struct HeapScanDescData int rs_nkeys; /* number of scan keys */ ScanKey rs_key; /* array of scan key descriptors */ BlockNumber rs_nblocks; /* number of blocks to scan */ + BufferAccessStrategy rs_strategy; /* access strategy for reads */ bool rs_pageatatime; /* verify visibility page-at-a-time? */ /* scan current state */ diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 87ff6aba501..1c741f38fd0 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.77 2007/05/20 21:08:19 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.78 2007/05/30 20:12:02 tgl Exp $ */ #ifndef XLOG_H #define XLOG_H @@ -159,6 +159,7 @@ extern bool XLOG_DEBUG; extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata); extern void XLogFlush(XLogRecPtr RecPtr); +extern bool XLogNeedsFlush(XLogRecPtr RecPtr); extern void xlog_redo(XLogRecPtr lsn, XLogRecord *record); extern void xlog_desc(StringInfo buf, uint8 xl_info, char *rec); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index acb2f623e27..50a475bc5e3 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.71 2007/05/17 15:28:29 alvherre Exp $ + * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.72 2007/05/30 20:12:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,9 +18,11 @@ #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" #include "nodes/parsenodes.h" +#include "storage/buf.h" #include "storage/lock.h" #include "utils/rel.h" + /*---------- * ANALYZE builds one of these structs for each attribute (column) that is * to be analyzed. The struct and subsidiary data are in anl_context, @@ -110,7 +112,8 @@ extern int vacuum_freeze_min_age; /* in commands/vacuum.c */ -extern void vacuum(VacuumStmt *vacstmt, List *relids, bool isTopLevel); +extern void vacuum(VacuumStmt *vacstmt, List *relids, + BufferAccessStrategy bstrategy, bool isTopLevel); extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, int *nindexes, Relation **Irel); extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); @@ -127,9 +130,11 @@ extern bool vac_is_partial_index(Relation indrel); extern void vacuum_delay_point(void); /* in commands/vacuumlazy.c */ -extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt); +extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, + BufferAccessStrategy bstrategy); /* in commands/analyze.c */ -extern void analyze_rel(Oid relid, VacuumStmt *vacstmt); +extern void analyze_rel(Oid relid, VacuumStmt *vacstmt, + BufferAccessStrategy bstrategy); #endif /* VACUUM_H */ diff --git a/src/include/storage/buf.h b/src/include/storage/buf.h index 94da564d1eb..a812a9e269a 100644 --- a/src/include/storage/buf.h +++ b/src/include/storage/buf.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/storage/buf.h,v 1.21 2007/01/05 22:19:57 momjian Exp $ + * $PostgreSQL: pgsql/src/include/storage/buf.h,v 1.22 2007/05/30 20:12:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,4 +36,11 @@ typedef int Buffer; */ #define BufferIsLocal(buffer) ((buffer) < 0) +/* + * Buffer access strategy objects. + * + * BufferAccessStrategyData is private to freelist.c + */ +typedef struct BufferAccessStrategyData *BufferAccessStrategy; + #endif /* BUF_H */ diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index 561b7e40f69..d5eef8734ff 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.89 2007/01/05 22:19:57 momjian Exp $ + * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.90 2007/05/30 20:12:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -167,9 +167,6 @@ extern DLLIMPORT BufferDesc *BufferDescriptors; /* in localbuf.c */ extern BufferDesc *LocalBufferDescriptors; -/* in freelist.c */ -extern bool strategy_hint_vacuum; - /* event counters in buf_init.c */ extern long int ReadBufferCount; extern long int ReadLocalBufferCount; @@ -184,8 +181,12 @@ extern long int LocalBufferFlushCount; */ /* freelist.c */ -extern volatile BufferDesc *StrategyGetBuffer(void); -extern void StrategyFreeBuffer(volatile BufferDesc *buf, bool at_head); +extern volatile BufferDesc *StrategyGetBuffer(BufferAccessStrategy strategy, + bool *lock_held); +extern void StrategyFreeBuffer(volatile BufferDesc *buf); +extern bool StrategyRejectBuffer(BufferAccessStrategy strategy, + volatile BufferDesc *buf); + extern int StrategySyncStart(void); extern Size StrategyShmemSize(void); extern void StrategyInitialize(bool init); diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index ad203621793..9ae83b4253e 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.103 2007/05/02 23:18:03 tgl Exp $ + * $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.104 2007/05/30 20:12:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,6 +19,14 @@ typedef void *Block; +/* Possible arguments for GetAccessStrategy() */ +typedef enum BufferAccessStrategyType +{ + BAS_NORMAL, /* Normal random access */ + BAS_BULKREAD, /* Large read-only scan (hint bit updates are ok) */ + BAS_VACUUM /* VACUUM */ +} BufferAccessStrategyType; + /* in globals.c ... this duplicates miscadmin.h */ extern DLLIMPORT int NBuffers; @@ -111,6 +119,8 @@ extern DLLIMPORT int32 *LocalRefCount; * prototypes for functions in bufmgr.c */ extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum); +extern Buffer ReadBufferWithStrategy(Relation reln, BlockNumber blockNum, + BufferAccessStrategy strategy); extern Buffer ReadOrZeroBuffer(Relation reln, BlockNumber blockNum); extern void ReleaseBuffer(Buffer buffer); extern void UnlockReleaseBuffer(Buffer buffer); @@ -157,6 +167,7 @@ extern void BgBufferSync(void); extern void AtProcExit_LocalBuffers(void); /* in freelist.c */ -extern void StrategyHintVacuum(bool vacuum_active); +extern BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype); +extern void FreeAccessStrategy(BufferAccessStrategy strategy); #endif |
