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

📄 smgr.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * smgr.c *	  public interface routines to storage manager switch. * *	  All file system operations in POSTGRES dispatch through these *	  routines. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.24.2.1 1999/09/02 04:07:17 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "storage/smgr.h"static void smgrshutdown(int dummy);typedef struct f_smgr{	int			(*smgr_init) ();/* may be NULL */	int			(*smgr_shutdown) ();	/* may be NULL */	int			(*smgr_create) ();	int			(*smgr_unlink) ();	int			(*smgr_extend) ();	int			(*smgr_open) ();	int			(*smgr_close) ();	int			(*smgr_read) ();	int			(*smgr_write) ();	int			(*smgr_flush) ();	int			(*smgr_blindwrt) ();	int			(*smgr_nblocks) ();	int			(*smgr_truncate) ();	int			(*smgr_commit) ();		/* may be NULL */	int			(*smgr_abort) ();		/* may be NULL */} f_smgr;/* *	The weird placement of commas in this init block is to keep the compiler *	happy, regardless of what storage managers we have (or don't have). */static f_smgr smgrsw[] = {	/* magnetic disk */	{mdinit, NULL, mdcreate, mdunlink, mdextend, mdopen, mdclose,		mdread, mdwrite, mdflush, mdblindwrt, mdnblocks, mdtruncate,	mdcommit, mdabort},#ifdef STABLE_MEMORY_STORAGE	/* main memory */	{mminit, mmshutdown, mmcreate, mmunlink, mmextend, mmopen, mmclose,		mmread, mmwrite, mmflush, mmblindwrt, mmnblocks, NULL,	mmcommit, mmabort},#endif};/* *	This array records which storage managers are write-once, and which *	support overwrite.	A 'true' entry means that the storage manager is *	write-once.  In the best of all possible worlds, there would be no *	write-once storage managers. */#ifdef NOT_USEDstatic bool smgrwo[] = {	false,						/* magnetic disk */#ifdef STABLE_MEMORY_STORAGE	false,						/* main memory */#endif};#endifstatic int	NSmgr = lengthof(smgrsw);/* *	smgrinit(), smgrshutdown() -- Initialize or shut down all storage *								  managers. * */intsmgrinit(){	int			i;	for (i = 0; i < NSmgr; i++)	{		if (smgrsw[i].smgr_init)		{			if ((*(smgrsw[i].smgr_init)) () == SM_FAIL)				elog(FATAL, "initialization failed on %s", smgrout(i));		}	}	/* register the shutdown proc */	on_proc_exit(smgrshutdown, NULL);	return SM_SUCCESS;}static voidsmgrshutdown(int dummy){	int			i;	for (i = 0; i < NSmgr; i++)	{		if (smgrsw[i].smgr_shutdown)		{			if ((*(smgrsw[i].smgr_shutdown)) () == SM_FAIL)				elog(FATAL, "shutdown failed on %s", smgrout(i));		}	}}/* *	smgrcreate() -- Create a new relation. * *		This routine takes a reldesc, creates the relation on the appropriate *		device, and returns a file descriptor for it. */intsmgrcreate(int16 which, Relation reln){	int			fd;	if ((fd = (*(smgrsw[which].smgr_create)) (reln)) < 0)		elog(ERROR, "cannot create %s", reln->rd_rel->relname.data);	return fd;}/* *	smgrunlink() -- Unlink a relation. * *		The relation is removed from the store. */intsmgrunlink(int16 which, Relation reln){	int			status;	if ((status = (*(smgrsw[which].smgr_unlink)) (reln)) == SM_FAIL)		elog(ERROR, "cannot unlink %s", reln->rd_rel->relname.data);	return status;}/* *	smgrextend() -- Add a new block to a file. * *		Returns SM_SUCCESS on success; aborts the current transaction on *		failure. */intsmgrextend(int16 which, Relation reln, char *buffer){	int			status;	status = (*(smgrsw[which].smgr_extend)) (reln, buffer);	if (status == SM_FAIL)		elog(ERROR, "%s: cannot extend.  Check free disk space.", reln->rd_rel->relname.data);	return status;}/* *	smgropen() -- Open a relation using a particular storage manager. * *		Returns the fd for the open relation on success, aborts the *		transaction on failure. */intsmgropen(int16 which, Relation reln){	int			fd;	if ((fd = (*(smgrsw[which].smgr_open)) (reln)) < 0)		elog(ERROR, "cannot open %s", reln->rd_rel->relname.data);	return fd;}/* *	smgrclose() -- Close a relation. * *		NOTE: underlying manager should allow case where relation is *		already closed.  Indeed relation may have been unlinked! *		This is currently called only from RelationFlushRelation() when *		the relation cache entry is about to be dropped; could be doing *		simple relation cache clear, or finishing up DROP TABLE. *		 *		Returns SM_SUCCESS on success, aborts on failure. */intsmgrclose(int16 which, Relation reln){	if ((*(smgrsw[which].smgr_close)) (reln) == SM_FAIL)		elog(ERROR, "cannot close %s", reln->rd_rel->relname.data);	return SM_SUCCESS;}/* *	smgrread() -- read a particular block from a relation into the supplied *				  buffer. * *		This routine is called from the buffer manager in order to *		instantiate pages in the shared buffer cache.  All storage managers *		return pages in the format that POSTGRES expects.  This routine *		dispatches the read.  On success, it returns SM_SUCCESS.  On failure, *		the current transaction is aborted. */intsmgrread(int16 which, Relation reln, BlockNumber blocknum, char *buffer){	int			status;	status = (*(smgrsw[which].smgr_read)) (reln, blocknum, buffer);	if (status == SM_FAIL)		elog(ERROR, "cannot read block %d of %s",			 blocknum, reln->rd_rel->relname.data);	return status;}/* *	smgrwrite() -- Write the supplied buffer out. * *		This is not a synchronous write -- the interface for that is *		smgrflush().  The buffer is written out via the appropriate *		storage manager.  This routine returns SM_SUCCESS or aborts *		the current transaction. */intsmgrwrite(int16 which, Relation reln, BlockNumber blocknum, char *buffer){	int			status;	status = (*(smgrsw[which].smgr_write)) (reln, blocknum, buffer);	if (status == SM_FAIL)		elog(ERROR, "cannot write block %d of %s",			 blocknum, reln->rd_rel->relname.data);	return status;}/* *	smgrflush() -- A synchronous smgrwrite(). */intsmgrflush(int16 which, Relation reln, BlockNumber blocknum, char *buffer){	int			status;	status = (*(smgrsw[which].smgr_flush)) (reln, blocknum, buffer);	if (status == SM_FAIL)		elog(ERROR, "cannot flush block %d of %s to stable store",			 blocknum, reln->rd_rel->relname.data);	return status;}/* *	smgrblindwrt() -- Write a page out blind. * *		In some cases, we may find a page in the buffer cache that we *		can't make a reldesc for.  This happens, for example, when we *		want to reuse a dirty page that was written by a transaction *		that has not yet committed, which created a new relation.  In *		this case, the buffer manager will call smgrblindwrt() with *		the name and OID of the database and the relation to which the *		buffer belongs.  Every storage manager must be able to force *		this page down to stable storage in this circumstance. */intsmgrblindwrt(int16 which,			 char *dbname,			 char *relname,			 Oid dbid,			 Oid relid,			 BlockNumber blkno,			 char *buffer){	char	   *dbstr;	char	   *relstr;	int			status;	dbstr = pstrdup(dbname);	relstr = pstrdup(relname);	status = (*(smgrsw[which].smgr_blindwrt)) (dbstr, relstr, dbid, relid,											   blkno, buffer);	if (status == SM_FAIL)		elog(ERROR, "cannot write block %d of %s [%s] blind",			 blkno, relstr, dbstr);	pfree(dbstr);	pfree(relstr);	return status;}/* *	smgrnblocks() -- Calculate the number of POSTGRES blocks in the *					 supplied relation. * *		Returns the number of blocks on success, aborts the current *		transaction on failure. */intsmgrnblocks(int16 which, Relation reln){	int			nblocks;	if ((nblocks = (*(smgrsw[which].smgr_nblocks)) (reln)) < 0)		elog(ERROR, "cannot count blocks for %s", reln->rd_rel->relname.data);	return nblocks;}/* *	smgrtruncate() -- Truncate supplied relation to a specified number *						of blocks * *		Returns the number of blocks on success, aborts the current *		transaction on failure. */intsmgrtruncate(int16 which, Relation reln, int nblocks){	int			newblks;	newblks = nblocks;	if (smgrsw[which].smgr_truncate)	{		if ((newblks = (*(smgrsw[which].smgr_truncate)) (reln, nblocks)) < 0)			elog(ERROR, "cannot truncate %s to %d blocks",				 reln->rd_rel->relname.data, nblocks);	}	return newblks;}/* *	smgrcommit(), smgrabort() -- Commit or abort changes made during the *								 current transaction. */intsmgrcommit(){	int			i;	for (i = 0; i < NSmgr; i++)	{		if (smgrsw[i].smgr_commit)		{			if ((*(smgrsw[i].smgr_commit)) () == SM_FAIL)				elog(FATAL, "transaction commit failed on %s", smgrout(i));		}	}	return SM_SUCCESS;}#ifdef NOT_USEDintsmgrabort(){	int			i;	for (i = 0; i < NSmgr; i++)	{		if (smgrsw[i].smgr_abort)		{			if ((*(smgrsw[i].smgr_abort)) () == SM_FAIL)				elog(FATAL, "transaction abort failed on %s", smgrout(i));		}	}	return SM_SUCCESS;}#endif#ifdef NOT_USEDboolsmgriswo(int16 smgrno){	if (smgrno < 0 || smgrno >= NSmgr)		elog(ERROR, "illegal storage manager number %d", smgrno);	return smgrwo[smgrno];}#endif

⌨️ 快捷键说明

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