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

📄 dbreg_rec.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2002 *	Sleepycat Software.  All rights reserved. *//* * Copyright (c) 1995, 1996 *	The President and Fellows of Harvard University.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "db_config.h"#ifndef lintstatic const char revid[] = "$Id: dbreg_rec.c,v 11.108 2002/08/14 20:04:25 bostic Exp $";#endif /* not lint */#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <string.h>#endif#include "db_int.h"#include "dbinc/db_page.h"#include "dbinc/db_am.h"#include "dbinc/log.h"#include "dbinc/txn.h"static int __dbreg_open_file __P((DB_ENV *,    DB_TXN *, __dbreg_register_args *, void *));/* * PUBLIC: int __dbreg_register_recover * PUBLIC:     __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__dbreg_register_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	DB_ENTRY *dbe;	DB_LOG *dblp;	DB *dbp;	__dbreg_register_args *argp;	int do_close, do_open, do_rem, ret, t_ret;	dblp = dbenv->lg_handle;	dbp = NULL;#ifdef DEBUG_RECOVER	REC_PRINT(__dbreg_register_print);#endif	do_open = do_close = 0;	if ((ret = __dbreg_register_read(dbenv, dbtp->data, &argp)) != 0)		goto out;	switch (argp->opcode) {	case LOG_OPEN:		if ((DB_REDO(op) ||		    op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES))			do_open = 1;		else			do_close = 1;		break;	case LOG_CLOSE:		if (DB_UNDO(op))			do_open = 1;		else			do_close = 1;		break;	case LOG_RCLOSE:		/*		 * LOG_RCLOSE was generated by recover because a file		 * was left open.  The POPENFILES pass, which is run		 * to open files to abort prepared transactions,		 * may not include the open for this file so we		 * open it here.  Note that a normal CLOSE is		 * not legal before the prepared transaction is		 * committed or aborted.		 */		if (DB_UNDO(op) || op == DB_TXN_POPENFILES)			do_open = 1;		else			do_close = 1;		break;	case LOG_CHECKPOINT:		if (DB_UNDO(op) ||		    op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES)			do_open = 1;		break;	}	if (do_open) {		/*		 * We must open the db even if the meta page is not		 * yet written as we may be creating subdatabase.		 */		if (op == DB_TXN_OPENFILES && argp->opcode != LOG_CHECKPOINT)			F_SET(dblp, DBLOG_FORCE_OPEN);		/*		 * During an abort or an open pass to recover prepared txns,		 * we need to make sure that we use the same locker id on the		 * open.  We pass the txnid along to ensure this.		 */		ret = __dbreg_open_file(dbenv,		    op == DB_TXN_ABORT || op == DB_TXN_POPENFILES ?		    argp->txnid : NULL, argp, info);		if (ret == ENOENT || ret == EINVAL) {			/*			 * If this is an OPEN while rolling forward, it's			 * possible that the file was recreated since last			 * time we got here.  In that case, we've got deleted			 * set and probably shouldn't, so we need to check			 * for that case and possibly retry.			 */			if (op == DB_TXN_FORWARD_ROLL &&			    argp->txnid != 0 &&			    dblp->dbentry[argp->fileid].deleted) {				dblp->dbentry[argp->fileid].deleted = 0;				ret =				    __dbreg_open_file(dbenv, NULL, argp, info);			}			ret = 0;		}		F_CLR(dblp, DBLOG_FORCE_OPEN);	}	if (do_close) {		/*		 * If we are undoing an open, or redoing a close,		 * then we need to close the file.		 *		 * If the file is deleted, then we can just ignore this close.		 * Otherwise, we should usually have a valid dbp we should		 * close or whose reference count should be decremented.		 * However, if we shut down without closing a file, we may, in		 * fact, not have the file open, and that's OK.		 */		do_rem = 0;		MUTEX_THREAD_LOCK(dbenv, dblp->mutexp);		if (argp->fileid < dblp->dbentry_cnt) {			/*			 * Typically, closes should match an open which means			 * that if this is a close, there should be a valid			 * entry in the dbentry table when we get here,			 * however there is an exception.  If this is an			 * OPENFILES pass, then we may have started from			 * a log file other than the first, and the			 * corresponding open appears in an earlier file.			 * We can ignore that case, but all others are errors.			 */			dbe = &dblp->dbentry[argp->fileid];			if (dbe->dbp == NULL && !dbe->deleted) {				/* No valid entry here. */				if ((argp->opcode != LOG_CLOSE &&				    argp->opcode != LOG_RCLOSE) ||				    (op != DB_TXN_OPENFILES &&				    op !=DB_TXN_POPENFILES)) {					__db_err(dbenv,					    "Improper file close at %lu/%lu",					    (u_long)lsnp->file,					    (u_long)lsnp->offset);					ret = EINVAL;				}				MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);				goto done;			}			/* We have either an open entry or a deleted entry. */			if ((dbp = dbe->dbp) != NULL) {				MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);				(void)__dbreg_revoke_id(dbp, 0);				/*				 * If we're a replication client, it's				 * possible to get here with a dbp that				 * the user opened, but which we later				 * assigned a fileid to.  Be sure that				 * we only close dbps that we opened in				 * the recovery code;  they should have				 * DB_AM_RECOVER set.				 *				 * The only exception is if we're aborting				 * in a normal environment;  then we might				 * get here with a non-AM_RECOVER database.				 */				if (F_ISSET(dbp, DB_AM_RECOVER) ||				    op == DB_TXN_ABORT)					do_rem = 1;			} else if (dbe->deleted) {				MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);				__dbreg_rem_dbentry(dblp, argp->fileid);			}		} else			MUTEX_THREAD_UNLOCK(dbenv, dblp->mutexp);		if (do_rem) {			/*			 * If we are undoing a create we'd better discard			 * any buffers from the memory pool.			 */			if (dbp != NULL && dbp->mpf != NULL && argp->id != 0) {				if ((ret = dbp->mpf->close(dbp->mpf,				    DB_MPOOL_DISCARD)) != 0)					goto out;				dbp->mpf = NULL;			}			/*			 * During recovery, all files are closed.  On an abort,			 * we only close the file if we opened it during the			 * abort (DB_AM_RECOVER set), otherwise we simply do			 * a __db_refresh.  For the close case, if remove or			 * rename has closed the file, don't request a sync,			 * because the NULL mpf would be a problem.			 */			if (dbp != NULL) {				if (op == DB_TXN_ABORT &&				    !F_ISSET(dbp, DB_AM_RECOVER))					t_ret =					    __db_refresh(dbp, NULL, DB_NOSYNC);				else					t_ret = dbp->close(dbp, DB_NOSYNC);				if (t_ret != 0 && ret == 0)					ret = t_ret;			}		}	}done:	if (ret == 0)		*lsnp = argp->prev_lsn;out:	if (argp != NULL)		__os_free(dbenv, argp);	return (ret);}/* * __dbreg_open_file -- *	Called during log_register recovery.  Make sure that we have an *	entry in the dbentry table for this ndx.  Returns 0 on success, *	non-zero on error. */static int__dbreg_open_file(dbenv, txn, argp, info)	DB_ENV *dbenv;	DB_TXN *txn;	__dbreg_register_args *argp;	void *info;{	DB_ENTRY *dbe;	DB_LOG *lp;	DB *dbp;	u_int32_t id;	lp = (DB_LOG *)dbenv->lg_handle;	/*	 * We never re-open temporary files.  Temp files are only	 * useful during aborts in which case the dbp was entered	 * when the file was registered.  During recovery, we treat	 * temp files as properly deleted files, allowing the open to	 * fail and not reporting any errors when recovery fails to	 * get a valid dbp from __dbreg_id_to_db.	 */	if (argp->name.size == 0) {		(void)__dbreg_add_dbentry(dbenv, lp, NULL, argp->fileid);		return (ENOENT);	}	/*	 * When we're opening, we have to check that the name we are opening	 * is what we expect.  If it's not, then we close the old file and	 * open the new one.	 */	MUTEX_THREAD_LOCK(dbenv, lp->mutexp);	if (argp->fileid < lp->dbentry_cnt)		dbe = &lp->dbentry[argp->fileid];	else		dbe = NULL;	if (dbe != NULL) {		if (dbe->deleted) {			MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);			return (ENOENT);		}		if ((dbp = dbe->dbp) != NULL) {			if (dbp->meta_pgno != argp->meta_pgno ||			    memcmp(dbp->fileid,			    argp->uid.data, DB_FILE_ID_LEN) != 0) {				MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);				(void)__dbreg_revoke_id(dbp, 0);				if (F_ISSET(dbp, DB_AM_RECOVER))					dbp->close(dbp, DB_NOSYNC);				goto reopen;			}			/*			 * We should only get here if we already have the			 * dbp from an openfiles pass, in which case, what's			 * here had better be the same dbp.			 */			DB_ASSERT(dbe->dbp == dbp);			MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);			/*			 * This is a successful open.  We need to record that			 * in the txnlist so that we know how to handle the			 * subtransaction that created the file system object.			 */			if (argp->id != TXN_INVALID &&			    __db_txnlist_update(dbenv, info,			    argp->id, TXN_EXPECTED, NULL) == TXN_NOTFOUND)				(void)__db_txnlist_add(dbenv,				    info, argp->id, TXN_EXPECTED, NULL);			return (0);		}	}	MUTEX_THREAD_UNLOCK(dbenv, lp->mutexp);	/*	 * We are about to pass a recovery txn pointer into the main library.	 * We need to make sure that any accessed fields are set appropriately.	 */reopen:	if (txn != NULL) {		id = txn->txnid;		memset(txn, 0, sizeof(DB_TXN));		txn->txnid = id;		txn->mgrp = dbenv->tx_handle;	}	return (__dbreg_do_open(dbenv, txn, lp, argp->uid.data, argp->name.data,	    argp->ftype, argp->fileid, argp->meta_pgno, info, argp->id));}

⌨️ 快捷键说明

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