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

📄 bt_verify.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
				if (ret == DB_VERIFY_BAD)					isbad = 1;				else					goto done;			}		if ((ret = __db_vrfy_ccclose(cc)) != 0)			goto err;		cc = NULL;		/* Case 1 */		if (pip->type == P_LRECNO) {			if (!LF_ISSET(ST_IS_RECNO) &&			    !(LF_ISSET(ST_DUPOK) && !LF_ISSET(ST_DUPSORT))) {				isbad = 1;				EPRINT((dbp->dbenv,				    "Page %lu: recno leaf page non-recno tree",				    (u_long)pgno));				goto done;			}			goto leaf;		} else if (LF_ISSET(ST_IS_RECNO)) {			/*			 * It's a non-recno leaf.  Had better not be a recno			 * subtree.			 */			isbad = 1;			EPRINT((dbp->dbenv,			    "Page %lu: non-recno leaf page in recno tree",			    (u_long)pgno));			goto done;		}		/* Case 2--no more work. */		if (pip->type == P_LDUP)			goto leaf;		/* Case 3 */		/* Check if we have any dups. */		if (F_ISSET(pip, VRFY_HAS_DUPS)) {			/* If dups aren't allowed in this btree, trouble. */			if (!LF_ISSET(ST_DUPOK)) {				isbad = 1;				EPRINT((dbp->dbenv,				    "Page %lu: duplicates in non-dup btree",				    (u_long)pgno));			} else {				/*				 * We correctly have dups.  If any are off-page,				 * traverse those btrees recursively.				 */				if ((ret =				    __db_vrfy_childcursor(vdp, &cc)) != 0)					goto err;				for (ret = __db_vrfy_ccset(cc, pgno, &child);				    ret == 0;				    ret = __db_vrfy_ccnext(cc, &child)) {					stflags = flags | ST_RECNUM | ST_DUPSET;					/* Skip any overflow entries. */					if (child->type == V_DUPLICATE) {						if ((ret = __db_vrfy_duptype(						    dbp, vdp, child->pgno,						    stflags)) != 0) {							isbad = 1;							/* Next child. */							continue;						}						if ((ret = __bam_vrfy_subtree(						    dbp, vdp, child->pgno, NULL,						    NULL, stflags | ST_TOPLEVEL,						    NULL, NULL, NULL)) != 0) {							if (ret !=							    DB_VERIFY_BAD)								goto err;							else								isbad = 1;						}					}				}				if ((ret = __db_vrfy_ccclose(cc)) != 0)					goto err;				cc = NULL;				/*				 * If VRFY_DUPS_UNSORTED is set,				 * ST_DUPSORT had better not be.				 */				if (F_ISSET(pip, VRFY_DUPS_UNSORTED) &&				    LF_ISSET(ST_DUPSORT)) {					EPRINT((dbp->dbenv,		    "Page %lu: unsorted duplicate set in sorted-dup database",					    (u_long)pgno));					isbad = 1;				}			}		}		goto leaf;	case P_IBTREE:	case P_IRECNO:		/* We handle these below. */		break;	default:		/*		 * If a P_IBTREE or P_IRECNO contains a reference to an		 * invalid page, we'll wind up here;  handle it gracefully.		 * Note that the code at the "done" label assumes that the		 * current page is a btree/recno one of some sort;  this		 * is not the case here, so we goto err.		 *		 * If the page is entirely zeroed, its pip->type will be a lie		 * (we assumed it was a hash page, as they're allowed to be		 * zeroed);  handle this case specially.		 */		if (F_ISSET(pip, VRFY_IS_ALLZEROES))			ZEROPG_ERR_PRINT(dbp->dbenv,			    pgno, "btree or recno page");		else			EPRINT((dbp->dbenv,	    "Page %lu: btree or recno page is of inappropriate type %lu",			    (u_long)pgno, (u_long)pip->type));		ret = DB_VERIFY_BAD;		goto err;	}	/*	 * Cases 4 & 5: This is a btree or recno internal page.  For each child,	 * recurse, keeping a running count of nrecs and making sure the level	 * is always reasonable.	 */	if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0)		goto err;	for (ret = __db_vrfy_ccset(cc, pgno, &child); ret == 0;	    ret = __db_vrfy_ccnext(cc, &child))		if (child->type == V_RECNO) {			if (pip->type != P_IRECNO) {				TYPE_ERR_PRINT(dbp->dbenv, "__bam_vrfy_subtree",				    pgno, pip->type);				DB_ASSERT(0);				ret = EINVAL;				goto err;			}			if ((ret = __bam_vrfy_subtree(dbp, vdp, child->pgno,			    NULL, NULL, flags, &child_level, &child_nrecs,			    &child_relen)) != 0) {				if (ret != DB_VERIFY_BAD)					goto done;				else					isbad = 1;			}			if (LF_ISSET(ST_RELEN)) {				if (relen == 0)					relen = child_relen;				/*				 * child_relen may be zero if the child subtree				 * is empty.				 */				else if (child_relen > 0 &&				    relen != child_relen) {					isbad = 1;					EPRINT((dbp->dbenv,			   "Page %lu: recno page returned bad re_len %lu",					    (u_long)child->pgno,					    (u_long)child_relen));				}				if (relenp)					*relenp = relen;			}			if (LF_ISSET(ST_RECNUM))				nrecs += child_nrecs;			if (level != child_level + 1) {				isbad = 1;   EPRINT((dbp->dbenv, "Page %lu: recno level incorrect: got %lu, expected %lu",				    (u_long)child->pgno, (u_long)child_level,				    (u_long)(level - 1)));			}		} else if (child->type == V_OVERFLOW &&		    (ret = __db_vrfy_ovfl_structure(dbp, vdp,		    child->pgno, child->tlen, flags)) != 0) {			if (ret == DB_VERIFY_BAD)				isbad = 1;			else				goto done;		}	if ((ret = __db_vrfy_ccclose(cc)) != 0)		goto err;	cc = NULL;	/* We're done with case 4. */	if (pip->type == P_IRECNO)		goto done;	/*	 * Case 5.  Btree internal pages.	 * As described above, we need to iterate through all the	 * items on the page and make sure that our children sort appropriately	 * with respect to them.	 *	 * For each entry, li will be the "left-hand" key for the entry	 * itself, which must sort lower than all entries on its child;	 * ri will be the key to its right, which must sort greater.	 */	if (h == NULL && (ret = mpf->get(mpf, &pgno, 0, &h)) != 0)		goto err;	for (i = 0; i < pip->entries; i += O_INDX) {		li = GET_BINTERNAL(dbp, h, i);		ri = (i + O_INDX < pip->entries) ?		    GET_BINTERNAL(dbp, h, i + O_INDX) : NULL;		/*		 * The leftmost key is forcibly sorted less than all entries,		 * so don't bother passing it.		 */		if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno,		    i == 0 ? NULL : li, ri, flags, &child_level,		    &child_nrecs, NULL)) != 0) {			if (ret != DB_VERIFY_BAD)				goto done;			else				isbad = 1;		}		if (LF_ISSET(ST_RECNUM)) {			/*			 * Keep a running tally on the actual record count so			 * we can return it to our parent (if we have one) or			 * compare it to the NRECS field if we're a root page.			 */			nrecs += child_nrecs;			/*			 * Make sure the actual record count of the child			 * is equal to the value in the BINTERNAL structure.			 */			if (li->nrecs != child_nrecs) {				isbad = 1;				EPRINT((dbp->dbenv,	"Page %lu: item %lu has incorrect record count of %lu, should be %lu",				    (u_long)pgno, (u_long)i, (u_long)li->nrecs,				    (u_long)child_nrecs));			}		}		if (level != child_level + 1) {			isbad = 1;			EPRINT((dbp->dbenv,		"Page %lu: Btree level incorrect: got %lu, expected %lu",			    (u_long)li->pgno,			    (u_long)child_level, (u_long)(level - 1)));		}	}	if (0) {leaf:		level = LEAFLEVEL;		if (LF_ISSET(ST_RECNUM))			nrecs = pip->rec_cnt;		/* XXX		 * We should verify that the record count on a leaf page		 * is the sum of the number of keys and the number of		 * records in its off-page dups.  This requires looking		 * at the page again, however, and it may all be changing		 * soon, so for now we don't bother.		 */		if (LF_ISSET(ST_RELEN) && relenp)			*relenp = pip->re_len;	}done:	if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) {		/*		 * During the page-by-page pass, item order verification was		 * not finished due to the presence of overflow items.  If		 * isbad == 0, though, it's now safe to do so, as we've		 * traversed any child overflow pages.  Do it.		 */		if (h == NULL && (ret = mpf->get(mpf, &pgno, 0, &h)) != 0)			goto err;		if ((ret = __bam_vrfy_itemorder(dbp,		    vdp, h, pgno, 0, 1, 0, flags)) != 0)			goto err;		F_CLR(pip, VRFY_INCOMPLETE);	}	/*	 * It's possible to get to this point with a page that has no	 * items, but without having detected any sort of failure yet.	 * Having zero items is legal if it's a leaf--it may be the	 * root page in an empty tree, or the tree may have been	 * modified with the DB_REVSPLITOFF flag set (there's no way	 * to tell from what's on disk).  For an internal page,	 * though, having no items is a problem (all internal pages	 * must have children).	 */	if (isbad == 0 && ret == 0) {		if (h == NULL && (ret = mpf->get(mpf, &pgno, 0, &h)) != 0)			goto err;		if (NUM_ENT(h) == 0 && ISINTERNAL(h)) {			EPRINT((dbp->dbenv,		    "Page %lu: internal page is empty and should not be",			    (u_long)pgno));			isbad = 1;			goto err;		}	}	/*	 * Our parent has sent us BINTERNAL pointers to parent records	 * so that we can verify our place with respect to them.  If it's	 * appropriate--we have a default sort function--verify this.	 */	if (isbad == 0 && ret == 0 && !LF_ISSET(DB_NOORDERCHK) && lp != NULL) {		if (h == NULL && (ret = mpf->get(mpf, &pgno, 0, &h)) != 0)			goto err;		/*		 * __bam_vrfy_treeorder needs to know what comparison function		 * to use.  If ST_DUPSET is set, we're in a duplicate tree		 * and we use the duplicate comparison function;  otherwise,		 * use the btree one.  If unset, use the default, of course.		 */		func = LF_ISSET(ST_DUPSET) ? dbp->dup_compare :		    ((BTREE *)dbp->bt_internal)->bt_compare;		if (func == NULL)			func = __bam_defcmp;		if ((ret = __bam_vrfy_treeorder(		    dbp, pgno, h, lp, rp, func, flags)) != 0) {			if (ret == DB_VERIFY_BAD)				isbad = 1;			else				goto err;		}	}	/*	 * This is guaranteed to succeed for leaf pages, but no harm done.	 *	 * Internal pages below the top level do not store their own	 * record numbers, so we skip them.	 */	if (LF_ISSET(ST_RECNUM) && nrecs != pip->rec_cnt && toplevel) {		isbad = 1;		EPRINT((dbp->dbenv,		    "Page %lu: bad record count: has %lu records, claims %lu",		    (u_long)pgno, (u_long)nrecs, (u_long)pip->rec_cnt));	}	if (levelp)		*levelp = level;	if (nrecsp)		*nrecsp = nrecs;	pgset = vdp->pgset;	if ((ret = __db_vrfy_pgset_get(pgset, pgno, &p)) != 0)		goto err;	if (p != 0) {		isbad = 1;		EPRINT((dbp->dbenv, "Page %lu: linked twice", (u_long)pgno));	} else if ((ret = __db_vrfy_pgset_inc(pgset, pgno)) != 0)		goto err;	if (toplevel)		/*		 * The last page's next_pgno in the leaf chain should have been		 * PGNO_INVALID.		 */		if (vdp->next_pgno != PGNO_INVALID) {			EPRINT((dbp->dbenv, "Page %lu: unterminated leaf chain",			    (u_long)vdp->prev_pgno));			isbad = 1;		}err:	if (toplevel) {		/* Restore our caller's settings. */		vdp->next_pgno = next_pgno;		vdp->prev_pgno = prev_pgno;		vdp->leaf_type = leaf_type;	}	if (h != NULL && (t_ret = mpf->put(mpf, h, 0)) != 0 && ret == 0)		ret = t_ret;	if ((t_ret =	    __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)		ret = t_ret;	if (cc != NULL && ((t_ret = __db_vrfy_ccclose(cc)) != 0) && ret == 0)		ret = t_ret;	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);}/* * __bam_vrfy_treeorder -- *	Verify that the lowest key on a page sorts greater than the *	BINTERNAL which points to it (lp), and the highest key *	sorts less than the BINTERNAL above that (rp). * *	If lp is NULL, this means that it was the leftmost key on the *	parent, which (regardless of sort function) sorts less than *	all keys.  No need to check it. * *	If rp is NULL, lp was the highest key on the parent, so there's *	no higher key we must sort less than. */static int__bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags)	DB *dbp;	db_pgno_t pgno;	PAGE *h;	BINTERNAL *lp, *rp;	int (*func) __P((DB *, const DBT *, const DBT *));	u_int32_t flags;{	BOVERFLOW *bo;	DBT dbt;	db_indx_t last;	int ret, cmp;	memset(&dbt, 0, sizeof(DBT));	F_SET(&dbt, DB_DBT_MALLOC);	ret = 0;	/*	 * Empty pages are sorted correctly by definition.  We check	 * to see whether they ought to be empty elsewhere;  leaf	 * pages legally may be.	 */	if (NUM_ENT(h) == 0)		return (0);	switch (TYPE(h)) {	case P_IBTREE:	case P_LDUP:		last = NUM_ENT(h) - O_INDX;		break;	case P_LBTREE:		last = NUM_ENT(h) - P_INDX;		break;	default:		TYPE_ERR_PRINT(dbp->dbenv,		    "__bam_vrfy_treeorder", pgno, TYPE(h));		DB_ASSERT(0);		return (EINVAL);	}	/*	 * The key on page h, the child page, is more likely to be	 * an overflow page, so we pass its offset, rather than lp/rp's,	 * into __bam_cmp.  This will take advantage of __db_moff.	 */	/*	 * Skip first-item check if we're an internal page--the first	 * entry on an internal page is treated specially by __bam_cmp,	 * so what's on the page shouldn't matter.  (Plus, since we're passing	 * our page and item 0 as to __bam_cmp, we'll sort before our	 * parent and falsely report a failure.)	 */	if (lp != NULL && TYPE(h) != P_IBTREE) {		if (lp->type == B_KEYDATA) {			dbt.data = lp->data;			dbt.size = lp->len;		} else if (lp->type == B_OVERFLOW) {			bo = (BOVERFLOW *)lp->data;			if ((ret = __db_goff(dbp, &dbt, bo->tlen, bo->pgno,			    NULL, NULL)) != 0)				return (ret);		} else {			DB_ASSERT(0);			EPRINT((dbp->dbenv,			    "Page %lu: unknown type for internal record",			    (u_long)PGNO(h)));			return (EINVAL);		}		/* On error, fall through, free if neeeded, and return. */

⌨️ 快捷键说明

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