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

📄 db.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* Register DB's pgin/pgout functions. */	if ((ret = dbenv->memp_register(	    dbenv, DB_FTYPE_SET, __db_pgin, __db_pgout)) != 0)		return (ret);	/* Create the DB_MPOOLFILE structure. */	if ((ret = dbenv->memp_fcreate(dbenv, &dbp->mpf, 0)) != 0)		return (ret);	mpf = dbp->mpf;	/* Set the database's cache priority if we've been given one. */	if (dbp->priority != 0 &&	    (ret = mpf->set_priority(mpf, dbp->priority)) != 0)		return (ret);	/*	 * Open a backing file in the memory pool.	 *	 * If we need to pre- or post-process a file's pages on I/O, set the	 * file type.  If it's a hash file, always call the pgin and pgout	 * routines.  This means that hash files can never be mapped into	 * process memory.  If it's a btree file and requires swapping, we	 * need to page the file in and out.  This has to be right -- we can't	 * mmap files that are being paged in and out.	 */	switch (dbp->type) {	case DB_BTREE:	case DB_RECNO:		ftype = F_ISSET(dbp, DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM)		    ? DB_FTYPE_SET : DB_FTYPE_NOTSET;		(void)mpf->set_ftype(mpf, ftype);		(void)mpf->set_clear_len(mpf, (CRYPTO_ON(dbenv) ?		    dbp->pgsize : DB_PAGE_DB_LEN));		break;	case DB_HASH:		(void)mpf->set_ftype(mpf, DB_FTYPE_SET);		(void)mpf->set_clear_len(mpf, (CRYPTO_ON(dbenv) ?		    dbp->pgsize : DB_PAGE_DB_LEN));		break;	case DB_QUEUE:		ftype = F_ISSET(dbp, DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM)		    ? DB_FTYPE_SET : DB_FTYPE_NOTSET;		(void)mpf->set_ftype(mpf, ftype);		(void)mpf->set_clear_len(mpf, (CRYPTO_ON(dbenv) ?		    dbp->pgsize : DB_PAGE_QUEUE_LEN));		break;	case DB_UNKNOWN:		/*		 * If we're running in the verifier, our database might		 * be corrupt and we might not know its type--but we may		 * still want to be able to verify and salvage.		 *		 * If we can't identify the type, it's not going to be safe		 * to call __db_pgin--we pretty much have to give up all		 * hope of salvaging cross-endianness.  Proceed anyway;		 * at worst, the database will just appear more corrupt		 * than it actually is, but at best, we may be able		 * to salvage some data even with no metadata page.		 */		if (F_ISSET(dbp, DB_AM_VERIFYING)) {			(void)mpf->set_ftype(mpf, DB_FTYPE_NOTSET);			(void)mpf->set_clear_len(mpf, DB_PAGE_DB_LEN);			break;		}		/* FALLTHROUGH */	default:		return (		    __db_unknown_type(dbenv, "__db_dbenv_setup", dbp->type));	}	(void)mpf->set_fileid(mpf, dbp->fileid);	(void)mpf->set_lsn_offset(mpf, 0);	pginfo.db_pagesize = dbp->pgsize;	pginfo.flags =	    F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP));	pginfo.type = dbp->type;	pgcookie.data = &pginfo;	pgcookie.size = sizeof(DB_PGINFO);	(void)mpf->set_pgcookie(mpf, &pgcookie);	if ((ret = mpf->open(mpf, name,	    LF_ISSET(DB_RDONLY | DB_NOMMAP | DB_ODDFILESIZE | DB_TRUNCATE) |	    (F_ISSET(dbenv, DB_ENV_DIRECT_DB) ? DB_DIRECT : 0),	    0, dbp->pgsize)) != 0)		return (ret);	/*	 * We may need a per-thread mutex.  Allocate it from the mpool	 * region, there's supposed to be extra space there for that purpose.	 */	if (LF_ISSET(DB_THREAD)) {		dbmp = dbenv->mp_handle;		if ((ret = __db_mutex_setup(dbenv, dbmp->reginfo, &dbp->mutexp,		    MUTEX_ALLOC | MUTEX_THREAD)) != 0)			return (ret);	}	/*	 * Set up a bookkeeping entry for this database in the log region,	 * if such a region exists.  Note that even if we're in recovery	 * or a replication client, where we won't log registries, we'll	 * still need an FNAME struct, so LOGGING_ON is the correct macro.	 */	if (LOGGING_ON(dbenv) &&	    (ret = __dbreg_setup(dbp, name, id)) != 0)		return (ret);	/*	 * If we're actively logging and our caller isn't a recovery function	 * that already did so, assign this dbp a log fileid.	 */	if (DBENV_LOGGING(dbenv) && !F_ISSET(dbp, DB_AM_RECOVER) &&#if !defined(DEBUG_ROP)	    !F_ISSET(dbp, DB_AM_RDONLY) &&#endif	    (ret = __dbreg_new_id(dbp, txn)) != 0)		return (ret);	/*	 * Insert ourselves into the DB_ENV's dblist.  We allocate a	 * unique ID to each {fileid, meta page number} pair, and to	 * each temporary file (since they all have a zero fileid).	 * This ID gives us something to use to tell which DB handles	 * go with which databases in all the cursor adjustment	 * routines, where we don't want to do a lot of ugly and	 * expensive memcmps.	 */	MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);	for (maxid = 0, ldbp = LIST_FIRST(&dbenv->dblist);	    ldbp != NULL; ldbp = LIST_NEXT(dbp, dblistlinks)) {		if (name != NULL &&		    memcmp(ldbp->fileid, dbp->fileid, DB_FILE_ID_LEN) == 0 &&		    ldbp->meta_pgno == dbp->meta_pgno)			break;		if (ldbp->adj_fileid > maxid)			maxid = ldbp->adj_fileid;	}	/*	 * If ldbp is NULL, we didn't find a match, or we weren't	 * really looking because name is NULL.  Assign the dbp an	 * adj_fileid one higher than the largest we found, and	 * insert it at the head of the master dbp list.	 *	 * If ldbp is not NULL, it is a match for our dbp.  Give dbp	 * the same ID that ldbp has, and add it after ldbp so they're	 * together in the list.	 */	if (ldbp == NULL) {		dbp->adj_fileid = maxid + 1;		LIST_INSERT_HEAD(&dbenv->dblist, dbp, dblistlinks);	} else {		dbp->adj_fileid = ldbp->adj_fileid;		LIST_INSERT_AFTER(ldbp, dbp, dblistlinks);	}	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);	return (0);}/* * __db_close -- *	DB destructor. * * PUBLIC: int __db_close __P((DB *, u_int32_t)); */int__db_close(dbp, flags)	DB *dbp;	u_int32_t flags;{	DB_ENV *dbenv;	dbenv = dbp->dbenv;	PANIC_CHECK(dbenv);	/* Validate arguments, but as a DB handle destructor, we can't fail. */	if (flags != 0 && flags != DB_NOSYNC)		(void)__db_ferr(dbenv, "DB->close", 0);	return (__db_close_i(dbp, NULL, flags));}/* * __db_close_i -- *	Internal DB destructor. * * PUBLIC: int __db_close_i __P((DB *, DB_TXN *, u_int32_t)); */int__db_close_i(dbp, txn, flags)	DB *dbp;	DB_TXN *txn;	u_int32_t flags;{	DB_ENV *dbenv;	int ret, t_ret;	dbenv = dbp->dbenv;	ret = 0;	/*	 * Validate arguments, but as a DB handle destructor, we can't fail.	 *	 * Check for consistent transaction usage -- ignore errors.  Only	 * internal callers specify transactions, so it's a serious problem	 * if we get error messages.	 */	if (txn != NULL)		(void)__db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0);	/* Refresh the structure and close any local environment. */	if ((t_ret = __db_refresh(dbp, txn, flags)) != 0 && ret == 0)		ret = t_ret;	/*	 * Call the access specific close function.	 *	 * !!!	 * Because of where these functions are called in the DB handle close	 * process, these routines can't do anything that would dirty pages or	 * otherwise affect closing down the database.  Specifically, we can't	 * abort and recover any of the information they control.	 */	if ((t_ret = __ham_db_close(dbp)) != 0 && ret == 0)		ret = t_ret;	if ((t_ret = __bam_db_close(dbp)) != 0 && ret == 0)		ret = t_ret;	if ((t_ret = __qam_db_close(dbp)) != 0 && ret == 0)		ret = t_ret;	--dbenv->db_ref;	if (F_ISSET(dbenv, DB_ENV_DBLOCAL) && dbenv->db_ref == 0 &&	    (t_ret = dbenv->close(dbenv, 0)) != 0 && ret == 0)		ret = t_ret;	/* Free the database handle. */	memset(dbp, CLEAR_BYTE, sizeof(*dbp));	__os_free(dbenv, dbp);	return (ret);}/* * __db_refresh -- *	Refresh the DB structure, releasing any allocated resources. * This does most of the work of closing files now because refresh * is what is used during abort processing (since we can't destroy * the actual handle) and during abort processing, we may have a * fully opened handle. * * PUBLIC: int __db_refresh __P((DB *, DB_TXN *, u_int32_t)); */int__db_refresh(dbp, txn, flags)	DB *dbp;	DB_TXN *txn;	u_int32_t flags;{	DB *sdbp;	DBC *dbc;	DB_ENV *dbenv;	DB_LOCKREQ lreq;	DB_MPOOL *dbmp;	int ret, t_ret;	ret = 0;	dbenv = dbp->dbenv;	/* If never opened, or not currently open, it's easy. */	if (!F_ISSET(dbp, DB_AM_OPEN_CALLED))		goto never_opened;	/*	 * If we have any secondary indices, disassociate them from us.	 * We don't bother with the mutex here;  it only protects some	 * of the ops that will make us core-dump mid-close anyway, and	 * if you're trying to do something with a secondary *while* you're	 * closing the primary, you deserve what you get.  The disassociation	 * is mostly done just so we can close primaries and secondaries in	 * any order--but within one thread of control.	 */	for (sdbp = LIST_FIRST(&dbp->s_secondaries);	    sdbp != NULL; sdbp = LIST_NEXT(sdbp, s_links)) {		LIST_REMOVE(sdbp, s_links);		if ((t_ret = __db_disassociate(sdbp)) != 0 && ret == 0)			ret = t_ret;	}	/*	 * Sync the underlying access method.  Do before closing the cursors	 * because DB->sync allocates cursors in order to write Recno backing	 * source text files.	 */	if (!LF_ISSET(DB_NOSYNC) && !F_ISSET(dbp, DB_AM_DISCARD) &&	    (t_ret = dbp->sync(dbp, 0)) != 0 && ret == 0)		ret = t_ret;	/*	 * Go through the active cursors and call the cursor recycle routine,	 * which resolves pending operations and moves the cursors onto the	 * free list.  Then, walk the free list and call the cursor destroy	 * routine.  Note that any failure on a close is considered "really	 * bad" and we just break out of the loop and force forward.	 */	while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL)		if ((t_ret = dbc->c_close(dbc)) != 0) {			if (ret == 0)				ret = t_ret;			break;		}	while ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL)		if ((t_ret = __db_c_destroy(dbc)) != 0) {			if (ret == 0)				ret = t_ret;			break;		}	/*	 * Close any outstanding join cursors.  Join cursors destroy	 * themselves on close and have no separate destroy routine.	 */	while ((dbc = TAILQ_FIRST(&dbp->join_queue)) != NULL)		if ((t_ret = dbc->c_close(dbc)) != 0) {			if (ret == 0)				ret = t_ret;			break;		}	/*	 * Sync the memory pool, even though we've already called DB->sync,	 * because closing cursors can dirty pages by deleting items they	 * referenced.	 */	if (!LF_ISSET(DB_NOSYNC) && !F_ISSET(dbp, DB_AM_DISCARD) &&	    (t_ret = dbp->mpf->sync(dbp->mpf)) != 0 && ret == 0)		ret = t_ret;	/* Close any handle we've been holding since the open.  */	if (dbp->saved_open_fhp != NULL &&	    F_ISSET(dbp->saved_open_fhp, DB_FH_VALID) &&	    (t_ret = __os_closehandle(dbenv, dbp->saved_open_fhp)) != 0 &&	    ret == 0)		ret = t_ret;never_opened:	/*	 * We are not releasing the handle lock here because we're about	 * to release all locks held by dbp->lid below.  There are two	 * ways that we can get in here with a handle_lock, but not a	 * dbp->lid.  The first is when our lid has been hijacked by a	 * subdb.  The second is when we are a Queue database in the midst	 * of a rename.  If the queue file hasn't actually been opened, we	 * hijack the main dbp's locker id to do the open so we can get the	 * extent files.  In both cases, we needn't free the handle lock	 * because it will be freed when the hijacked locker-id is freed.	 */	DB_ASSERT(!LOCK_ISSET(dbp->handle_lock) ||	    dbp->lid != DB_LOCK_INVALIDID ||	    dbp->type == DB_QUEUE ||	    F_ISSET(dbp, DB_AM_SUBDB));	if (dbp->lid != DB_LOCK_INVALIDID) {		/* We may have pending trade operations on this dbp. */		if (txn != NULL)			__txn_remlock(dbenv, txn, &dbp->handle_lock, dbp->lid);		/* We may be holding the handle lock; release it. */		lreq.op = DB_LOCK_PUT_ALL;		if ((t_ret = __lock_vec(dbenv,		    dbp->lid, 0, &lreq, 1, NULL)) != 0 && ret == 0)			ret = t_ret;		if ((t_ret =		    dbenv->lock_id_free(dbenv, dbp->lid)) != 0 && ret == 0)			ret = t_ret;		dbp->lid = DB_LOCK_INVALIDID;		LOCK_INIT(dbp->handle_lock);	}	/* Discard the locker ID allocated as the fileid. */	if (F_ISSET(dbp, DB_AM_INMEM) &&	    LOCKING_ON(dbenv) && (t_ret = dbenv->lock_id_free(	    dbenv, *(u_int32_t *)dbp->fileid)) != 0 && ret == 0)		ret = t_ret;	dbp->type = DB_UNKNOWN;	/* Discard the thread mutex. */	if (dbp->mutexp != NULL) {		dbmp = dbenv->mp_handle;		__db_mutex_free(dbenv, dbmp->reginfo, dbp->mutexp);		dbp->mutexp = NULL;	}	/* Discard any memory used to store returned data. */	if (dbp->my_rskey.data != NULL)		__os_free(dbp->dbenv, dbp->my_rskey.data);	if (dbp->my_rkey.data != NULL)		__os_free(dbp->dbenv, dbp->my_rkey.data);	if (dbp->my_rdata.data != NULL)		__os_free(dbp->dbenv, dbp->my_rdata.data);	/* For safety's sake;  we may refresh twice. */	memset(&dbp->my_rskey, 0, sizeof(DBT));	memset(&dbp->my_rkey, 0, sizeof(DBT));	memset(&dbp->my_rdata, 0, sizeof(DBT));	/*	 * Remove this DB handle from the DB_ENV's dblist, if it's been added.	 */	MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);	if (dbp->dblistlinks.le_prev != NULL)		LIST_REMOVE(dbp, dblistlinks);	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);	dbp->dblistlinks.le_prev = NULL;	/* Close the memory pool file handle. */	if (dbp->mpf != NULL) {		if ((t_ret = dbp->mpf->close(dbp->mpf,		    F_ISSET(dbp, DB_AM_DISCARD) ? DB_MPOOL_DISCARD : 0)) != 0 &&		    ret == 0)			ret = t_ret;		dbp->mpf = NULL;	}	if (LOGGING_ON(dbp->dbenv)) {		/*		 * Discard the log file id, if any.  We want to log the close		 * if and only if this is not a recovery dbp.		 */		if (F_ISSET(dbp, DB_AM_RECOVER))

⌨️ 快捷键说明

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