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

📄 hash_rec.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	/*	 * Now we need to fix up the spares array.  Each entry in the	 * spares array indicates the beginning page number for the	 * indicated doubling.  We need to fill this in whenever the	 * spares array is invalid, since we never reclaim pages from	 * the spares array and we have to allocate the pages to the	 * spares array in both the redo and undo cases.	 */	if (argp->newalloc &&	    hcp->hdr->spares[__db_log2(argp->bucket + 1) + 1] == PGNO_INVALID) {		hcp->hdr->spares[__db_log2(argp->bucket + 1) + 1] =		    argp->pgno - argp->bucket - 1;		did_recover = 1;	}	/*	 * Finally, we need to potentially fix up the last_pgno field	 * in the master meta-data page (which may or may not be the	 * same as the hash header page).	 */	if (argp->mmpgno != argp->mpgno) {		if ((ret =		    mpf->get(mpf, &argp->mmpgno, 0, (PAGE **)&mmeta)) != 0)			goto out;		mmeta_flags = 0;		cmp_n = log_compare(lsnp, &mmeta->lsn);		cmp_p = log_compare(&mmeta->lsn, &argp->mmetalsn);		if (cmp_p == 0 && DB_REDO(op)) {			mmeta->lsn = *lsnp;			mmeta_flags = DB_MPOOL_DIRTY;		} else if (cmp_n == 0 && DB_UNDO(op)) {			mmeta->lsn = argp->mmetalsn;			mmeta_flags = DB_MPOOL_DIRTY;		}	} else		mmeta = (DBMETA *)hcp->hdr;	if (argp->newalloc) {		if (mmeta->last_pgno < pgno)			mmeta->last_pgno = pgno;		mmeta_flags = DB_MPOOL_DIRTY;	}	if (argp->mmpgno != argp->mpgno &&	    (ret = mpf->put(mpf, mmeta, mmeta_flags)) != 0)		goto out;	mmeta = NULL;	if (did_recover)		F_SET(hcp, H_DIRTY);done:	*lsnp = argp->prev_lsn;	ret = 0;out:	if (mmeta != NULL)		(void)mpf->put(mpf, mmeta, 0);	if (dbc != NULL)		(void)__ham_release_meta(dbc);	if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC)		ret = 0;	REC_CLOSE;}/* * __ham_groupalloc_recover -- *	Recover the batch creation of a set of pages for a new database. * * PUBLIC: int __ham_groupalloc_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_groupalloc_args *argp;	DBMETA *mmeta;	DB_MPOOLFILE *mpf;	DB *file_dbp;	DBC *dbc;	PAGE *pagep;	db_pgno_t pgno;	int cmp_n, cmp_p, modified, ret;	mmeta = NULL;	modified = 0;	REC_PRINT(__ham_groupalloc_print);	REC_INTRO(__ham_groupalloc_read, 0);	pgno = PGNO_BASE_MD;	if ((ret = mpf->get(mpf, &pgno, 0, &mmeta)) != 0) {		if (DB_REDO(op)) {			/* Page should have existed. */			__db_pgerr(file_dbp, pgno, ret);			goto out;		} else {			ret = 0;			goto done;		}	}	cmp_n = log_compare(lsnp, &LSN(mmeta));	cmp_p = log_compare(&LSN(mmeta), &argp->meta_lsn);	CHECK_LSN(op, cmp_p, &LSN(mmeta), &argp->meta_lsn);	/*	 * Basically, we used mpool to allocate a chunk of pages.	 * We need to either add those to a free list (in the undo	 * case) or initialize them (in the redo case).	 *	 * If we are redoing and this is a hash subdatabase, it's possible	 * that the pages were never allocated, so we'd better check for	 * that and handle it here.	 */	if (DB_REDO(op)) {		if ((ret = __ham_alloc_pages(file_dbp, argp, lsnp)) != 0)			goto out;		if (cmp_p == 0) {			LSN(mmeta) = *lsnp;			modified = 1;		}	} else if (DB_UNDO(op)) {		/*		 * Reset the last page back to its preallocation state.		 */		pgno = argp->start_pgno + argp->num - 1;		if ((ret = mpf->get(mpf, &pgno, 0, &pagep)) == 0) {			if (log_compare(&pagep->lsn, lsnp) == 0)				ZERO_LSN(pagep->lsn);			if ((ret = mpf->put(mpf, pagep, DB_MPOOL_DIRTY)) != 0)				goto out;		} else if (ret != DB_PAGE_NOTFOUND)			goto out;		/*		 * Always put the pages into the limbo list and free them later.		 */		if ((ret = __db_add_limbo(dbenv,		    info, argp->fileid, argp->start_pgno, argp->num)) != 0)			goto out;		if (cmp_n == 0) {			LSN(mmeta) = argp->meta_lsn;			modified = 1;		}	}done:	if (ret == 0)		*lsnp = argp->prev_lsn;out:	if (mmeta != NULL)		(void)mpf->put(mpf, mmeta, modified ? DB_MPOOL_DIRTY : 0);	if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC)		ret = 0;	REC_CLOSE;}/* * __ham_alloc_pages -- * * Called during redo of a file create.  We create new pages in the file * using the MPOOL_NEW_GROUP flag.  We then log the meta-data page with a * __crdel_metasub message.  If we manage to crash without the newly written * pages getting to disk (I'm not sure this can happen anywhere except our * test suite?!), then we need to go through a recreate the final pages. * Hash normally has holes in its files and handles them appropriately. */static int__ham_alloc_pages(dbp, argp, lsnp)	DB *dbp;	__ham_groupalloc_args *argp;	DB_LSN *lsnp;{	DB_MPOOLFILE *mpf;	PAGE *pagep;	db_pgno_t pgno;	int ret;	mpf = dbp->mpf;	/* Read the last page of the allocation. */	pgno = argp->start_pgno + argp->num - 1;	/* If the page exists, and it has been initialized, then we're done. */	if ((ret = mpf->get(mpf, &pgno, 0, &pagep)) == 0) {		if (NUM_ENT(pagep) == 0 && IS_ZERO_LSN(pagep->lsn))			goto reinit_page;		if ((ret = mpf->put(mpf, pagep, 0)) != 0)			return (ret);		return (0);	}	/* Had to create the page. */	if ((ret = mpf->get(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) {		__db_pgerr(dbp, pgno, ret);		return (ret);	}reinit_page:	/* Initialize the newly allocated page. */	P_INIT(pagep, dbp->pgsize, pgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH);	pagep->lsn = *lsnp;	if ((ret = mpf->put(mpf, pagep, DB_MPOOL_DIRTY)) != 0)		return (ret);	return (0);}/* * __ham_curadj_recover -- *	Undo cursor adjustments if a subtransaction fails. * * PUBLIC: int __ham_curadj_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_curadj_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_curadj_args *argp;	DB_MPOOLFILE *mpf;	DB *file_dbp;	DBC *dbc;	int ret;	HASH_CURSOR *hcp;	COMPQUIET(info, NULL);	REC_PRINT(__ham_curadj_print);	REC_INTRO(__ham_curadj_read, 0);	if (op != DB_TXN_ABORT)		goto done;	/*	 * Undo the adjustment by reinitializing the the cursor	 * to look like the one that was used to do the adustment,	 * then we invert the add so that undo the adjustment.	 */	hcp = (HASH_CURSOR *)dbc->internal;	hcp->pgno = argp->pgno;	hcp->indx = argp->indx;	hcp->dup_off = argp->dup_off;	hcp->order = argp->order;	if (!argp->add)		F_SET(hcp, H_DELETED);	(void)__ham_c_update(dbc, argp->len, !argp->add, argp->is_dup);done:	*lsnp = argp->prev_lsn;out:	REC_CLOSE;}/* * __ham_chgpg_recover -- *	Undo cursor adjustments if a subtransaction fails. * * PUBLIC: int __ham_chgpg_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_chgpg_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_chgpg_args *argp;	BTREE_CURSOR *opdcp;	DB_MPOOLFILE *mpf;	DB *file_dbp, *ldbp;	DBC *dbc;	int ret;	DBC *cp;	HASH_CURSOR *lcp;	u_int32_t order, indx;	COMPQUIET(info, NULL);	REC_PRINT(__ham_chgpg_print);	REC_INTRO(__ham_chgpg_read, 0);	if (op != DB_TXN_ABORT)		goto done;	/* Overloaded fields for DB_HAM_DEL*PG */	indx = argp->old_indx;	order = argp->new_indx;	MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);	for (ldbp = __dblist_get(dbenv, file_dbp->adj_fileid);	    ldbp != NULL && ldbp->adj_fileid == file_dbp->adj_fileid;	    ldbp = LIST_NEXT(ldbp, dblistlinks)) {		MUTEX_THREAD_LOCK(dbenv, file_dbp->mutexp);		for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL;		    cp = TAILQ_NEXT(cp, links)) {			lcp = (HASH_CURSOR *)cp->internal;			switch (argp->mode) {			case DB_HAM_DELFIRSTPG:				if (lcp->pgno != argp->new_pgno)					break;				if (lcp->indx != indx ||				    !F_ISSET(lcp, H_DELETED) ||				    lcp->order >= order) {					lcp->pgno = argp->old_pgno;					if (lcp->indx == indx)						lcp->order -= order;				}				break;			case DB_HAM_DELMIDPG:			case DB_HAM_DELLASTPG:				if (lcp->pgno == argp->new_pgno &&				    lcp->indx == indx &&				    F_ISSET(lcp, H_DELETED) &&				    lcp->order >= order) {					lcp->pgno = argp->old_pgno;					lcp->order -= order;					lcp->indx = 0;				}				break;			case DB_HAM_CHGPG:				/*				 * If we're doing a CHGPG, we're undoing				 * the move of a non-deleted item to a				 * new page.  Any cursors with the deleted				 * flag set do not belong to this item;				 * don't touch them.				 */				if (F_ISSET(lcp, H_DELETED))					break;				/* FALLTHROUGH */			case DB_HAM_SPLIT:				if (lcp->pgno == argp->new_pgno &&				    lcp->indx == argp->new_indx) {					lcp->indx = argp->old_indx;					lcp->pgno = argp->old_pgno;				}				break;			case DB_HAM_DUP:				if (lcp->opd == NULL)					break;				opdcp = (BTREE_CURSOR *)lcp->opd->internal;				if (opdcp->pgno != argp->new_pgno ||				    opdcp->indx != argp->new_indx)					break;				if (F_ISSET(opdcp, C_DELETED))					F_SET(lcp, H_DELETED);				/*				 * We can't close a cursor while we have the				 * dbp mutex locked, since c_close reacquires				 * it.  It should be safe to drop the mutex				 * here, though, since newly opened cursors				 * are put only at the end of the tailq and				 * the cursor we're adjusting can't be closed				 * under us.				 */				MUTEX_THREAD_UNLOCK(dbenv, file_dbp->mutexp);				if ((ret = lcp->opd->c_close(lcp->opd)) != 0)					goto out;				MUTEX_THREAD_LOCK(dbenv, file_dbp->mutexp);				lcp->opd = NULL;				break;			}		}		MUTEX_THREAD_UNLOCK(dbenv, file_dbp->mutexp);	}	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);done:	*lsnp = argp->prev_lsn;out:	REC_CLOSE;}

⌨️ 快捷键说明

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