Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
bufmgr.h394 linesDownload Raw Back to storage
1/*-------------------------------------------------------------------------2 *3 * bufmgr.h4 *	  POSTGRES buffer manager definitions.5 *6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 * Portions Copyright (c) 1994, Regents of the University of California9 *10 * src/include/storage/bufmgr.h11 *12 *-------------------------------------------------------------------------13 */14#ifndef BUFMGR_H15#define BUFMGR_H16 17#include "storage/block.h"18#include "storage/buf.h"19#include "storage/bufpage.h"20#include "storage/relfilelocator.h"21#include "utils/relcache.h"22#include "utils/snapmgr.h"23 24typedef void *Block;25 26/*27 * Possible arguments for GetAccessStrategy().28 *29 * If adding a new BufferAccessStrategyType, also add a new IOContext so30 * IO statistics using this strategy are tracked.31 */32typedef enum BufferAccessStrategyType33{34	BAS_NORMAL,					/* Normal random access */35	BAS_BULKREAD,				/* Large read-only scan (hint bit updates are36								 * ok) */37	BAS_BULKWRITE,				/* Large multi-block write (e.g. COPY IN) */38	BAS_VACUUM					/* VACUUM */39} BufferAccessStrategyType;40 41/* Possible modes for ReadBufferExtended() */42typedef enum43{44	RBM_NORMAL,					/* Normal read */45	RBM_ZERO_AND_LOCK,			/* Don't read from disk, caller will46								 * initialize. Also locks the page. */47	RBM_ZERO_AND_CLEANUP_LOCK,	/* Like RBM_ZERO_AND_LOCK, but locks the page48								 * in "cleanup" mode */49	RBM_ZERO_ON_ERROR,			/* Read, but return an all-zeros page on error */50	RBM_NORMAL_NO_LOG			/* Don't log page as invalid during WAL51								 * replay; otherwise same as RBM_NORMAL */52} ReadBufferMode;53 54/*55 * Type returned by PrefetchBuffer().56 */57typedef struct PrefetchBufferResult58{59	Buffer		recent_buffer;	/* If valid, a hit (recheck needed!) */60	bool		initiated_io;	/* If true, a miss resulting in async I/O */61} PrefetchBufferResult;62 63/*64 * Flags influencing the behaviour of ExtendBufferedRel*65 */66typedef enum ExtendBufferedFlags67{68	/*69	 * Don't acquire extension lock. This is safe only if the relation isn't70	 * shared, an access exclusive lock is held or if this is the startup71	 * process.72	 */73	EB_SKIP_EXTENSION_LOCK = (1 << 0),74 75	/* Is this extension part of recovery? */76	EB_PERFORMING_RECOVERY = (1 << 1),77 78	/*79	 * Should the fork be created if it does not currently exist? This likely80	 * only ever makes sense for relation forks.81	 */82	EB_CREATE_FORK_IF_NEEDED = (1 << 2),83 84	/* Should the first (possibly only) return buffer be returned locked? */85	EB_LOCK_FIRST = (1 << 3),86 87	/* Should the smgr size cache be cleared? */88	EB_CLEAR_SIZE_CACHE = (1 << 4),89 90	/* internal flags follow */91	EB_LOCK_TARGET = (1 << 5),92}			ExtendBufferedFlags;93 94/*95 * Some functions identify relations either by relation or smgr +96 * relpersistence.  Used via the BMR_REL()/BMR_SMGR() macros below.  This97 * allows us to use the same function for both recovery and normal operation.98 */99typedef struct BufferManagerRelation100{101	Relation	rel;102	struct SMgrRelationData *smgr;103	char		relpersistence;104} BufferManagerRelation;105 106#define BMR_REL(p_rel) ((BufferManagerRelation){.rel = p_rel})107#define BMR_SMGR(p_smgr, p_relpersistence) ((BufferManagerRelation){.smgr = p_smgr, .relpersistence = p_relpersistence})108 109 110/* forward declared, to avoid having to expose buf_internals.h here */111struct WritebackContext;112 113/* forward declared, to avoid including smgr.h here */114struct SMgrRelationData;115 116/* in globals.c ... this duplicates miscadmin.h */117extern PGDLLIMPORT int NBuffers;118 119/* in bufmgr.c */120extern PGDLLIMPORT bool zero_damaged_pages;121extern PGDLLIMPORT int bgwriter_lru_maxpages;122extern PGDLLIMPORT double bgwriter_lru_multiplier;123extern PGDLLIMPORT bool track_io_timing;124 125/* only applicable when prefetching is available */126#ifdef USE_PREFETCH127#define DEFAULT_EFFECTIVE_IO_CONCURRENCY 1128#define DEFAULT_MAINTENANCE_IO_CONCURRENCY 10129#else130#define DEFAULT_EFFECTIVE_IO_CONCURRENCY 0131#define DEFAULT_MAINTENANCE_IO_CONCURRENCY 0132#endif133extern PGDLLIMPORT int effective_io_concurrency;134extern PGDLLIMPORT int maintenance_io_concurrency;135 136extern PGDLLIMPORT int checkpoint_flush_after;137extern PGDLLIMPORT int backend_flush_after;138extern PGDLLIMPORT int bgwriter_flush_after;139 140/* in buf_init.c */141extern PGDLLIMPORT char *BufferBlocks;142 143/* in localbuf.c */144extern PGDLLIMPORT int NLocBuffer;145extern PGDLLIMPORT Block *LocalBufferBlockPointers;146extern PGDLLIMPORT int32 *LocalRefCount;147 148/* upper limit for effective_io_concurrency */149#define MAX_IO_CONCURRENCY 1000150 151/* special block number for ReadBuffer() */152#define P_NEW	InvalidBlockNumber	/* grow the file to get a new page */153 154/*155 * Buffer content lock modes (mode argument for LockBuffer())156 */157#define BUFFER_LOCK_UNLOCK		0158#define BUFFER_LOCK_SHARE		1159#define BUFFER_LOCK_EXCLUSIVE	2160 161 162/*163 * prototypes for functions in bufmgr.c164 */165extern PrefetchBufferResult PrefetchSharedBuffer(struct SMgrRelationData *smgr_reln,166												 ForkNumber forkNum,167												 BlockNumber blockNum);168extern PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum,169										   BlockNumber blockNum);170extern bool ReadRecentBuffer(RelFileLocator rlocator, ForkNumber forkNum,171							 BlockNumber blockNum, Buffer recent_buffer);172extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);173extern Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum,174								 BlockNumber blockNum, ReadBufferMode mode,175								 BufferAccessStrategy strategy);176extern Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator,177										ForkNumber forkNum, BlockNumber blockNum,178										ReadBufferMode mode, BufferAccessStrategy strategy,179										bool permanent);180extern void ReleaseBuffer(Buffer buffer);181extern void UnlockReleaseBuffer(Buffer buffer);182extern void MarkBufferDirty(Buffer buffer);183extern void IncrBufferRefCount(Buffer buffer);184extern void CheckBufferIsPinnedOnce(Buffer buffer);185extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,186								   BlockNumber blockNum);187 188extern Buffer ExtendBufferedRel(BufferManagerRelation bmr,189								ForkNumber forkNum,190								BufferAccessStrategy strategy,191								uint32 flags);192extern BlockNumber ExtendBufferedRelBy(BufferManagerRelation bmr,193									   ForkNumber fork,194									   BufferAccessStrategy strategy,195									   uint32 flags,196									   uint32 extend_by,197									   Buffer *buffers,198									   uint32 *extended_by);199extern Buffer ExtendBufferedRelTo(BufferManagerRelation bmr,200								  ForkNumber fork,201								  BufferAccessStrategy strategy,202								  uint32 flags,203								  BlockNumber extend_to,204								  ReadBufferMode mode);205 206extern void InitBufferPoolAccess(void);207extern void AtEOXact_Buffers(bool isCommit);208extern void PrintBufferLeakWarning(Buffer buffer);209extern void CheckPointBuffers(int flags);210extern BlockNumber BufferGetBlockNumber(Buffer buffer);211extern BlockNumber RelationGetNumberOfBlocksInFork(Relation relation,212												   ForkNumber forkNum);213extern void FlushOneBuffer(Buffer buffer);214extern void FlushRelationBuffers(Relation rel);215extern void FlushRelationsAllBuffers(struct SMgrRelationData **smgrs, int nrels);216extern void CreateAndCopyRelationData(RelFileLocator src_rlocator,217									  RelFileLocator dst_rlocator,218									  bool permanent);219extern void FlushDatabaseBuffers(Oid dbid);220extern void DropRelationBuffers(struct SMgrRelationData *smgr_reln,221								ForkNumber *forkNum,222								int nforks, BlockNumber *firstDelBlock);223extern void DropRelationsAllBuffers(struct SMgrRelationData **smgr_reln,224									int nlocators);225extern void DropDatabaseBuffers(Oid dbid);226 227#define RelationGetNumberOfBlocks(reln) \228	RelationGetNumberOfBlocksInFork(reln, MAIN_FORKNUM)229 230extern bool BufferIsPermanent(Buffer buffer);231extern XLogRecPtr BufferGetLSNAtomic(Buffer buffer);232 233#ifdef NOT_USED234extern void PrintPinnedBufs(void);235#endif236extern void BufferGetTag(Buffer buffer, RelFileLocator *rlocator,237						 ForkNumber *forknum, BlockNumber *blknum);238 239extern void MarkBufferDirtyHint(Buffer buffer, bool buffer_std);240 241extern void UnlockBuffers(void);242extern void LockBuffer(Buffer buffer, int mode);243extern bool ConditionalLockBuffer(Buffer buffer);244extern void LockBufferForCleanup(Buffer buffer);245extern bool ConditionalLockBufferForCleanup(Buffer buffer);246extern bool IsBufferCleanupOK(Buffer buffer);247extern bool HoldingBufferPinThatDelaysRecovery(void);248 249extern void AbortBufferIO(Buffer buffer);250 251extern bool BgBufferSync(struct WritebackContext *wb_context);252 253extern void TestForOldSnapshot_impl(Snapshot snapshot, Relation relation);254 255/* in buf_init.c */256extern void InitBufferPool(void);257extern Size BufferShmemSize(void);258 259/* in localbuf.c */260extern void AtProcExit_LocalBuffers(void);261 262/* in freelist.c */263 264extern BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype);265extern BufferAccessStrategy GetAccessStrategyWithSize(BufferAccessStrategyType btype,266													  int ring_size_kb);267extern int	GetAccessStrategyBufferCount(BufferAccessStrategy strategy);268 269extern void FreeAccessStrategy(BufferAccessStrategy strategy);270 271 272/* inline functions */273 274/*275 * Although this header file is nominally backend-only, certain frontend276 * programs like pg_waldump include it.  For compilers that emit static277 * inline functions even when they're unused, that leads to unsatisfied278 * external references; hence hide these with #ifndef FRONTEND.279 */280 281#ifndef FRONTEND282 283/*284 * BufferIsValid285 *		True iff the given buffer number is valid (either as a shared286 *		or local buffer).287 *288 * Note: For a long time this was defined the same as BufferIsPinned,289 * that is it would say False if you didn't hold a pin on the buffer.290 * I believe this was bogus and served only to mask logic errors.291 * Code should always know whether it has a buffer reference,292 * independently of the pin state.293 *294 * Note: For a further long time this was not quite the inverse of the295 * BufferIsInvalid() macro, in that it also did sanity checks to verify296 * that the buffer number was in range.  Most likely, this macro was297 * originally intended only to be used in assertions, but its use has298 * since expanded quite a bit, and the overhead of making those checks299 * even in non-assert-enabled builds can be significant.  Thus, we've300 * now demoted the range checks to assertions within the macro itself.301 */302static inline bool303BufferIsValid(Buffer bufnum)304{305	Assert(bufnum <= NBuffers);306	Assert(bufnum >= -NLocBuffer);307 308	return bufnum != InvalidBuffer;309}310 311/*312 * BufferGetBlock313 *		Returns a reference to a disk page image associated with a buffer.314 *315 * Note:316 *		Assumes buffer is valid.317 */318static inline Block319BufferGetBlock(Buffer buffer)320{321	Assert(BufferIsValid(buffer));322 323	if (BufferIsLocal(buffer))324		return LocalBufferBlockPointers[-buffer - 1];325	else326		return (Block) (BufferBlocks + ((Size) (buffer - 1)) * BLCKSZ);327}328 329/*330 * BufferGetPageSize331 *		Returns the page size within a buffer.332 *333 * Notes:334 *		Assumes buffer is valid.335 *336 *		The buffer can be a raw disk block and need not contain a valid337 *		(formatted) disk page.338 */339/* XXX should dig out of buffer descriptor */340static inline Size341BufferGetPageSize(Buffer buffer)342{343	AssertMacro(BufferIsValid(buffer));344	return (Size) BLCKSZ;345}346 347/*348 * BufferGetPage349 *		Returns the page associated with a buffer.350 *351 * When this is called as part of a scan, there may be a need for a nearby352 * call to TestForOldSnapshot().  See the definition of that for details.353 */354static inline Page355BufferGetPage(Buffer buffer)356{357	return (Page) BufferGetBlock(buffer);358}359 360/*361 * Check whether the given snapshot is too old to have safely read the given362 * page from the given table.  If so, throw a "snapshot too old" error.363 *364 * This test generally needs to be performed after every BufferGetPage() call365 * that is executed as part of a scan.  It is not needed for calls made for366 * modifying the page (for example, to position to the right place to insert a367 * new index tuple or for vacuuming).  It may also be omitted where calls to368 * lower-level functions will have already performed the test.369 *370 * Note that a NULL snapshot argument is allowed and causes a fast return371 * without error; this is to support call sites which can be called from372 * either scans or index modification areas.373 *374 * For best performance, keep the tests that are fastest and/or most likely to375 * exclude a page from old snapshot testing near the front.376 */377static inline void378TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)379{380	Assert(relation != NULL);381 382	if (old_snapshot_threshold >= 0383		&& (snapshot) != NULL384		&& ((snapshot)->snapshot_type == SNAPSHOT_MVCC385			|| (snapshot)->snapshot_type == SNAPSHOT_TOAST)386		&& !XLogRecPtrIsInvalid((snapshot)->lsn)387		&& PageGetLSN(page) > (snapshot)->lsn)388		TestForOldSnapshot_impl(snapshot, relation);389}390 391#endif							/* FRONTEND */392 393#endif							/* BUFMGR_H */394 
codekingpro/portable-devtools · Team Ai