1996-08-28 01:59:28 +00:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-13 23:22:53 +00:00
|
|
|
* bufmgr.h
|
1997-09-07 05:04:48 +00:00
|
|
|
* POSTGRES buffer manager definitions.
|
1996-08-28 01:59:28 +00:00
|
|
|
*
|
|
|
|
*
|
2013-01-01 17:15:01 -05:00
|
|
|
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
|
2000-01-26 05:58:53 +00:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-08-28 01:59:28 +00:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/storage/bufmgr.h
|
1996-08-28 01:59:28 +00:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
1997-09-07 05:04:48 +00:00
|
|
|
#ifndef BUFMGR_H
|
1996-08-28 01:59:28 +00:00
|
|
|
#define BUFMGR_H
|
|
|
|
|
2008-06-19 00:46:06 +00:00
|
|
|
#include "storage/block.h"
|
2000-11-30 01:39:08 +00:00
|
|
|
#include "storage/buf.h"
|
2008-06-08 22:00:48 +00:00
|
|
|
#include "storage/bufpage.h"
|
2008-06-19 00:46:06 +00:00
|
|
|
#include "storage/relfilenode.h"
|
|
|
|
#include "utils/relcache.h"
|
1996-08-28 01:59:28 +00:00
|
|
|
|
1998-01-13 04:05:12 +00:00
|
|
|
typedef void *Block;
|
1996-08-28 01:59:28 +00:00
|
|
|
|
2007-05-30 20:12:03 +00:00
|
|
|
/* Possible arguments for GetAccessStrategy() */
|
|
|
|
typedef enum BufferAccessStrategyType
|
|
|
|
{
|
2007-11-15 21:14:46 +00:00
|
|
|
BAS_NORMAL, /* Normal random access */
|
|
|
|
BAS_BULKREAD, /* Large read-only scan (hint bit updates are
|
|
|
|
* ok) */
|
2008-11-06 20:51:15 +00:00
|
|
|
BAS_BULKWRITE, /* Large multi-block write (e.g. COPY IN) */
|
2007-11-15 21:14:46 +00:00
|
|
|
BAS_VACUUM /* VACUUM */
|
2007-11-15 22:25:18 +00:00
|
|
|
} BufferAccessStrategyType;
|
2007-05-30 20:12:03 +00:00
|
|
|
|
Unite ReadBufferWithFork, ReadBufferWithStrategy, and ZeroOrReadBuffer
functions into one ReadBufferExtended function, that takes the strategy
and mode as argument. There's three modes, RBM_NORMAL which is the default
used by plain ReadBuffer(), RBM_ZERO, which replaces ZeroOrReadBuffer, and
a new mode RBM_ZERO_ON_ERROR, which allows callers to read corrupt pages
without throwing an error. The FSM needs the new mode to recover from
corrupt pages, which could happend if we crash after extending an FSM file,
and the new page is "torn".
Add fork number to some error messages in bufmgr.c, that still lacked it.
2008-10-31 15:05:00 +00:00
|
|
|
/* Possible modes for ReadBufferExtended() */
|
|
|
|
typedef enum
|
|
|
|
{
|
2009-06-11 14:49:15 +00:00
|
|
|
RBM_NORMAL, /* Normal read */
|
|
|
|
RBM_ZERO, /* Don't read from disk, caller will
|
|
|
|
* initialize */
|
|
|
|
RBM_ZERO_ON_ERROR /* Read, but return an all-zeros page on error */
|
Unite ReadBufferWithFork, ReadBufferWithStrategy, and ZeroOrReadBuffer
functions into one ReadBufferExtended function, that takes the strategy
and mode as argument. There's three modes, RBM_NORMAL which is the default
used by plain ReadBuffer(), RBM_ZERO, which replaces ZeroOrReadBuffer, and
a new mode RBM_ZERO_ON_ERROR, which allows callers to read corrupt pages
without throwing an error. The FSM needs the new mode to recover from
corrupt pages, which could happend if we crash after extending an FSM file,
and the new page is "torn".
Add fork number to some error messages in bufmgr.c, that still lacked it.
2008-10-31 15:05:00 +00:00
|
|
|
} ReadBufferMode;
|
|
|
|
|
2000-11-30 01:39:08 +00:00
|
|
|
/* in globals.c ... this duplicates miscadmin.h */
|
2007-07-25 12:22:54 +00:00
|
|
|
extern PGDLLIMPORT int NBuffers;
|
2000-11-30 01:39:08 +00:00
|
|
|
|
2003-03-28 20:17:13 +00:00
|
|
|
/* in bufmgr.c */
|
|
|
|
extern bool zero_damaged_pages;
|
2005-03-04 20:21:07 +00:00
|
|
|
extern int bgwriter_lru_maxpages;
|
2007-09-25 20:03:38 +00:00
|
|
|
extern double bgwriter_lru_multiplier;
|
2012-04-29 16:23:54 -04:00
|
|
|
extern bool track_io_timing;
|
2009-01-12 05:10:45 +00:00
|
|
|
extern int target_prefetch_pages;
|
2003-03-28 20:17:13 +00:00
|
|
|
|
2000-11-30 01:39:08 +00:00
|
|
|
/* in buf_init.c */
|
2007-07-25 12:22:54 +00:00
|
|
|
extern PGDLLIMPORT char *BufferBlocks;
|
|
|
|
extern PGDLLIMPORT int32 *PrivateRefCount;
|
2000-11-30 01:39:08 +00:00
|
|
|
|
|
|
|
/* in localbuf.c */
|
2007-07-25 12:22:54 +00:00
|
|
|
extern PGDLLIMPORT int NLocBuffer;
|
|
|
|
extern PGDLLIMPORT Block *LocalBufferBlockPointers;
|
|
|
|
extern PGDLLIMPORT int32 *LocalRefCount;
|
2000-11-30 01:39:08 +00:00
|
|
|
|
2004-04-25 23:50:58 +00:00
|
|
|
/* special block number for ReadBuffer() */
|
1997-09-07 05:04:48 +00:00
|
|
|
#define P_NEW InvalidBlockNumber /* grow the file to get a new page */
|
1996-08-28 01:59:28 +00:00
|
|
|
|
2000-11-30 01:39:08 +00:00
|
|
|
/*
|
2005-03-04 20:21:07 +00:00
|
|
|
* Buffer content lock modes (mode argument for LockBuffer())
|
2000-11-30 01:39:08 +00:00
|
|
|
*/
|
|
|
|
#define BUFFER_LOCK_UNLOCK 0
|
|
|
|
#define BUFFER_LOCK_SHARE 1
|
|
|
|
#define BUFFER_LOCK_EXCLUSIVE 2
|
|
|
|
|
1996-08-28 01:59:28 +00:00
|
|
|
/*
|
|
|
|
* These routines are beaten on quite heavily, hence the macroization.
|
|
|
|
*/
|
|
|
|
|
1998-04-24 14:43:33 +00:00
|
|
|
/*
|
1999-05-25 16:15:34 +00:00
|
|
|
* BufferIsValid
|
1999-09-24 00:25:33 +00:00
|
|
|
* True iff the given buffer number is valid (either as a shared
|
|
|
|
* or local buffer).
|
|
|
|
*
|
|
|
|
* Note: For a long time this was defined the same as BufferIsPinned,
|
|
|
|
* that is it would say False if you didn't hold a pin on the buffer.
|
|
|
|
* I believe this was bogus and served only to mask logic errors.
|
|
|
|
* Code should always know whether it has a buffer reference,
|
|
|
|
* independently of the pin state.
|
2011-10-28 17:04:22 -04:00
|
|
|
*
|
|
|
|
* Note: For a further long time this was not quite the inverse of the
|
|
|
|
* BufferIsInvalid() macro, in that it also did sanity checks to verify
|
|
|
|
* that the buffer number was in range. Most likely, this macro was
|
|
|
|
* originally intended only to be used in assertions, but its use has
|
|
|
|
* since expanded quite a bit, and the overhead of making those checks
|
|
|
|
* even in non-assert-enabled builds can be significant. Thus, we've
|
|
|
|
* now demoted the range checks to assertions within the macro itself.
|
1998-04-24 14:43:33 +00:00
|
|
|
*/
|
|
|
|
#define BufferIsValid(bufnum) \
|
1999-09-24 00:25:33 +00:00
|
|
|
( \
|
2011-10-28 17:04:22 -04:00
|
|
|
AssertMacro((bufnum) <= NBuffers && (bufnum) >= -NLocBuffer), \
|
|
|
|
(bufnum) != InvalidBuffer \
|
1999-09-24 00:25:33 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BufferIsPinned
|
|
|
|
* True iff the buffer is pinned (also checks for valid buffer number).
|
|
|
|
*
|
|
|
|
* NOTE: what we check here is that *this* backend holds a pin on
|
|
|
|
* the buffer. We do not care whether some other backend does.
|
|
|
|
*/
|
|
|
|
#define BufferIsPinned(bufnum) \
|
1998-04-24 14:43:33 +00:00
|
|
|
( \
|
2004-10-15 22:40:29 +00:00
|
|
|
!BufferIsValid(bufnum) ? \
|
|
|
|
false \
|
1998-04-24 14:43:33 +00:00
|
|
|
: \
|
2004-10-15 22:40:29 +00:00
|
|
|
BufferIsLocal(bufnum) ? \
|
|
|
|
(LocalRefCount[-(bufnum) - 1] > 0) \
|
1998-04-24 14:43:33 +00:00
|
|
|
: \
|
|
|
|
(PrivateRefCount[(bufnum) - 1] > 0) \
|
|
|
|
)
|
|
|
|
|
|
|
|
/*
|
1999-05-25 16:15:34 +00:00
|
|
|
* BufferGetBlock
|
1998-04-24 14:43:33 +00:00
|
|
|
* Returns a reference to a disk page image associated with a buffer.
|
|
|
|
*
|
|
|
|
* Note:
|
|
|
|
* Assumes buffer is valid.
|
|
|
|
*/
|
|
|
|
#define BufferGetBlock(buffer) \
|
|
|
|
( \
|
1998-06-15 18:40:05 +00:00
|
|
|
AssertMacro(BufferIsValid(buffer)), \
|
1998-04-24 14:43:33 +00:00
|
|
|
BufferIsLocal(buffer) ? \
|
2000-11-30 01:39:08 +00:00
|
|
|
LocalBufferBlockPointers[-(buffer) - 1] \
|
1998-04-24 14:43:33 +00:00
|
|
|
: \
|
2005-08-12 05:05:51 +00:00
|
|
|
(Block) (BufferBlocks + ((Size) ((buffer) - 1)) * BLCKSZ) \
|
1998-04-24 14:43:33 +00:00
|
|
|
)
|
|
|
|
|
2008-06-08 22:00:48 +00:00
|
|
|
/*
|
|
|
|
* BufferGetPageSize
|
|
|
|
* Returns the page size within a buffer.
|
|
|
|
*
|
|
|
|
* Notes:
|
|
|
|
* Assumes buffer is valid.
|
|
|
|
*
|
|
|
|
* The buffer can be a raw disk block and need not contain a valid
|
|
|
|
* (formatted) disk page.
|
|
|
|
*/
|
|
|
|
/* XXX should dig out of buffer descriptor */
|
|
|
|
#define BufferGetPageSize(buffer) \
|
|
|
|
( \
|
|
|
|
AssertMacro(BufferIsValid(buffer)), \
|
|
|
|
(Size)BLCKSZ \
|
|
|
|
)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BufferGetPage
|
|
|
|
* Returns the page associated with a buffer.
|
|
|
|
*/
|
|
|
|
#define BufferGetPage(buffer) ((Page)BufferGetBlock(buffer))
|
|
|
|
|
1996-08-28 01:59:28 +00:00
|
|
|
/*
|
1997-09-07 05:04:48 +00:00
|
|
|
* prototypes for functions in bufmgr.c
|
1996-08-28 01:59:28 +00:00
|
|
|
*/
|
2009-01-12 05:10:45 +00:00
|
|
|
extern void PrefetchBuffer(Relation reln, ForkNumber forkNum,
|
2009-06-11 14:49:15 +00:00
|
|
|
BlockNumber blockNum);
|
1997-09-08 02:41:22 +00:00
|
|
|
extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
|
Unite ReadBufferWithFork, ReadBufferWithStrategy, and ZeroOrReadBuffer
functions into one ReadBufferExtended function, that takes the strategy
and mode as argument. There's three modes, RBM_NORMAL which is the default
used by plain ReadBuffer(), RBM_ZERO, which replaces ZeroOrReadBuffer, and
a new mode RBM_ZERO_ON_ERROR, which allows callers to read corrupt pages
without throwing an error. The FSM needs the new mode to recover from
corrupt pages, which could happend if we crash after extending an FSM file,
and the new page is "torn".
Add fork number to some error messages in bufmgr.c, that still lacked it.
2008-10-31 15:05:00 +00:00
|
|
|
extern Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum,
|
2009-06-11 14:49:15 +00:00
|
|
|
BlockNumber blockNum, ReadBufferMode mode,
|
|
|
|
BufferAccessStrategy strategy);
|
2010-08-13 20:10:54 +00:00
|
|
|
extern Buffer ReadBufferWithoutRelcache(RelFileNode rnode,
|
2009-06-11 14:49:15 +00:00
|
|
|
ForkNumber forkNum, BlockNumber blockNum,
|
|
|
|
ReadBufferMode mode, BufferAccessStrategy strategy);
|
2004-04-21 18:06:30 +00:00
|
|
|
extern void ReleaseBuffer(Buffer buffer);
|
2006-03-31 23:32:07 +00:00
|
|
|
extern void UnlockReleaseBuffer(Buffer buffer);
|
|
|
|
extern void MarkBufferDirty(Buffer buffer);
|
2004-07-17 03:32:14 +00:00
|
|
|
extern void IncrBufferRefCount(Buffer buffer);
|
1998-09-01 04:40:42 +00:00
|
|
|
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
|
2001-10-25 05:50:21 +00:00
|
|
|
BlockNumber blockNum);
|
1997-09-07 05:04:48 +00:00
|
|
|
|
2000-11-28 23:27:57 +00:00
|
|
|
extern void InitBufferPool(void);
|
2000-12-18 00:44:50 +00:00
|
|
|
extern void InitBufferPoolAccess(void);
|
2005-08-08 03:12:16 +00:00
|
|
|
extern void InitBufferPoolBackend(void);
|
2002-08-06 02:36:35 +00:00
|
|
|
extern void AtEOXact_Buffers(bool isCommit);
|
2004-10-16 18:57:26 +00:00
|
|
|
extern void PrintBufferLeakWarning(Buffer buffer);
|
2007-06-28 00:02:40 +00:00
|
|
|
extern void CheckPointBuffers(int flags);
|
1996-08-28 01:59:28 +00:00
|
|
|
extern BlockNumber BufferGetBlockNumber(Buffer buffer);
|
2010-12-29 06:48:53 -05:00
|
|
|
extern BlockNumber RelationGetNumberOfBlocksInFork(Relation relation,
|
|
|
|
ForkNumber forkNum);
|
2005-03-20 22:00:54 +00:00
|
|
|
extern void FlushRelationBuffers(Relation rel);
|
2007-06-28 00:02:40 +00:00
|
|
|
extern void FlushDatabaseBuffers(Oid dbid);
|
2010-08-13 20:10:54 +00:00
|
|
|
extern void DropRelFileNodeBuffers(RelFileNodeBackend rnode,
|
|
|
|
ForkNumber forkNum, BlockNumber firstDelBlock);
|
Accelerate end-of-transaction dropping of relations
When relations are dropped, at end of transaction we need to remove the
files and clean the buffer pool of buffers containing pages of those
relations. Previously we would scan the buffer pool once per relation
to clean up buffers. When there are many relations to drop, the
repeated scans make this process slow; so we now instead pass a list of
relations to drop and scan the pool once, checking each buffer against
the passed list. When the number of relations is larger than a
threshold (which as of this patch is being set to 20 relations) we sort
the array before starting, and bsearch the array; when it's smaller, we
simply scan the array linearly each time, because that's faster. The
exact optimal threshold value depends on many factors, but the
difference is not likely to be significant enough to justify making it
user-settable.
This has been measured to be a significant win (a 15x win when dropping
100,000 relations; an extreme case, but reportedly a real one).
Author: Tomas Vondra, some tweaks by me
Reviewed by: Robert Haas, Shigeru Hanada, Andres Freund, Álvaro Herrera
2013-01-17 15:55:10 -03:00
|
|
|
extern void DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes);
|
2006-03-29 21:17:39 +00:00
|
|
|
extern void DropDatabaseBuffers(Oid dbid);
|
2002-09-04 20:31:48 +00:00
|
|
|
|
2010-12-29 06:48:53 -05:00
|
|
|
#define RelationGetNumberOfBlocks(reln) \
|
|
|
|
RelationGetNumberOfBlocksInFork(reln, MAIN_FORKNUM)
|
|
|
|
|
2011-10-28 17:08:09 -04:00
|
|
|
extern bool BufferIsPermanent(Buffer buffer);
|
|
|
|
|
2002-07-02 05:47:37 +00:00
|
|
|
#ifdef NOT_USED
|
1997-09-08 02:41:22 +00:00
|
|
|
extern void PrintPinnedBufs(void);
|
2002-07-02 05:47:37 +00:00
|
|
|
#endif
|
2005-08-20 23:26:37 +00:00
|
|
|
extern Size BufferShmemSize(void);
|
2009-06-11 14:49:15 +00:00
|
|
|
extern void BufferGetTag(Buffer buffer, RelFileNode *rnode,
|
|
|
|
ForkNumber *forknum, BlockNumber *blknum);
|
1997-09-08 02:41:22 +00:00
|
|
|
|
|
|
|
extern void SetBufferCommitInfoNeedsSave(Buffer buffer);
|
1997-09-07 05:04:48 +00:00
|
|
|
|
1998-12-15 12:47:01 +00:00
|
|
|
extern void UnlockBuffers(void);
|
|
|
|
extern void LockBuffer(Buffer buffer, int mode);
|
2003-08-10 19:48:08 +00:00
|
|
|
extern bool ConditionalLockBuffer(Buffer buffer);
|
2001-07-06 21:04:26 +00:00
|
|
|
extern void LockBufferForCleanup(Buffer buffer);
|
2007-09-20 17:56:33 +00:00
|
|
|
extern bool ConditionalLockBufferForCleanup(Buffer buffer);
|
2010-01-23 16:37:12 +00:00
|
|
|
extern bool HoldingBufferPinThatDelaysRecovery(void);
|
1998-12-15 12:47:01 +00:00
|
|
|
|
2001-07-06 21:04:26 +00:00
|
|
|
extern void AbortBufferIO(void);
|
2000-10-20 11:01:21 +00:00
|
|
|
|
2000-10-28 16:21:00 +00:00
|
|
|
extern void BufmgrCommit(void);
|
2012-01-26 18:19:48 +02:00
|
|
|
extern bool BgBufferSync(void);
|
2000-10-28 16:21:00 +00:00
|
|
|
|
2005-03-18 16:16:09 +00:00
|
|
|
extern void AtProcExit_LocalBuffers(void);
|
2001-10-28 06:26:15 +00:00
|
|
|
|
2005-03-04 20:21:07 +00:00
|
|
|
/* in freelist.c */
|
2007-05-30 20:12:03 +00:00
|
|
|
extern BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype);
|
|
|
|
extern void FreeAccessStrategy(BufferAccessStrategy strategy);
|
2005-03-04 20:21:07 +00:00
|
|
|
|
1999-09-24 00:25:33 +00:00
|
|
|
#endif
|