⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buf_init.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * buf_init.c *	  buffer manager initialization routines * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.25 1999/06/26 15:58:28 momjian Exp $ * *------------------------------------------------------------------------- */#include <sys/types.h>#include <sys/file.h>#include <stdio.h>#include <math.h>#include <signal.h>#include "postgres.h"/* declarations split between these three files */#include "storage/buf.h"#include "storage/buf_internals.h"#include "storage/bufmgr.h"#include "storage/fd.h"#include "storage/ipc.h"#include "storage/s_lock.h"#include "storage/shmem.h"#include "storage/spin.h"#include "storage/smgr.h"#include "storage/lmgr.h"#include "miscadmin.h"#include "utils/builtins.h"#include "utils/hsearch.h"#include "utils/memutils.h"#include "executor/execdebug.h" /* for NDirectFileRead */#include "catalog/catalog.h"/* *	if BMTRACE is defined, we trace the last 200 buffer allocations and *	deallocations in a circular buffer in shared memory. */#ifdef	BMTRACEbmtrace    *TraceBuf;long	   *CurTraceBuf;#define BMT_LIMIT		200#endif	 /* BMTRACE */int			ShowPinTrace = 0;int			NBuffers = DEF_NBUFFERS;	/* default is set in config.h */int			Data_Descriptors;int			Free_List_Descriptor;int			Lookup_List_Descriptor;int			Num_Descriptors;BufferDesc *BufferDescriptors;BufferBlock BufferBlocks;#ifndef HAS_TEST_AND_SETlong	   *NWaitIOBackendP;#endifextern IpcSemaphoreId WaitIOSemId;long	   *PrivateRefCount;	/* also used in freelist.c */long	   *LastRefCount;		/* refcounts of last ExecMain level */bits8	   *BufferLocks;		/* */long	   *CommitInfoNeedsSave;/* to write buffers where we have filled								 * in t_infomask *//* * Data Structures: *		buffers live in a freelist and a lookup data structure. * * * Buffer Lookup: *		Two important notes.  First, the buffer has to be *		available for lookup BEFORE an IO begins.  Otherwise *		a second process trying to read the buffer will *		allocate its own copy and the buffeer pool will *		become inconsistent. * * Buffer Replacement: *		see freelist.c.  A buffer cannot be replaced while in *		use either by data manager or during IO. * * WriteBufferBack: *		currently, a buffer is only written back at the time *		it is selected for replacement.  It should *		be done sooner if possible to reduce latency of *		BufferAlloc().	Maybe there should be a daemon process. * * Synchronization/Locking: * * BufMgrLock lock -- must be acquired before manipulating the *		buffer queues (lookup/freelist).  Must be released *		before exit and before doing any IO. * * IO_IN_PROGRESS -- this is a flag in the buffer descriptor. *		It must be set when an IO is initiated and cleared at *		the end of	the IO.  It is there to make sure that one *		process doesn't start to use a buffer while another is *		faulting it in.  see IOWait/IOSignal. * * refcount --	A buffer is pinned during IO and immediately *		after a BufferAlloc().	A buffer is always either pinned *		or on the freelist but never both.	The buffer must be *		released, written, or flushed before the end of *		transaction. * * PrivateRefCount -- Each buffer also has a private refcount the keeps *		track of the number of times the buffer is pinned in the current *		processes.	This is used for two purposes, first, if we pin a *		a buffer more than once, we only need to change the shared refcount *		once, thus only lock the buffer pool once, second, when a transaction *		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. * */SPINLOCK	BufMgrLock;long int	ReadBufferCount;long int	ReadLocalBufferCount;long int	BufferHitCount;long int	LocalBufferHitCount;long int	BufferFlushCount;long int	LocalBufferFlushCount;/* * Initialize module: * * should calculate size of pool dynamically based on the * amount of available memory. */voidInitBufferPool(IPCKey key){	bool		foundBufs,				foundDescs;	int			i;	Data_Descriptors = NBuffers;	Free_List_Descriptor = Data_Descriptors;	Lookup_List_Descriptor = Data_Descriptors + 1;	Num_Descriptors = Data_Descriptors + 1;	SpinAcquire(BufMgrLock);#ifdef BMTRACE	CurTraceBuf = (long *) ShmemInitStruct("Buffer trace",							(BMT_LIMIT * sizeof(bmtrace)) + sizeof(long),										   &foundDescs);	if (!foundDescs)		MemSet(CurTraceBuf, 0, (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long));	TraceBuf = (bmtrace *) & (CurTraceBuf[1]);#endif	BufferDescriptors = (BufferDesc *)		ShmemInitStruct("Buffer Descriptors",					  Num_Descriptors * sizeof(BufferDesc), &foundDescs);	BufferBlocks = (BufferBlock)		ShmemInitStruct("Buffer Blocks",						NBuffers * BLCKSZ, &foundBufs);#ifndef HAS_TEST_AND_SET	{		bool		foundNWaitIO;		NWaitIOBackendP = (long *) ShmemInitStruct("#Backends Waiting IO",												   sizeof(long),												   &foundNWaitIO);		if (!foundNWaitIO)			*NWaitIOBackendP = 0;	}#endif	if (foundDescs || foundBufs)	{		/* both should be present or neither */		Assert(foundDescs && foundBufs);	}	else	{		BufferDesc *buf;		unsigned long block;		buf = BufferDescriptors;		block = (unsigned long) BufferBlocks;		/*		 * link the buffers into a circular, doubly-linked list to		 * initialize free list.  Still don't know anything about		 * replacement strategy in this file.		 */		for (i = 0; i < Data_Descriptors; block += BLCKSZ, buf++, i++)		{			Assert(ShmemIsValid((unsigned long) block));			buf->freeNext = i + 1;			buf->freePrev = i - 1;			CLEAR_BUFFERTAG(&(buf->tag));			buf->data = MAKE_OFFSET(block);			buf->flags = (BM_DELETED | BM_FREE | BM_VALID);			buf->refcount = 0;			buf->buf_id = i;#ifdef HAS_TEST_AND_SET			S_INIT_LOCK(&(buf->io_in_progress_lock));			S_INIT_LOCK(&(buf->cntx_lock));#endif		}		/* close the circular queue */		BufferDescriptors[0].freePrev = Data_Descriptors - 1;		BufferDescriptors[Data_Descriptors - 1].freeNext = 0;	}	/* Init the rest of the module */	InitBufTable();	InitFreeList(!foundDescs);	SpinRelease(BufMgrLock);#ifndef HAS_TEST_AND_SET	{		int			status;		extern IpcSemaphoreId WaitIOSemId;		extern IpcSemaphoreId WaitCLSemId;		WaitIOSemId = IpcSemaphoreCreate(IPCKeyGetWaitIOSemaphoreKey(key),										 1, IPCProtection, 0, 1, &status);		WaitCLSemId = IpcSemaphoreCreate(IPCKeyGetWaitCLSemaphoreKey(key),										 1, IPCProtection,										 IpcSemaphoreDefaultStartValue,										 1, &status);	}#endif	PrivateRefCount = (long *) calloc(NBuffers, sizeof(long));	LastRefCount = (long *) calloc(NBuffers, sizeof(long));	BufferLocks = (bits8 *) calloc(NBuffers, sizeof(bits8));	CommitInfoNeedsSave = (long *) calloc(NBuffers, sizeof(long));}/* ----------------------------------------------------- * BufferShmemSize * * compute the size of shared memory for the buffer pool including * data pages, buffer descriptors, hash tables, etc. * ---------------------------------------------------- */intBufferShmemSize(){	int			size = 0;	/* size of shmem index hash table */	size += hash_estimate_size(SHMEM_INDEX_SIZE,							   SHMEM_INDEX_KEYSIZE,							   SHMEM_INDEX_DATASIZE);	/* size of buffer descriptors */	size += MAXALIGN((NBuffers + 1) * sizeof(BufferDesc));	/* size of data pages */	size += NBuffers * MAXALIGN(BLCKSZ);	/* size of buffer hash table */	size += hash_estimate_size(NBuffers,							   sizeof(BufferTag),							   sizeof(Buffer));#ifdef BMTRACE	size += (BMT_LIMIT * sizeof(bmtrace)) + sizeof(long);#endif	return size;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -