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

📄 db_dispatch.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
	db_pgno_t pgno;	db_lockmode_t mode;	DB_TXN *ptxn, *txn;{	DBT lock_dbt;	DB_LOCK lock;	DB_LOCK_ILOCK lock_obj;	DB_LOCKREQ req;	int ret;	lock_obj.pgno = pgno;	memcpy(lock_obj.fileid, fileid, DB_FILE_ID_LEN);	lock_obj.type = DB_PAGE_LOCK;	memset(&lock_dbt, 0, sizeof(lock_dbt));	lock_dbt.data = &lock_obj;	lock_dbt.size = sizeof(lock_obj);	if ((ret = dbenv->lock_get(dbenv,	    txn->txnid, 0, &lock_dbt, mode, &lock)) == 0) {		memset(&req, 0, sizeof(req));		req.lock = lock;		req.op = DB_LOCK_TRADE;		ret = dbenv->lock_vec(dbenv, ptxn->txnid, 0, &req, 1, NULL);	}	return (ret);}/* * __db_limbo_move *	Move just the metapage lock to the parent. */static int__db_limbo_move(dbenv, ptxn, txn, elp)	DB_ENV *dbenv;	DB_TXN *ptxn, *txn;	DB_TXNLIST *elp;{	int ret;	for (; elp != NULL; elp = LIST_NEXT(elp, links)) {		if (elp->type != TXNLIST_PGNO || elp->u.p.locked == 1)			continue;		if ((ret = __db_lock_move(dbenv, elp->u.p.uid,		    PGNO_BASE_MD, DB_LOCK_WRITE, ptxn, txn)) != 0)			return (ret);		elp->u.p.locked = 1;	}	return (0);}/* * __db_limbo_bucket *	Perform limbo processing for a single hash bucket in the txnlist. * txn is the transaction aborting in the case of an abort and ctxn is the * compensating transaction. */#define T_RESTORED(txn)       ((txn) != NULL && F_ISSET(txn, TXN_RESTORED))static int__db_limbo_bucket(dbenv, txn, elp)	DB_ENV *dbenv;	DB_TXN *txn;	DB_TXNLIST *elp;{	DB *dbp;	DB_MPOOLFILE *mpf;	DBMETA *meta;	DB_TXN *ctxn, *t;	db_pgno_t last_pgno, pgno;	int dbp_created, in_retry, ret, t_ret;	ctxn = NULL;	in_retry = 0;	meta = NULL;	mpf = NULL;	ret = 0;	for (; elp != NULL; elp = LIST_NEXT(elp, links)) {		if (elp->type != TXNLIST_PGNO)			continue;retry:		dbp_created = 0;		/*		 * Pick the transaction in which to potentially		 * log compensations.		 */		if (!in_retry && !IS_RECOVERING(dbenv) && !T_RESTORED(txn)		    && (ret = __txn_compensate_begin(dbenv, &ctxn)) != 0)			return (ret);		/*		 * Either use the compensating transaction or		 * the one passed in, which will be null if recovering.		 */		t = ctxn == NULL ? txn : ctxn;		/* First try to get a dbp by fileid. */		ret = __dbreg_id_to_db(dbenv, t, &dbp, elp->u.p.fileid, 0);		/*		 * File is being destroyed.  No need to worry about		 * dealing with recovery of allocations.		 */		if (ret == DB_DELETED ||		    (ret == 0 && F_ISSET(dbp, DB_AM_DISCARD)))			goto next;		if (ret != 0) {			if ((ret = db_create(&dbp, dbenv, 0)) != 0)				goto err;			/*			 * This tells the system not to lock, which is always			 * OK, whether this is an abort or recovery.			 */			F_SET(dbp, DB_AM_COMPENSATE);			dbp_created = 1;			/* It is ok if the file is nolonger there. */			dbp->type = DB_UNKNOWN;			ret = __db_dbopen(dbp, t, elp->u.p.fname, NULL,			    DB_ODDFILESIZE, __db_omode("rw----"), PGNO_BASE_MD);			if (ret == ENOENT)				goto next;		}		/*		 * Verify that we are opening the same file that we were		 * referring to when we wrote this log record.		 */		if (memcmp(elp->u.p.uid, dbp->fileid, DB_FILE_ID_LEN) != 0)			goto next;		mpf = dbp->mpf;		last_pgno = PGNO_INVALID;		if (ctxn == NULL) {			pgno = PGNO_BASE_MD;			if ((ret =			    mpf->get(mpf, &pgno, 0, (PAGE **)&meta)) != 0)				goto err;			last_pgno = meta->free;		}		ret = __db_limbo_fix(dbp, ctxn, elp, &last_pgno, meta);		/*		 * If we were doing compensating transactions, then we are		 * going to hope this error was due to running out of space.		 * We'll change modes (into the sync the file mode) and keep		 * trying.  If we weren't doing compensating transactions,		 * then this is a real error and we're sunk.		 */		if (ret != 0) {			if (ret == DB_RUNRECOVERY || ctxn == NULL)				goto err;			in_retry = 1;			goto retry;		}		if (ctxn != NULL) {			ret = ctxn->commit(ctxn, DB_TXN_NOSYNC);			ctxn = NULL;			if (ret != 0)				goto retry;			goto next;		}		/*		 * This is where we handle the case where we're explicitly		 * putting together a free list.  We need to decide whether		 * we have to write the meta-data page, and if we do, then		 * we need to sync it as well.		 */		if (last_pgno == meta->free) {			/* No change to page; just put the page back. */			if ((ret = mpf->put(mpf, meta, 0)) != 0)				goto err;			meta = NULL;		} else {			/*			 * These changes are unlogged so we cannot have the			 * metapage pointing at pages that are not on disk.			 * Therefore, we flush the new free list, then update			 * the metapage.  We have to put the meta-data page			 * first so that it isn't pinned when we try to sync.			 */			if (!IS_RECOVERING(dbenv) && !T_RESTORED(txn))				__db_err(dbenv, "Flushing free list to disk");			if ((ret = mpf->put(mpf, meta, 0)) != 0)				goto err;			meta = NULL;			dbp->sync(dbp, 0);			pgno = PGNO_BASE_MD;			if ((ret =			    mpf->get(mpf, &pgno, 0, (PAGE **)&meta)) != 0)				goto err;			meta->free = last_pgno;			if ((ret = mpf->put(mpf, meta, DB_MPOOL_DIRTY)) != 0)				goto err;			meta = NULL;		}next:		/*		 * If we get here, either we have processed the list		 * or the db file has been deleted or could no be opened.		 */		if (ctxn != NULL &&		    (t_ret = ctxn->abort(ctxn)) != 0 && ret == 0)			ret = t_ret;		if (dbp_created &&		    (t_ret = __db_close_i(dbp, txn, 0)) != 0 && ret == 0)			ret = t_ret;		dbp = NULL;		__os_free(dbenv, elp->u.p.fname);		__os_free(dbenv, elp->u.p.pgno_array);		if (ret == ENOENT)			ret = 0;		else if (ret != 0)			goto err;	}err:	if (meta != NULL)		(void)mpf->put(mpf, meta, 0);	return (ret);}/* * __db_limbo_fix -- *	Process a single limbo entry which describes all the page allocations * for a single file. */static int__db_limbo_fix(dbp, ctxn, elp, lastp, meta)	DB *dbp;	DB_TXN *ctxn;	DB_TXNLIST *elp;	db_pgno_t *lastp;	DBMETA *meta;{	DBC *dbc;	DB_MPOOLFILE *mpf;	PAGE *freep, *pagep;	db_pgno_t next, pgno;	int i, put_page, ret, t_ret;	/*	 * Loop through the entries for this txnlist element and	 * either link them into the free list or write a compensating	 * record for each.	 */	put_page = 0;	ret = 0;	mpf = dbp->mpf;	dbc = NULL;	for (i = 0; i < elp->u.p.nentries; i++) {		pgno = elp->u.p.pgno_array[i];		if ((ret = mpf->get(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0)			goto err;		put_page = 1;		if (IS_ZERO_LSN(LSN(pagep))) {			if (ctxn == NULL) {				/*				 * If this is a fatal recovery which				 * spans a previous crash this page may				 * be on the free list already.				 */				for (next = *lastp; next != 0; ) {					if (next == pgno)						break;					if ((ret = mpf->get(mpf,					    &next, 0, &freep)) != 0)						goto err;					next = NEXT_PGNO(freep);					if ((ret =					    mpf->put(mpf, freep, 0)) != 0)						goto err;				}				if (next != pgno) {					P_INIT(pagep, dbp->pgsize, pgno,					    PGNO_INVALID, *lastp, 0, P_INVALID);					LSN(pagep) = LSN(meta);					*lastp = pgno;				}			} else {				P_INIT(pagep, dbp->pgsize, pgno,				    PGNO_INVALID, *lastp, 0, P_INVALID);				if (dbc == NULL && (ret =				    dbp->cursor(dbp, ctxn, &dbc, 0)) != 0)						goto err;				/*				 * If the dbp is compensating (because we				 * opened it), the dbc will automatically be				 * marked compensating, but in case we didn't				 * do the open, we have to mark it explicitly.				 */				F_SET(dbc, DBC_COMPENSATE);				ret = __db_free(dbc, pagep);				put_page = 0;				/*				 * On any error, we hope that the error was				 * caused due to running out of space, and we				 * switch modes, doing the processing where we				 * sync out files instead of doing compensating				 * transactions.  If this was a real error and				 * not out of space, we assume that some other				 * call will fail real soon.				 */				if (ret != 0) {					/* Assume that this is out of space. */					(void)dbc->c_close(dbc);					dbc = NULL;					goto err;				}			}		}		if (put_page == 1) {			ret = mpf->put(mpf, pagep, DB_MPOOL_DIRTY);			put_page = 0;		}		if (ret != 0)			goto err;	}err:	if (put_page &&	    (t_ret = mpf->put(mpf, pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0)		ret = t_ret;	if (dbc != NULL && (t_ret = dbc->c_close(dbc)) != 0 && ret == 0)		ret = t_ret;	return (ret);}#define	DB_TXNLIST_MAX_PGNO	8		/* A nice even number. *//* * __db_txnlist_pgnoadd -- *	Find the txnlist entry for a file and add this pgno, or add the list *	entry for the file and then add the pgno. */static int__db_txnlist_pgnoadd(dbenv, hp, fileid, uid, fname, pgno)	DB_ENV *dbenv;	DB_TXNHEAD *hp;	int32_t fileid;	u_int8_t uid[DB_FILE_ID_LEN];	char *fname;	db_pgno_t pgno;{	DB_TXNLIST *elp;	u_int32_t hash;	int len, ret;	elp = NULL;	if (__db_txnlist_find_internal(dbenv, hp,	    TXNLIST_PGNO, 0, uid, &elp, 0) != 0) {		if ((ret =		    __os_malloc(dbenv, sizeof(DB_TXNLIST), &elp)) != 0)			goto err;		memcpy(&hash, uid, sizeof(hash));		LIST_INSERT_HEAD(		    &hp->head[DB_TXNLIST_MASK(hp, hash)], elp, links);		elp->u.p.fileid = fileid;		memcpy(elp->u.p.uid, uid, DB_FILE_ID_LEN);		len = (int)strlen(fname) + 1;		if ((ret = __os_malloc(dbenv, len, &elp->u.p.fname)) != 0)			goto err;		memcpy(elp->u.p.fname, fname, len);		elp->u.p.maxentry = 0;		elp->u.p.locked = 0;		elp->type = TXNLIST_PGNO;		if ((ret = __os_malloc(dbenv,		    8 * sizeof(db_pgno_t), &elp->u.p.pgno_array)) != 0)			goto err;		elp->u.p.maxentry = DB_TXNLIST_MAX_PGNO;		elp->u.p.nentries = 0;	} else if (elp->u.p.nentries == elp->u.p.maxentry) {		elp->u.p.maxentry <<= 1;		if ((ret = __os_realloc(dbenv, elp->u.p.maxentry *		    sizeof(db_pgno_t), &elp->u.p.pgno_array)) != 0)			goto err;	}	elp->u.p.pgno_array[elp->u.p.nentries++] = pgno;	return (0);err:	__db_txnlist_end(dbenv, hp);	return (ret);}/* * __db_default_getpgnos -- *	Fill in default getpgnos information for an application-specific * log record. */static int__db_default_getpgnos(dbenv, lsnp, summary)	DB_ENV *dbenv;	DB_LSN *lsnp;	void *summary;{	TXN_RECS *t;	int ret;	t = (TXN_RECS *)summary;	if ((ret = __rep_check_alloc(dbenv, t, 1)) != 0)		return (ret);	t->array[t->npages].flags = LSN_PAGE_NOLOCK;	t->array[t->npages].lsn = *lsnp;	t->array[t->npages].fid = DB_LOGFILEID_INVALID;	memset(&t->array[t->npages].pgdesc, 0,	    sizeof(t->array[t->npages].pgdesc));	t->npages++;	return (0);}#ifdef DEBUG/* * __db_txnlist_print -- *	Print out the transaction list. * * PUBLIC: void __db_txnlist_print __P((void *)); */void__db_txnlist_print(listp)	void *listp;{	DB_TXNHEAD *hp;	DB_TXNLIST *p;	int i;	char *stats[] = { "ok", "commit", "prepare", "abort", "notfound",	    "ignore", "expected", "unexpected" };	hp = (DB_TXNHEAD *)listp;	printf("Maxid: %lu Generation: %lu\n",	    (u_long)hp->maxid, (u_long)hp->generation);	for (i = 0; i < hp->nslots; i++)	for (p = LIST_FIRST(&hp->head[i]); p != NULL; p = LIST_NEXT(p, links)) {		switch (p->type) {		case TXNLIST_TXNID:			printf("TXNID: %lx(%lu): %s\n",			    (u_long)p->u.t.txnid, (u_long)p->u.t.generation,			    stats[p->u.t.status]);			break;		default:			printf("Unrecognized type: %d\n", p->type);			break;		}	}}#endif

⌨️ 快捷键说明

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