1 /*-------------------------------------------------------------------------
4 * POSTGRES buffer manager definitions.
7 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
12 *-------------------------------------------------------------------------
17 #include "storage/block.h"
18 #include "storage/buf.h"
19 #include "storage/bufpage.h"
20 #include "storage/relfilenode.h"
21 #include "utils/relcache.h"
25 /* Possible arguments for GetAccessStrategy() */
26 typedef enum BufferAccessStrategyType
28 BAS_NORMAL
, /* Normal random access */
29 BAS_BULKREAD
, /* Large read-only scan (hint bit updates are
31 BAS_VACUUM
/* VACUUM */
32 } BufferAccessStrategyType
;
34 /* Possible modes for ReadBufferExtended() */
37 RBM_NORMAL
, /* Normal read */
38 RBM_ZERO
, /* Don't read from disk, caller will initialize */
39 RBM_ZERO_ON_ERROR
/* Read, but return an all-zeros page on error */
42 /* in globals.c ... this duplicates miscadmin.h */
43 extern PGDLLIMPORT
int NBuffers
;
46 extern bool zero_damaged_pages
;
47 extern int bgwriter_lru_maxpages
;
48 extern double bgwriter_lru_multiplier
;
51 extern PGDLLIMPORT
char *BufferBlocks
;
52 extern PGDLLIMPORT int32
*PrivateRefCount
;
55 extern PGDLLIMPORT
int NLocBuffer
;
56 extern PGDLLIMPORT Block
*LocalBufferBlockPointers
;
57 extern PGDLLIMPORT int32
*LocalRefCount
;
59 /* special block number for ReadBuffer() */
60 #define P_NEW InvalidBlockNumber /* grow the file to get a new page */
63 * Buffer content lock modes (mode argument for LockBuffer())
65 #define BUFFER_LOCK_UNLOCK 0
66 #define BUFFER_LOCK_SHARE 1
67 #define BUFFER_LOCK_EXCLUSIVE 2
70 * These routines are beaten on quite heavily, hence the macroization.
75 * True iff the given buffer number is valid (either as a shared
78 * This is not quite the inverse of the BufferIsInvalid() macro, since this
79 * adds sanity rangechecks on the buffer number.
81 * Note: For a long time this was defined the same as BufferIsPinned,
82 * that is it would say False if you didn't hold a pin on the buffer.
83 * I believe this was bogus and served only to mask logic errors.
84 * Code should always know whether it has a buffer reference,
85 * independently of the pin state.
87 #define BufferIsValid(bufnum) \
89 (bufnum) != InvalidBuffer && \
90 (bufnum) >= -NLocBuffer && \
91 (bufnum) <= NBuffers \
96 * True iff the buffer is pinned (also checks for valid buffer number).
98 * NOTE: what we check here is that *this* backend holds a pin on
99 * the buffer. We do not care whether some other backend does.
101 #define BufferIsPinned(bufnum) \
103 !BufferIsValid(bufnum) ? \
106 BufferIsLocal(bufnum) ? \
107 (LocalRefCount[-(bufnum) - 1] > 0) \
109 (PrivateRefCount[(bufnum) - 1] > 0) \
114 * Returns a reference to a disk page image associated with a buffer.
117 * Assumes buffer is valid.
119 #define BufferGetBlock(buffer) \
121 AssertMacro(BufferIsValid(buffer)), \
122 BufferIsLocal(buffer) ? \
123 LocalBufferBlockPointers[-(buffer) - 1] \
125 (Block) (BufferBlocks + ((Size) ((buffer) - 1)) * BLCKSZ) \
130 * Returns the page size within a buffer.
133 * Assumes buffer is valid.
135 * The buffer can be a raw disk block and need not contain a valid
136 * (formatted) disk page.
138 /* XXX should dig out of buffer descriptor */
139 #define BufferGetPageSize(buffer) \
141 AssertMacro(BufferIsValid(buffer)), \
147 * Returns the page associated with a buffer.
149 #define BufferGetPage(buffer) ((Page)BufferGetBlock(buffer))
152 * prototypes for functions in bufmgr.c
154 extern Buffer
ReadBuffer(Relation reln
, BlockNumber blockNum
);
155 extern Buffer
ReadBufferExtended(Relation reln
, ForkNumber forkNum
,
156 BlockNumber blockNum
, ReadBufferMode mode
,
157 BufferAccessStrategy strategy
);
158 extern Buffer
ReadBufferWithoutRelcache(RelFileNode rnode
, bool isTemp
,
159 ForkNumber forkNum
, BlockNumber blockNum
,
160 ReadBufferMode mode
, BufferAccessStrategy strategy
);
161 extern void ReleaseBuffer(Buffer buffer
);
162 extern void UnlockReleaseBuffer(Buffer buffer
);
163 extern void MarkBufferDirty(Buffer buffer
);
164 extern void IncrBufferRefCount(Buffer buffer
);
165 extern Buffer
ReleaseAndReadBuffer(Buffer buffer
, Relation relation
,
166 BlockNumber blockNum
);
168 extern void InitBufferPool(void);
169 extern void InitBufferPoolAccess(void);
170 extern void InitBufferPoolBackend(void);
171 extern char *ShowBufferUsage(void);
172 extern void ResetBufferUsage(void);
173 extern void AtEOXact_Buffers(bool isCommit
);
174 extern void PrintBufferLeakWarning(Buffer buffer
);
175 extern void CheckPointBuffers(int flags
);
176 extern BlockNumber
BufferGetBlockNumber(Buffer buffer
);
177 extern BlockNumber
RelationGetNumberOfBlocks(Relation relation
);
178 extern void RelationTruncate(Relation rel
, BlockNumber nblocks
);
179 extern void FlushRelationBuffers(Relation rel
);
180 extern void FlushDatabaseBuffers(Oid dbid
);
181 extern void DropRelFileNodeBuffers(RelFileNode rnode
, ForkNumber forkNum
,
182 bool istemp
, BlockNumber firstDelBlock
);
183 extern void DropDatabaseBuffers(Oid dbid
);
186 extern void PrintPinnedBufs(void);
188 extern Size
BufferShmemSize(void);
189 extern void BufferGetTag(Buffer buffer
, RelFileNode
*rnode
,
190 ForkNumber
*forknum
, BlockNumber
*blknum
);
192 extern void SetBufferCommitInfoNeedsSave(Buffer buffer
);
194 extern void UnlockBuffers(void);
195 extern void LockBuffer(Buffer buffer
, int mode
);
196 extern bool ConditionalLockBuffer(Buffer buffer
);
197 extern void LockBufferForCleanup(Buffer buffer
);
198 extern bool ConditionalLockBufferForCleanup(Buffer buffer
);
200 extern void AbortBufferIO(void);
202 extern void BufmgrCommit(void);
203 extern void BgBufferSync(void);
205 extern void AtProcExit_LocalBuffers(void);
208 extern BufferAccessStrategy
GetAccessStrategy(BufferAccessStrategyType btype
);
209 extern void FreeAccessStrategy(BufferAccessStrategy strategy
);