!6067 upage ubtree校验增加打印rnode block offset信息

Merge pull request !6067 from 徐达标/0817
This commit is contained in:
opengauss_bot
2024-08-19 08:13:12 +00:00
committed by Gitee
11 changed files with 327 additions and 243 deletions

View File

@ -1898,7 +1898,7 @@ static void VerifyUstorePage(Relation rel, Page page, BlockNumber blkno, ForkNum
UBTRecycleQueueVerifyPageOffline(rel, page, blkno);
}
} else {
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, rel);
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, rel, NULL, blkno);
}
}

View File

@ -34,7 +34,7 @@ static void UBTreeVerifyTupleKey(Relation rel, Page page, BlockNumber blkno, Off
static void UBTreeVerifyRowptrNonDML(Relation rel, Page page, BlockNumber blkno);
static void UBTreeVerifyHeader(PageHeaderData* page, Relation rel, BlockNumber blkno, uint16 pageSize, uint16 headerSize);
static void UBTreeVerifyRowptr(PageHeaderData* header, Page page, BlockNumber blkno, OffsetNumber offset,
ItemIdSort indexSortPtr, const char *indexName, Oid relOid);
ItemIdSort indexSortPtr, const char *indexName, Relation rel);
void UBTreeVerifyIndex(Relation rel, TupleDesc *tupDesc, Tuplestorestate *tupstore, uint32 cols)
{
@ -404,33 +404,33 @@ char* UBTGetVerifiedResultStr(uint32 type)
}
}
bool UBTreeVerifyTupleTransactionStatus(Relation rel, BlockNumber blkno, TransactionIdStatus xminStatus, TransactionIdStatus xmaxStatus,
static bool UBTreeVerifyTupleTransactionStatus(Relation rel, BlockNumber blkno, OffsetNumber offnum,
TransactionIdStatus xminStatus, TransactionIdStatus xmaxStatus,
TransactionId xmin, TransactionId xmax, CommitSeqNo xminCSN, CommitSeqNo xmaxCSN)
{
if (u_sess->attr.attr_storage.ustore_verify_level < USTORE_VERIFY_FAST) {
return false;
}
bool tranStatusError = false;
switch (xminStatus) {
case XID_COMMITTED:
tranStatusError = (xmaxStatus == XID_COMMITTED && xminCSN > xmaxCSN && xmaxCSN != COMMITSEQNO_FROZEN) ? true : false;
tranStatusError = (xmaxStatus == XID_COMMITTED && xminCSN > xmaxCSN && xmaxCSN != COMMITSEQNO_FROZEN);
break;
case XID_INPROGRESS:
tranStatusError = (xmaxStatus == XID_COMMITTED && TransactionIdIsValid(xmax)) ? true : false;
tranStatusError = (xmaxStatus == XID_COMMITTED && TransactionIdIsValid(xmax));
break;
case XID_ABORTED:
tranStatusError = (xminStatus == XID_ABORTED && xmaxStatus != XID_ABORTED) ? true : false;
tranStatusError = (xminStatus == XID_ABORTED && xmaxStatus != XID_ABORTED);
break;
default:
break;
}
if (tranStatusError) {
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] xmin or xmax status invalid, relName=%s, blkno=%u, xmin=%lu, xmax=%lu, xminStatus=%d, "
"xmaxStatus=%d, xminCSN=%lu, xmaxCSN=%lu.", NameStr(rel->rd_rel->relname), blkno, xmin, xmax, xminStatus,
xmaxStatus, xminCSN, xmaxCSN)));
"[Verify UBTree] xmin or xmax status invalid, xmin=%lu, xmax=%lu, xminStatus=%d, "
"xmaxStatus=%d, xminCSN=%lu, xmaxCSN=%lu, rnode[%u,%u,%u], block %u, offnum %u.",
xmin, xmax, xminStatus, xmaxStatus, xminCSN, xmaxCSN,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offnum)));
return false;
}
return true;
@ -440,21 +440,21 @@ static int ItemCompare(const void *item1, const void *item2)
{
return ((ItemIdSort)item1)->start - ((ItemIdSort)item2)->start;
}
void UBTreeVerifyHikey(Relation rel, Page page, BlockNumber blkno)
{
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
Oid relOid = (rel ? rel->rd_id : InvalidOid);
UBTPageOpaqueInternal opaque = (UBTPageOpaqueInternal)PageGetSpecialPointer(page);
if (P_RIGHTMOST(opaque))
return;
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (P_ISLEAF(opaque) ? (opaque->btpo.level != 0) : (opaque->btpo.level == 0)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("UBTREEVERIFY corrupted rel %s, level %u, flag %u, tid[%d:%d]", (rel && rel->rd_rel ? RelationGetRelationName(rel) : "Unknown"),
opaque->btpo.level, opaque->btpo_flags, relOid, blkno)));
errmsg("UBTREEVERIFY corrupted. level %u, flag %u, rnode[%u,%u,%u], block %u.",
opaque->btpo.level, opaque->btpo_flags, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
return;
}
@ -475,34 +475,39 @@ void UBTreeVerifyHikey(Relation rel, Page page, BlockNumber blkno)
index_deform_tuple(lastTuple, RelationGetDescr(rel), values, isnull);
char *keyDesc = BuildIndexValueDescription(rel, values, isnull);
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("UBTREEVERIFY corrupted key %s with HIKEY compare in rel %s, tid[%d:%d]",
(keyDesc ? keyDesc : "(UNKNOWN)"), (rel && rel->rd_rel ? RelationGetRelationName(rel) : "Unknown"), relOid, blkno)));
errmsg("UBTREEVERIFY corrupted key %s with HIKEY compare in rel %s, rnode[%u,%u,%u], block %u.",
(keyDesc ? keyDesc : "(UNKNOWN)"), (rel && rel->rd_rel ? RelationGetRelationName(rel) : "Unknown"),
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
}
void UBTreeVerifyPageXid(Relation rel, BlockNumber blkno, TransactionId xidBase, TransactionId pruneXid)
{
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
const char *indexName = (rel && rel->rd_rel ? RelationGetRelationName(rel) : "unknown");
Oid relOid = (rel ? rel->rd_id : InvalidOid);
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (TransactionIdFollows(xidBase, t_thrd.xact_cxt.ShmemVariableCache->nextXid) ||
TransactionIdPrecedes(xidBase + MaxShortTransactionId, t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] ubtree's page xid_base invalid: indexName=%s, oid=%u, blkno=%u, xid_base=%lu, nextxid=%lu.",
indexName, relOid, blkno, xidBase, t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
"[Verify UBTree] ubtree's page xid_base invalid: indexName=%s, xid_base=%lu, nextxid=%lu, "
"rnode[%u,%u,%u], block %u.",
indexName, xidBase, t_thrd.xact_cxt.ShmemVariableCache->nextXid,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
return;
}
if (TransactionIdFollows(pruneXid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] ubtree's page prune_xid invalid: indexName=%s, oid=%u, blkno=%u, xid_base=%lu, nextxid=%lu.",
indexName, relOid, blkno, pruneXid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
"[Verify UBTree] ubtree's page prune_xid invalid: indexName=%s, xid_base=%lu, nextxid=%lu, "
"rnode[%u,%u,%u], block %u.",
indexName, pruneXid, t_thrd.xact_cxt.ShmemVariableCache->nextXid,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
return;
}
}
void UBTreeVerifyTupleTransactionInfo(Relation rel, Page page, OffsetNumber offnum, bool fromInsert, TransactionId xidBase)
static void UBTreeVerifyTupleTransactionInfo(Relation rel, BlockNumber blkno, Page page,
OffsetNumber offnum, bool fromInsert, TransactionId xidBase)
{
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
@ -511,26 +516,31 @@ void UBTreeVerifyTupleTransactionInfo(Relation rel, Page page, OffsetNumber offn
IndexTuple tuple = (IndexTuple)PageGetItem(page, PageGetItemId(page, offnum));
UstoreIndexXid uxid = (UstoreIndexXid)UstoreIndexTupleGetXid(tuple);
TransactionId xid = fromInsert? ShortTransactionIdToNormal(xidBase, uxid->xmin) : ShortTransactionIdToNormal(xidBase, uxid->xmax);
TransactionId xid = fromInsert ?
ShortTransactionIdToNormal(xidBase, uxid->xmin) : ShortTransactionIdToNormal(xidBase, uxid->xmax);
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (TransactionIdIsNormal(xid) && !TransactionIdIsCurrentTransactionId(xid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmodule(MOD_USTORE), errmsg("[Verify UBTree] tuple xid %s invalid: indexName=%s, oid=%u, xid=%lu.",
(fromInsert ? "xmin" : "xmax"), (rel && rel->rd_rel ? RelationGetRelationName(rel) : "Unknown"),
(rel ? rel->rd_id : InvalidOid), xid)));
errmodule(MOD_USTORE), errmsg("[Verify UBTree] tuple xid %s invalid: indexName=%s, xid=%lu, "
"rnode[%u,%u,%u], block %u, offnum %u.",
(fromInsert ? "xmin" : "xmax"), (rel && rel->rd_rel ? RelationGetRelationName(rel) : "Unknown"), xid,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offnum)));
}
}
void UBTreeVerifyAllTuplesTransactionInfo(Relation rel, Page page, BlockNumber blkno, OffsetNumber startoffset, bool fromInsert,
TransactionId xidBase)
static void UBTreeVerifyAllTuplesTransactionInfo(Relation rel, Page page, BlockNumber blkno,
OffsetNumber startoffset, bool fromInsert, TransactionId xidBase)
{
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
CHECK_VERIFY_LEVEL(USTORE_VERIFY_COMPLETE)
TransactionId maxXmax = InvalidTransactionId;
TransactionId minCommittedXmax = MaxTransactionId;
TransactionId pruneXid = ShortTransactionIdToNormal(xidBase, ((PageHeader)page)->pd_prune_xid);
OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
TransactionId oldestXmin = u_sess->utils_cxt.RecentGlobalDataXmin;
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
for (OffsetNumber offnum = startoffset; offnum <= maxoff; offnum = OffsetNumberNext(offnum)) {
ItemId itemid = PageGetItemId(page, offnum);
IndexTuple tuple = (IndexTuple)PageGetItem(page, itemid);
@ -540,8 +550,10 @@ void UBTreeVerifyAllTuplesTransactionInfo(Relation rel, Page page, BlockNumber b
if (TransactionIdFollows(Max(xmin, xmax), t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] index tuple xid(xmin/xmax) is bigger than nextXid: relName=%s, blkno=%u, xmin=%lu, xmax=%lu, nextxid=%lu, xid_base=%lu.",
NameStr(rel->rd_rel->relname), blkno, xmin, xmax, t_thrd.xact_cxt.ShmemVariableCache->nextXid, xidBase)));
"[Verify UBTree] index tuple xid(xmin/xmax) is bigger than nextXid: "
"xmin=%lu, xmax=%lu, nextxid=%lu, xid_base=%lu, rnode[%u,%u,%u], block %u, offnum %u.",
xmin, xmax, t_thrd.xact_cxt.ShmemVariableCache->nextXid, xidBase,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offnum)));
return;
}
@ -549,15 +561,17 @@ void UBTreeVerifyAllTuplesTransactionInfo(Relation rel, Page page, BlockNumber b
if (TransactionIdIsNormal(xmin) && !IndexItemIdIsFrozen(itemid) &&
TransactionIdPrecedes(xmin + base, oldestXmin)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] index tuple xmin invalid: relName=%s, blkno=%u, xmin=%lu, oldest_xmin=%lu, xid_base=%lu.",
NameStr(rel->rd_rel->relname), blkno, xmin, oldestXmin, xidBase)));
"[Verify UBTree] index tuple xmin invalid: xmin=%lu, oldest_xmin=%lu, xid_base=%lu, "
"rnode[%u,%u,%u], block %u, offnum %u.",
xmin, oldestXmin, xidBase, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offnum)));
return;
}
if (TransactionIdIsNormal(xmax) && !ItemIdIsDead(itemid) &&
TransactionIdPrecedes(xmax + base, oldestXmin)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] index tuple xmin invalid: relName=%s, blkno=%u, xmax=%lu, oldest_xmin=%lu, xid_base=%lu.",
NameStr(rel->rd_rel->relname), blkno, xmax, oldestXmin, xidBase)));
"[Verify UBTree] index tuple xmin invalid: xmax=%lu, oldest_xmin=%lu, xid_base=%lu, "
"rnode[%u,%u,%u], block %u, offnum %u.",
xmax, oldestXmin, xidBase, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offnum)));
return;
}
if (!u_sess->attr.attr_storage.ustore_verify) {
@ -576,10 +590,12 @@ void UBTreeVerifyAllTuplesTransactionInfo(Relation rel, Page page, BlockNumber b
if (xmaxStatus == XID_COMMITTED && TransactionIdPrecedes(xmax, minCommittedXmax)) {
minCommittedXmax = xmax;
}
if (TransactionIdFollows(xmax, maxXmax)) {
maxXmax = xmax;
}
if (!UBTreeVerifyTupleTransactionStatus(rel, blkno, xminStatus, xmaxStatus, xmin, xmax, xminCSN, xmaxCSN)) {
if (!UBTreeVerifyTupleTransactionStatus(rel, blkno, offnum, xminStatus, xmaxStatus,
xmin, xmax, xminCSN, xmaxCSN)) {
return;
}
}
@ -588,8 +604,9 @@ void UBTreeVerifyAllTuplesTransactionInfo(Relation rel, Page page, BlockNumber b
UBTPageOpaqueInternal ubtOpaque = (UBTPageOpaqueInternal)PageGetSpecialPointer(page);
if (TransactionIdFollows(uopaque->xact, t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] xact xid is bigger than nextXid: relName=%s, blkno=%u, xact=%lu, nextxid=%lu.",
NameStr(rel->rd_rel->relname), blkno, uopaque->xact, t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
"[Verify UBTree] xact xid is bigger than nextXid: xact=%lu, nextxid=%lu, rnode[%u,%u,%u], block %u.",
uopaque->xact, t_thrd.xact_cxt.ShmemVariableCache->nextXid,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
return;
}
if (!u_sess->attr.attr_storage.ustore_verify) {
@ -598,19 +615,21 @@ void UBTreeVerifyAllTuplesTransactionInfo(Relation rel, Page page, BlockNumber b
if (minCommittedXmax != MaxTransactionId && TransactionIdIsValid(pruneXid) &&
TransactionIdFollows(minCommittedXmax, pruneXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] min_committed_xmax is bigger than prune_xid: relName=%s, blkno=%u, prune_xid=%lu, minCommittedXmax=%lu.",
NameStr(rel->rd_rel->relname), blkno, pruneXid, minCommittedXmax)));
"[Verify UBTree] min_committed_xmax is bigger than prune_xid: prune_xid=%lu, minCommittedXmax=%lu, "
"rnode[%u,%u,%u], block %u.",
pruneXid, minCommittedXmax, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
return;
}
if (TransactionIdIsValid(maxXmax) && TransactionIdIsValid(ubtOpaque->last_delete_xid) &&
TransactionIdFollows(maxXmax, ubtOpaque->last_delete_xid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] max_xmax is bigger than last_delete_xid: relName=%s, blkno=%u, last_delete_xid on page=%lu, actual value=%lu.",
NameStr(rel->rd_rel->relname), blkno, ubtOpaque->last_delete_xid, maxXmax)));
"[Verify UBTree] max_xmax is bigger than last_delete_xid: last_delete_xid on page=%lu, actual value=%lu, "
"rnode[%u,%u,%u], block %u.",
ubtOpaque->last_delete_xid, maxXmax, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
}
}
void UBTreeVerifyRowptrDML(Relation rel, Page page, BlockNumber blkno, OffsetNumber offnum)
{
if (u_sess->attr.attr_storage.ustore_verify) {
@ -622,7 +641,6 @@ void UBTreeVerifyRowptrDML(Relation rel, Page page, BlockNumber blkno, OffsetNum
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
const char *indexName = (rel && rel->rd_rel ? RelationGetRelationName(rel) : "unknown");
Oid relOid = (rel ? rel->rd_id : InvalidOid);
UBTPageOpaqueInternal opaque = (UBTPageOpaqueInternal)PageGetSpecialPointer(page);
OffsetNumber firstPos = P_FIRSTDATAKEY(opaque);
OffsetNumber lastPos = PageGetMaxOffsetNumber(page);
@ -630,12 +648,12 @@ void UBTreeVerifyRowptrDML(Relation rel, Page page, BlockNumber blkno, OffsetNum
return;
}
ItemIdSort indexSortPtr = (ItemIdSort)palloc0(sizeof(ItemIdSortData));
UBTreeVerifyRowptr((PageHeaderData*)page, page, blkno, offnum, indexSortPtr, indexName, relOid);
UBTreeVerifyRowptr((PageHeaderData*)page, page, blkno, offnum, indexSortPtr, indexName, rel);
pfree(indexSortPtr);
UBTreeVerifyTupleKey(rel, page, blkno, offnum, firstPos, lastPos);
}
void UBTreeVerifyItems(Relation rel, BlockNumber blkno, TupleDesc desc, BTScanInsert cmpKeys, int keysz,
IndexTuple currKey, IndexTuple nextKey, UBTPageOpaqueInternal opaque)
{
@ -648,6 +666,8 @@ void UBTreeVerifyItems(Relation rel, BlockNumber blkno, TupleDesc desc, BTScanIn
char *nextkeyDesc = NULL;
Datum values[INDEX_MAX_KEYS];
bool isnull[INDEX_MAX_KEYS];
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (P_ISLEAF(opaque)) {
index_deform_tuple(currKey, RelationGetDescr(rel), values, isnull);
currkeyDesc = BuildIndexValueDescription(rel, values, isnull);
@ -655,14 +675,15 @@ void UBTreeVerifyItems(Relation rel, BlockNumber blkno, TupleDesc desc, BTScanIn
nextkeyDesc = BuildIndexValueDescription(rel, values, isnull);
}
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] nextkey >= currkey, nextkey: %s, currkey : %s, relName=%s, blkno=%u.", (nextkeyDesc ? nextkeyDesc : "(unknown)"),
(currkeyDesc ? currkeyDesc : "(unknown)"), NameStr(rel->rd_rel->relname), blkno)));
"[Verify UBTree] nextkey >= currkey, nextkey: %s, currkey : %s, rnode[%u,%u,%u], block %u.",
(nextkeyDesc ? nextkeyDesc : "(unknown)"), (currkeyDesc ? currkeyDesc : "(unknown)"),
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
}
static void UBTreeVerifyTupleKey(Relation rel, Page page, BlockNumber blkno, OffsetNumber offnum,
OffsetNumber firstPos, OffsetNumber lastPos)
{
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
CHECK_VERIFY_LEVEL(USTORE_VERIFY_COMPLETE)
UBTPageOpaqueInternal opaque = (UBTPageOpaqueInternal)PageGetSpecialPointer(page);
TupleDesc desc = RelationGetDescr(rel);
@ -681,13 +702,12 @@ static void UBTreeVerifyTupleKey(Relation rel, Page page, BlockNumber blkno, Off
}
pfree(cmpKeys);
}
static void UBTreeVerifyRowptrNonDML(Relation rel, Page page, BlockNumber blkno)
{
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
CHECK_VERIFY_LEVEL(USTORE_VERIFY_COMPLETE)
const char *indexName = (rel && rel->rd_rel ? RelationGetRelationName(rel) : "unknown");
Oid relOid = (rel ? rel->rd_id : InvalidOid);
TupleDesc desc = RelationGetDescr(rel);
int keysz = IndexRelationGetNumberOfKeyAttributes(rel);
ItemIdSortData itemidBase[MaxIndexTuplesPerPage];
@ -701,10 +721,11 @@ static void UBTreeVerifyRowptrNonDML(Relation rel, Page page, BlockNumber blkno)
}
BTScanInsert cmpKeys = UBTreeMakeScanKey(rel, NULL);
UBTreeVerifyRowptr((PageHeaderData*)page, page, blkno, firstPos, sortPtr, indexName, relOid);
UBTreeVerifyRowptr((PageHeaderData*)page, page, blkno, firstPos, sortPtr, indexName, rel);
IndexTuple currKey = (IndexTuple)PageGetItem(page, PageGetItemId(page, firstPos));
OffsetNumber nextPos = OffsetNumberNext(firstPos);
sortPtr++;
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
while (nextPos <= lastPos) {
ItemId itemid = PageGetItemId(page, nextPos);
IndexTuple nextKey = (IndexTuple)PageGetItem(page, itemid);
@ -720,15 +741,17 @@ static void UBTreeVerifyRowptrNonDML(Relation rel, Page page, BlockNumber blkno)
index_deform_tuple(nextKey, RelationGetDescr(rel), values, isnull);
nextkeyDesc = BuildIndexValueDescription(rel, values, isnull);
}
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] nextkey >= currkey, nextkey: %s, currkey : %s, indexName=%s, oid %u, blkno=%u.",
(nextkeyDesc ? nextkeyDesc : "(unknown)"), (currkeyDesc ? currkeyDesc : "(unknown)"), indexName, relOid, blkno)));
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED), errmsg(
"[Verify UBTree] nextkey >= currkey, nextkey: %s, currkey : %s, indexName=%s, "
"rnode[%u,%u,%u], block %u.",
(nextkeyDesc ? nextkeyDesc : "(unknown)"), (currkeyDesc ? currkeyDesc : "(unknown)"), indexName,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
pfree(cmpKeys);
return;
}
}
currKey = nextKey;
UBTreeVerifyRowptr((PageHeaderData*)page, page, blkno, nextPos, sortPtr, indexName, relOid);
UBTreeVerifyRowptr((PageHeaderData*)page, page, blkno, nextPos, sortPtr, indexName, rel);
nextPos = OffsetNumberNext(nextPos);
sortPtr++;
}
@ -746,10 +769,12 @@ static void UBTreeVerifyRowptrNonDML(Relation rel, Page page, BlockNumber blkno)
ItemIdSort tempPtr2 = &itemidBase[i + 1];
if (tempPtr1->end > tempPtr2->start) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] Ubtree ItemIdSort conflict: indexName=%s, oid=%u, blkno=%u, ptr1offset %u, "
"ptr1start = %u, ptr1end = %u, ptr2offset = %u, ptr2start = %u, ptr2end = %u.",
indexName, relOid, blkno, tempPtr1->offset, tempPtr1->start, tempPtr1->end,
tempPtr2->offset, tempPtr2->start, tempPtr2->end)));
"[Verify UBTree] Ubtree ItemIdSort conflict: indexName=%s, ptr1offset %u, "
"ptr1start = %u, ptr1end = %u, ptr2offset = %u, ptr2start = %u, ptr2end = %u, "
"rnode[%u,%u,%u], block %u.",
indexName, tempPtr1->offset, tempPtr1->start, tempPtr1->end,
tempPtr2->offset, tempPtr2->start, tempPtr2->end,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
pfree(cmpKeys);
return;
}
@ -757,7 +782,7 @@ static void UBTreeVerifyRowptrNonDML(Relation rel, Page page, BlockNumber blkno)
pfree(cmpKeys);
}
void UBTreeVerifyPage(Relation rel, Page page, BlockNumber blkno, OffsetNumber offnum, bool fromInsert)
{
BYPASS_VERIFY(USTORE_VERIFY_MOD_UBTREE, rel);
@ -778,43 +803,47 @@ void UBTreeVerifyPage(Relation rel, Page page, BlockNumber blkno, OffsetNumber o
}
TransactionId xidBase = ubtOpaque->xid_base;
UBTreeVerifyPageXid(rel, blkno, xidBase, ShortTransactionIdToNormal(xidBase, ((PageHeader)page)->pd_prune_xid));
UBTreeVerifyTupleTransactionInfo(rel, page, offnum, fromInsert, xidBase);
UBTreeVerifyTupleTransactionInfo(rel, blkno, page, offnum, fromInsert, xidBase);
}
static void UBTreeVerifyHeader(PageHeaderData* page, Relation rel, BlockNumber blkno, uint16 pageSize, uint16 headerSize)
{
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (pageSize != BLCKSZ || (page->pd_flags & ~PD_VALID_FLAG_BITS) != 0 || page->pd_lower < headerSize ||
page->pd_lower > page->pd_upper || page->pd_upper > page->pd_special || page->pd_special > BLCKSZ) {
const char *indexName = (rel && rel->rd_rel ? RelationGetRelationName(rel) : "unknown");
Oid relOid = (rel ? rel->rd_id : InvalidOid);
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] index page header invalid: indexName=%s, oid=%u, blkno=%u, size=%u,"
"flags=%u, lower=%u, upper=%u, special=%u.", indexName, relOid, blkno, headerSize,
page->pd_flags, page->pd_lower, page->pd_upper, page->pd_special)));
"[Verify UBTree] index page header invalid: indexName=%s, size=%u,"
"flags=%u, lower=%u, upper=%u, special=%u, rnode[%u,%u,%u], block %u.", indexName, headerSize,
page->pd_flags, page->pd_lower, page->pd_upper, page->pd_special,
rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
}
}
static void UBTreeVerifyRowptr(PageHeaderData* header, Page page, BlockNumber blkno, OffsetNumber offset,
ItemIdSort indexSortPtr, const char *indexName, Oid relOid)
ItemIdSort indexSortPtr, const char *indexName, Relation rel)
{
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
ItemId itemId = PageGetItemId(page, offset);
unsigned rpStart = ItemIdGetOffset(itemId);
Size rpLen = ItemIdGetLength(itemId);
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (!ItemIdIsUsed(itemId)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] row pointer is unused: indexName=%s, oid=%u, blkno=%u, offset=%u, "
"rowPtr startOffset=%u, rowPtr len=%lu.", indexName, relOid, blkno, offset, rpStart, rpLen)));
"[Verify UBTree] row pointer is unused: indexName=%s, "
"rowPtr startOffset=%u, rowPtr len=%lu, rnode[%u,%u,%u], block %u, offnum %u.",
indexName, rpStart, rpLen, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offset)));
return;
}
if (!ItemIdHasStorage(itemId)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] row pointer has no storage: indexName=%s, oid=%u, blkno=%u, offset=%u, "
"rowPtr startOffset=%u, rowPtr len=%lu.", indexName, relOid, blkno, offset, rpStart, rpLen)));
"[Verify UBTree] row pointer has no storage: indexName=%s, "
"rowPtr startOffset=%u, rowPtr len=%lu, rnode[%u,%u,%u], block %u, offnum %u.",
indexName, rpStart, rpLen, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offset)));
return;
}
indexSortPtr->start = rpStart;
@ -822,15 +851,17 @@ static void UBTreeVerifyRowptr(PageHeaderData* header, Page page, BlockNumber bl
indexSortPtr->offset = offset;
if (indexSortPtr->start < header->pd_upper || indexSortPtr->end > header->pd_special) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] The item corresponding to row pointer exceeds the range of item stored in the page: indexName=%s, oid=%u, "
"blkno=%u, offset=%u, rowPtr startOffset=%u, rowPtr len=%lu.", indexName, relOid, blkno, offset, rpStart, rpLen)));
"[Verify UBTree] The item corresponding to row pointer exceeds the range of item stored in the page: "
"indexName=%s, rowPtr startOffset=%u, rowPtr len=%lu, rnode[%u,%u,%u], block %u, offnum %u.",
indexName, rpStart, rpLen, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offset)));
return;
}
int tupleSize = IndexTupleSize((IndexTuple)PageGetItem(page, itemId));
if (tupleSize > (int)rpLen) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify UBTree] tuple size is bigger than item's len: indexName=%s, oid=%u, blkno=%u, offset=%u, "
"tuple size=%d, rowPtr len=%lu.", indexName, relOid, blkno, offset, tupleSize, rpLen)));
"[Verify UBTree] tuple size is bigger than item's len: indexName=%s, "
"tuple size=%d, rowPtr len=%lu, rnode[%u,%u,%u], block %u, offnum %u.",
indexName, tupleSize, rpLen, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno, offset)));
return;
}
}

View File

@ -1222,13 +1222,12 @@ static void UBTRecycleQueueVerifyHeader(UBTRecycleQueueHeader header, Relation r
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
uint32 urqBlocks = MaxBlockNumber;
Oid relOid = InvalidOid;
bool headerError = false;
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (rel != NULL) {
RelationOpenSmgr(rel);
urqBlocks = Max(minRecycleQueueBlockNumber, smgrnblocks(rel->rd_smgr, FSM_FORKNUM));
relOid = rel->rd_id;
}
headerError = (header->flags > (URQ_HEAD_PAGE | URQ_TAIL_PAGE)) || (IsNormalOffset(header->head) && !IsNormalOffset(header->tail)) ||
@ -1238,13 +1237,14 @@ static void UBTRecycleQueueVerifyHeader(UBTRecycleQueueHeader header, Relation r
if (headerError) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify URQ] urq header is invalid : oid=%u, blkno=%u, flags=%u, head=%d, tail=%d,"
" free_items=%d, free_list_head=%d, prev_blkno=%u, next_blkno=%u", relOid, blkno, header->flags,
header->head, header->tail, header->freeItems, header->freeListHead, header->prevBlkno, header->nextBlkno)));
"[Verify URQ] urq header is invalid : flags=%u, head=%d, tail=%d, "
"free_items=%d, free_list_head=%d, prev_blkno=%u, next_blkno=%u, rnode[%u,%u,%u], block %u.",
header->flags, header->head, header->tail, header->freeItems, header->freeListHead,
header->prevBlkno, header->nextBlkno, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
}
}
void UBTRecycleQueueVerifyAllItems(UBTRecycleQueueHeader header, Oid oid, BlockNumber blkno)
static void UBTRecycleQueueVerifyAllItems(UBTRecycleQueueHeader header, Relation rel, BlockNumber blkno)
{
TransactionId maxXid = ReadNewTransactionId();
TransactionId prevXid = 0;
@ -1254,7 +1254,8 @@ void UBTRecycleQueueVerifyAllItems(UBTRecycleQueueHeader header, Oid oid, BlockN
uint16 prevOffset = InvalidOffset;
UBTRecycleQueueItem item = NULL;
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
while (IsNormalOffset(currOffset) && itemCount <= itemMaxNum) {
if (currOffset == itemMaxNum) {
break;
@ -1287,9 +1288,10 @@ void UBTRecycleQueueVerifyAllItems(UBTRecycleQueueHeader header, Oid oid, BlockN
if (itemCount + header->freeItems != itemMaxNum) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify URQ] urq items are invalid : oid %u, blkno %u, (items info : curr_item_offset = %u, "
"prev_offset = %u, item_count = %u, free_list_offset = %u, free_items = %u, next_xid = %ld)",
oid, blkno, currOffset, prevOffset, itemCount, freelistOffset, header->freeItems, maxXid)));
"[Verify URQ] urq items are invalid : (items info : curr_item_offset = %u, "
"prev_offset = %u, item_count = %u, free_list_offset = %u, free_items = %u, next_xid = %ld), "
"rnode[%u,%u,%u], block %u", currOffset, prevOffset, itemCount, freelistOffset, header->freeItems,
maxXid, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
}
}
@ -1298,10 +1300,9 @@ static void UBTRecycleQueueVerifyItem(UBTRecycleQueueHeader header, Relation rel
BYPASS_VERIFY(USTORE_VERIFY_MOD_UBTREE, rel);
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
Oid relOid = (rel ? rel->rd_id : InvalidOid);
bool itemError = false;
UBTRecycleQueueItem item = NULL;
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (offnum != InvalidOffset) {
item = &header->items[offnum];
@ -1313,25 +1314,26 @@ static void UBTRecycleQueueVerifyItem(UBTRecycleQueueHeader header, Relation rel
}
if (itemError) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify URQ] urq item is invalid: oid=%u, blkno=%u, offset=%u, "
"(item info : xid=%ld blkno=%u prev=%u next=%u)", relOid, blkno, offnum,
item->xid, item->blkno, item->prev, item->next)));
"[Verify URQ] urq item is invalid: xid=%ld, blkno=%u, prev=%u, next=%u, rnode[%u,%u,%u], block %u",
item->xid, item->blkno, item->prev, item->next, rNode.spcNode, rNode.dbNode, rNode.relNode, blkno)));
}
}
CHECK_VERIFY_LEVEL(USTORE_VERIFY_COMPLETE)
UBTRecycleQueueVerifyAllItems(header, relOid, blkno);
UBTRecycleQueueVerifyAllItems(header, rel, blkno);
}
static void UBTRecycleMetaDataVerify(UBTRecycleMeta metaData, Relation rel, BlockNumber metaBlkno)
{
BYPASS_VERIFY(USTORE_VERIFY_MOD_UBTREE, rel);
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
BlockNumber indexBlocks = (rel == NULL ? metaData->nblocksUpper : RelationGetNumberOfBlocks(rel));
uint32 urqBlocks = MaxBlockNumber;
Oid oid = InvalidOid;
bool metaError = false;
RelFileNode rNode = rel ? rel->rd_node : RelFileNode{InvalidOid, InvalidOid, InvalidOid};
if (rel != NULL) {
RelationOpenSmgr(rel);
@ -1344,9 +1346,9 @@ static void UBTRecycleMetaDataVerify(UBTRecycleMeta metaData, Relation rel, Bloc
if (metaError) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),errmsg(
"[Verify URQ] urq meta is invalid : oid=%u, meta_blkno=%u, (meta info : headBlkno = %u, tailBlkno = %u, "
"nblocksUpper = %u, nblocksLower = %u; urq_blocks = %u, index_blocks = %u)",
"[Verify URQ] urq meta is invalid : (meta info : headBlkno = %u, tailBlkno = %u, "
"nblocksUpper = %u, nblocksLower = %u; urq_blocks = %u, index_blocks = %u), rnode[%u,%u,%u], block %u",
oid, metaBlkno, metaData->headBlkno, metaData->tailBlkno, metaData->nblocksUpper,
metaData->nblocksLower, urqBlocks, indexBlocks)));
metaData->nblocksLower, urqBlocks, indexBlocks, rNode.spcNode, rNode.dbNode, rNode.relNode, metaBlkno)));
}
}

View File

@ -367,7 +367,8 @@ int UHeapPagePrune(Relation relation, const RelationBuffer *relbuf, TransactionI
END_CRIT_SECTION();
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, false, (USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_ROWS));
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, NULL, BufferGetBlockNumber(relbuf->buffer),
false, (USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_ROWS));
/*
* Report the number of tuples reclaimed to pgstats. This is ndeleted

View File

@ -722,7 +722,7 @@ reacquire_buffer:
/* Clean up */
Assert(UHEAP_XID_IS_TRANS(tuple->disk_tuple->flag));
if (u_sess->attr.attr_storage.ustore_verify_level >= USTORE_VERIFY_FAST) {
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, rel, false,
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, rel, NULL, blkno, false,
(USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_TUPLE | USTORE_VERIFY_UPAGE_ROW),
ItemPointerGetOffsetNumber(&(tuple->ctid)));
UndoRecordVerify(undorec);
@ -2316,7 +2316,7 @@ check_tup_satisfies_update:
pfree(undotup.data);
Assert(UHEAP_XID_IS_TRANS(utuple.disk_tuple->flag));
if (u_sess->attr.attr_storage.ustore_verify_level >= USTORE_VERIFY_FAST) {
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, false,
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, NULL, blkno, false,
(USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_TUPLE | USTORE_VERIFY_UPAGE_ROW), offnum);
UndoRecord *undorec = (*t_thrd.ustore_cxt.urecvec)[0];
@ -3315,13 +3315,16 @@ check_tup_satisfies_update:
Assert(UHEAP_XID_IS_TRANS(uheaptup->disk_tuple->flag));
if (u_sess->attr.attr_storage.ustore_verify_level >= USTORE_VERIFY_FAST) {
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, false,
(USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_TUPLE | USTORE_VERIFY_UPAGE_ROW), ItemPointerGetOffsetNumber(&oldtup.ctid));
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, NULL, BufferGetBlockNumber(buffer),
false, (USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_TUPLE | USTORE_VERIFY_UPAGE_ROW),
ItemPointerGetOffsetNumber(&oldtup.ctid));
if (!useInplaceUpdate) {
Page newPage = BufferGetPage(newbuf);
UpageVerify((UHeapPageHeader)newPage, InvalidXLogRecPtr, NULL, relation, false,
(USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_TUPLE | USTORE_VERIFY_UPAGE_ROW), ItemPointerGetOffsetNumber(&(uheaptup->ctid)));
UpageVerify((UHeapPageHeader)newPage, InvalidXLogRecPtr, NULL, relation, NULL,
BufferGetBlockNumber(newbuf), false,
(USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_TUPLE | USTORE_VERIFY_UPAGE_ROW),
ItemPointerGetOffsetNumber(&(uheaptup->ctid)));
}
}
@ -3653,9 +3656,10 @@ reacquire_buffer:
END_CRIT_SECTION();
if (u_sess->attr.attr_storage.ustore_verify_level >= USTORE_VERIFY_FAST) {
UpageVerifyHeader((UHeapPageHeader)page, InvalidXLogRecPtr, relation);
BlockNumber blkno = BufferGetBlockNumber(buffer);
UpageVerifyHeader((UHeapPageHeader)page, InvalidXLogRecPtr, &relation->rd_node, blkno);
for (int k = 0; k < nthispage; k++) {
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, false,
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, NULL, false,
(USTORE_VERIFY_UPAGE_TUPLE | USTORE_VERIFY_UPAGE_ROW), verifyOffnum[k]);
}
}
@ -4199,7 +4203,7 @@ bool UHeapPageFreezeTransSlots(Relation relation, Buffer buf, bool *lockReacquir
}
cleanup:
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation);
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, NULL, BufferGetBlockNumber(buf));
if (frozenSlots != NULL)
pfree(frozenSlots);
@ -5788,7 +5792,7 @@ void UHeapAbortSpeculative(Relation relation, UHeapTuple utuple)
END_CRIT_SECTION();
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation);
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relation, NULL, blkno);
UnlockReleaseBuffer(buffer);

View File

@ -297,7 +297,7 @@ void ExecuteUndoActionsPage(UndoRecPtr fromUrp, Relation rel, Buffer buffer, Tra
END_CRIT_SECTION();
}
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, rel);
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, rel, NULL, BufferGetBlockNumber(buffer));
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
}
@ -612,7 +612,8 @@ int UHeapUndoActions(URecVector *urecvec, int startIdx, int endIdx, TransactionI
}
END_CRIT_SECTION();
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relationData.relation);
UpageVerify((UHeapPageHeader)page, InvalidXLogRecPtr, NULL, relationData.relation, NULL,
BufferGetBlockNumber(buffer));
UnlockReleaseBuffer(buffer);

View File

@ -29,9 +29,10 @@
#define ISNULL_BITMAP_NUMBER 2
#define HIGH_BITS_LENGTH_OF_LSN 32
static void UpageVerifyTuple(UHeapPageHeader header, OffsetNumber off, TupleDesc tupDesc, Relation rel, bool isRedo = false);
static void UpageVerifyAllRowptr(UHeapPageHeader header, Relation rel, bool isRedo = false);
static void UpageVerifyRowptr(RowPtr *rowPtr, Page page, OffsetNumber offnum, Relation rel);
static void UpageVerifyTuple(UHeapPageHeader header, OffsetNumber off, TupleDesc tupDesc, Relation rel,
RelFileNode* rNode, BlockNumber blkno, bool isRedo = false);
static void UpageVerifyAllRowptr(UHeapPageHeader header, RelFileNode* rNode, BlockNumber blkno, bool isRedo = false);
static void UpageVerifyRowptr(RowPtr *rowPtr, Page page, OffsetNumber offnum, RelFileNode* rNode, BlockNumber blkno);
template<UPageType upagetype> void UPageInit(Page page, Size pageSize, Size specialSize, uint8 tdSlots)
{
@ -702,100 +703,106 @@ static int getModule(bool isRedo)
return isRedo ? USTORE_VERIFY_MOD_REDO : USTORE_VERIFY_MOD_UPAGE;
}
void UpageVerify(UHeapPageHeader header, XLogRecPtr lastRedo, TupleDesc tupDesc, Relation rel, bool isRedo, uint8 mask, OffsetNumber num)
void UpageVerify(UHeapPageHeader header, XLogRecPtr lastRedo, TupleDesc tupDesc, Relation rel,
RelFileNode* rNode, BlockNumber blkno, bool isRedo, uint8 mask, OffsetNumber num)
{
BYPASS_VERIFY(getModule(isRedo), rel);
if (!isRedo) {
rNode = rel ? &rel->rd_node : NULL;
}
if (rNode == NULL) {
RelFileNode invalidRelFileNode = {InvalidOid, InvalidOid, InvalidOid};
rNode = &invalidRelFileNode;
}
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST);
uint8 curMask = mask & USTORE_VERIFY_UPAGE_MASK;
if ((curMask & USTORE_VERIFY_UPAGE_HEADER) > 0) {
UpageVerifyHeader(header, lastRedo, rel, isRedo);
UpageVerifyHeader(header, lastRedo, rNode, blkno, isRedo);
}
if ((curMask & USTORE_VERIFY_UPAGE_ROWS) > 0) {
UpageVerifyAllRowptr(header, rel, isRedo);
}
if ((curMask & USTORE_VERIFY_UPAGE_ROW) > 0 && num != InvalidOffsetNumber) {
RowPtr *rowptr = UPageGetRowPtr(header, num);
UpageVerifyRowptr(rowptr, (Page)header, num, rel);
if (num != InvalidOffsetNumber) {
if ((curMask & USTORE_VERIFY_UPAGE_ROW) > 0) {
RowPtr *rowptr = UPageGetRowPtr(header, num);
UpageVerifyRowptr(rowptr, (Page)header, num, rNode, blkno);
}
if ((curMask & USTORE_VERIFY_UPAGE_TUPLE) > 0) {
UpageVerifyTuple(header, num, tupDesc, rel, rNode, blkno, isRedo);
}
}
if (curMask & USTORE_VERIFY_UPAGE_TUPLE) {
if (num != InvalidOffsetNumber) {
UpageVerifyTuple(header, num, tupDesc, rel, isRedo);
} else {
CHECK_VERIFY_LEVEL(USTORE_VERIFY_COMPLETE);
if ((curMask & USTORE_VERIFY_UPAGE_ROWS) > 0) {
UpageVerifyAllRowptr(header, rNode, blkno, isRedo);
}
if ((curMask & USTORE_VERIFY_UPAGE_TUPLE) > 0) {
if (num == InvalidOffsetNumber) {
for (OffsetNumber offNum= FirstOffsetNumber; offNum <= UHeapPageGetMaxOffsetNumber((char *)header); offNum++) {
UpageVerifyTuple(header, offNum, tupDesc, rel, isRedo);
UpageVerifyTuple(header, offNum, tupDesc, rel, rNode, blkno, isRedo);
}
}
}
}
void UpageVerifyHeader(UHeapPageHeader header, XLogRecPtr lastRedo, Relation rel, bool isRedo)
void UpageVerifyHeader(UHeapPageHeader header, XLogRecPtr lastRedo, RelFileNode* rNode, BlockNumber blkno, bool isRedo)
{
if (lastRedo != InvalidXLogRecPtr && PageGetLSN(header) < lastRedo) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|HEADER] Current lsn(%X/%X) in page is smaller than last checkpoint(%X/%X)).",
(uint32)(PageGetLSN(header) >> HIGH_BITS_LENGTH_OF_LSN), (uint32)PageGetLSN(header),
(uint32)(lastRedo >> HIGH_BITS_LENGTH_OF_LSN), (uint32)lastRedo)));
errmsg("[UPAGE_VERIFY|HEADER] Current lsn(%X/%X) in page is smaller than last checkpoint(%X/%X)), "
"rnode[%u,%u,%u], block %u.", (uint32)(PageGetLSN(header) >> HIGH_BITS_LENGTH_OF_LSN),
(uint32)PageGetLSN(header), (uint32)(lastRedo >> HIGH_BITS_LENGTH_OF_LSN), (uint32)lastRedo,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno)));
}
if (unlikely(header->pd_lower < (SizeOfUHeapPageHeaderData + SizeOfUHeapTDData(header)) ||
header->pd_lower > header->pd_upper || header->pd_upper > header->pd_special ||
header->potential_freespace > BLCKSZ || header->pd_special != BLCKSZ)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|HEADER] lower = %u, upper = %u, special = %u, potential = %u.",
header->pd_lower, header->pd_upper, header->pd_special, header->potential_freespace)));
errmsg("[UPAGE_VERIFY|HEADER] lower = %u, upper = %u, special = %u, potential = %u,"
" rnode[%u,%u,%u], block %u.", header->pd_lower, header->pd_upper, header->pd_special,
header->potential_freespace, rNode->spcNode, rNode->dbNode, rNode->relNode, blkno)));
}
if (header->td_count <= 0 || header->td_count > UHEAP_MAX_TD) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|HEADER] tdcount invalid: tdcount = %u.", header->td_count)));
errmsg("[UPAGE_VERIFY|HEADER] tdcount invalid: tdcount = %u, rnode[%u,%u,%u], block %u.",
header->td_count, rNode->spcNode, rNode->dbNode, rNode->relNode, blkno)));
}
if (TransactionIdFollows(header->pd_prune_xid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|HEADER] prune_xid invalid: prune_xid = %lu, nextxid = %lu.",
header->pd_prune_xid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
errmsg("[UPAGE_VERIFY|HEADER] prune_xid invalid: prune_xid = %lu, nextxid = %lu."
" rnode[%u,%u,%u], block %u.", header->pd_prune_xid, t_thrd.xact_cxt.ShmemVariableCache->nextXid,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno)));
}
}
static void UpageVerifyTuple(UHeapPageHeader header, OffsetNumber off, TupleDesc tupDesc, Relation rel, bool isRedo)
static void UpageVerifyTuple(UHeapPageHeader header, OffsetNumber offnum, TupleDesc tupDesc, Relation rel,
RelFileNode* rNode, BlockNumber blkno, bool isRedo)
{
RowPtr *rp = NULL;
UHeapDiskTuple diskTuple = NULL;
int tdSlot = InvalidTDSlotId;
bool hasInvalidXact = false;
TransactionId tupXid = InvalidTransactionId;
UHeapTupleTransInfo td_info = {InvalidTDSlotId, InvalidTransactionId, InvalidCommandId, INVALID_UNDO_REC_PTR};
rp = UPageGetRowPtr(header, off);
rp = UPageGetRowPtr(header, offnum);
if (RowPtrIsNormal(rp)) {
diskTuple = (UHeapDiskTuple)UPageGetRowData(header, rp);
tdSlot = UHeapTupleHeaderGetTDSlot(diskTuple);
hasInvalidXact = UHeapTupleHasInvalidXact(diskTuple->flag);
tupXid = UDiskTupleGetModifiedXid(diskTuple, (Page)header);
int tup_size = 0;
tup_size = (rel == NULL) ? 0 : CalTupSize(rel, diskTuple, tupDesc);
if (tup_size > (int)RowPtrGetLen(rp) || (diskTuple->reserved != 0 &&
diskTuple->reserved != 0xFF)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|TUPLE]corrupted tuple: tupsize = %d, rpsize = %u.",
tup_size, RowPtrGetLen(rp))));
return;
}
td_info.td_slot = tdSlot;
if ((tdSlot != UHEAPTUP_SLOT_FROZEN)) {
if (tdSlot < 1 || tdSlot > header->td_count) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|TUPLE] tdSlot out of bounds, tdSlot = %d, td_count = %d.", tdSlot, header->td_count)));
errmsg("[UPAGE_VERIFY|TUPLE]tdSlot out of bounds, tdSlot = %d, td_count = %d, "
"rnode[%u,%u,%u], block %u, offnum %u.", tdSlot, header->td_count,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
@ -809,52 +816,66 @@ static void UpageVerifyTuple(UHeapPageHeader header, OffsetNumber off, TupleDesc
TransactionId xid = this_trans->xactid;
if (TransactionIdFollows(xid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|TUPLE] tdxid invalid: tdSlot = %d, tdxid = %lu, nextxid = %lu.",
tdSlot, xid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
errmsg("[UPAGE_VERIFY|TUPLE]tdxid invalid: tdSlot = %d, tdxid = %lu, nextxid = %lu, "
"rnode[%u,%u,%u], block %u, offnum %u.", tdSlot, xid, t_thrd.xact_cxt.ShmemVariableCache->nextXid,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
}
if (TransactionIdIsValid(xid) && !TransactionIdDidCommit(xid) &&
if (TransactionIdIsValid(xid) && !UHeapTransactionIdDidCommit(xid) &&
TransactionIdPrecedes(xid, g_instance.undo_cxt.globalFrozenXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|TUPLE] Transaction %lu in tdslot(%d) is smaller than global frozen xid %lu.",
xid, tdSlot, g_instance.undo_cxt.globalFrozenXid)));
errmsg("[UPAGE_VERIFY|TUPLE]tdxid %lu in tdslot(%d) is smaller than global frozen xid %lu, "
"rnode[%u,%u,%u], block %u, offnum %u.", xid, tdSlot, g_instance.undo_cxt.globalFrozenXid,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
}
}
if (!hasInvalidXact && IS_VALID_UNDO_REC_PTR(td_info.urec_add) &&
(!TransactionIdIsValid(td_info.xid) || (TransactionIdIsValid(tupXid) && !TransactionIdEquals(td_info.xid, tupXid)))) {
(!TransactionIdIsValid(td_info.xid) || (TransactionIdIsValid(tupXid) &&
!TransactionIdEquals(td_info.xid, tupXid)))) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|TUPLE] tup xid inconsistency with td: tupxid = %lu, tdxid = %lu, urp %lu.",
tupXid, td_info.xid, td_info.urec_add)));
return;
}
if (!TransactionIdIsValid(tupXid)) {
errmsg("[UPAGE_VERIFY|TUPLE] tup xid inconsistency with td: tupxid = %lu, tdxid = %lu, urp %lu, "
"rnode[%u,%u,%u], block %u, offnum %u.", tupXid, td_info.xid, td_info.urec_add,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
CHECK_VERIFY_LEVEL(USTORE_VERIFY_COMPLETE)
int tupSize = (rel == NULL) ? 0 : CalTupSize(rel, diskTuple, tupDesc);
if (tupSize > (int)RowPtrGetLen(rp) || (diskTuple->reserved != 0 &&
diskTuple->reserved != 0xFF)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|TUPLE]corrupted tuple: tupsize = %d, rpsize = %u, "
"rnode[%u,%u,%u], block %u, offnum %u.",
tupSize, RowPtrGetLen(rp), rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
if (!TransactionIdIsValid(tupXid)) {
return;
}
if (hasInvalidXact) {
if (!UHeapTransactionIdDidCommit(tupXid) && !t_thrd.xlog_cxt.InRecovery) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|TUPLE] tup xid not commit, tupxid = %lu.", tupXid)));
errmsg("[UPAGE_VERIFY|TUPLE] tup xid not commit, tupxid = %lu, "
"rnode[%u,%u,%u], block %u, offnum %u.", tupXid,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
if (TransactionIdEquals(td_info.xid, tupXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|TUPLE] td reused but xid equal td: tupxid = %lu, tdxid = %lu.",
tupXid, td_info.xid)));
errmsg("[UPAGE_VERIFY|TUPLE] td reused but xid equal td: tupxid = %lu, tdxid = %lu, "
"rnode[%u,%u,%u], block %u, offnum %u.", tupXid, td_info.xid,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
}
}
}
static void UpageVerifyRowptr(RowPtr *rowPtr, Page page, OffsetNumber offnum, Relation rel)
static void UpageVerifyRowptr(RowPtr *rowPtr, Page page, OffsetNumber offnum, RelFileNode* rNode, BlockNumber blkno)
{
BYPASS_VERIFY(USTORE_VERIFY_MOD_UPAGE, rel);
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
UHeapPageHeader phdr = (UHeapPageHeader)page;
int nline = UHeapPageGetMaxOffsetNumber(page);
UHeapDiskTuple diskTuple = (UHeapDiskTuple)UPageGetRowData(page, rowPtr);
@ -869,14 +890,17 @@ static void UpageVerifyRowptr(RowPtr *rowPtr, Page page, OffsetNumber offnum, Re
if (!RowPtrIsNormal(rowPtr)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ROWPTR] Rowptr is abnormal (flags:%d, offset %d, len %d).",
rowPtr->flags, offset, len)));
errmsg("[UPAGE_VERIFY|ROWPTR] Rowptr is abnormal (flags:%d, offset %d, len %d), "
"rnode[%u,%u,%u], block %u, offnum %u.", rowPtr->flags, offset, len, rNode->spcNode,
rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
if (tdSlot < 1 || tdSlot > phdr->td_count) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ROWPTR] Invalid tdSlot %d, td count of page is %d.", tdSlot, phdr->td_count)));
errmsg("[UPAGE_VERIFY|ROWPTR] Invalid tdSlot %d, td count of page is %d, "
"rnode[%u,%u,%u], block %u, offnum %u.",
tdSlot, phdr->td_count, rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
@ -886,17 +910,23 @@ static void UpageVerifyRowptr(RowPtr *rowPtr, Page page, OffsetNumber offnum, Re
if (UHEAP_XID_IS_LOCK(diskTuple->flag)) {
if (!TransactionIdEquals(locker, topXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ROWPTR] locker invalid: locker %lu, topxid %lu.", locker, topXid)));
errmsg("[UPAGE_VERIFY|ROWPTR] locker invalid: locker %lu, topxid %lu, "
"rnode[%u,%u,%u], block %u, offnum %u.",
locker, topXid, rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
} else if (!IS_VALID_UNDO_REC_PTR(tdUrp) || hasInvalidXact || !TransactionIdEquals(tdXid, locker) ||
!TransactionIdEquals(tdXid, topXid) || !TransactionIdEquals(tdXid, tupXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ROWPTR] Td xid invalid: tdSlot %d, tdxid %lu, topxid %lu, "
"tupxid %lu, isInvalidSlot %d.", tdSlot, tdXid, topXid, tupXid, hasInvalidXact)));
"tupxid %lu, isInvalidSlot %d, rnode[%u,%u,%u], block %u, offnum %u.",
tdSlot, tdXid, topXid, tupXid, hasInvalidXact,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum)));
return;
}
for (int i = FirstOffsetNumber; i <= nline; i++) {
CHECK_VERIFY_LEVEL(USTORE_VERIFY_COMPLETE)
for (OffsetNumber i = FirstOffsetNumber; i <= nline; i++) {
if (i == offnum) {
continue;
}
@ -908,25 +938,29 @@ static void UpageVerifyRowptr(RowPtr *rowPtr, Page page, OffsetNumber offnum, Re
if (tupOffset + tupLen > offset) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ROWPTR] Rowptr data is abnormal, flags %d, offset %u,"
" len %d, alignTupLen %u, targetRpOffset %u",
rp->flags, tupOffset, RowPtrGetLen(rp), tupLen, offset)));
" len %d, alignTupLen %u, targetRpOffset %u, "
"rnode[%u,%u,%u], block %u, offnum %u, offnum2 %u.",
rp->flags, tupOffset, RowPtrGetLen(rp), tupLen, offset,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum, i)));
}
} else if (offset + len > tupOffset) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ROWPTR] Rowptr data is abnormal, flags %d, offset %u,"
" len %d, alignTupLen %u, targetRpOffset %u, targetRpLen %u.",
rp->flags, tupOffset, RowPtrGetLen(rp), tupLen, offset, len)));
" len %d, alignTupLen %u, targetRpOffset %u, targetRpLen %u, "
"rnode[%u,%u,%u], block %u, offnum %u, offnum2 %u.",
rp->flags, tupOffset, RowPtrGetLen(rp), tupLen, offset, len,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, offnum, i)));
}
}
}
}
static void UpageVerifyAllRowptr(UHeapPageHeader header, Relation rel, bool isRedo)
static void UpageVerifyAllRowptr(UHeapPageHeader header, RelFileNode* rNode, BlockNumber blkno, bool isRedo)
{
int nline = UHeapPageGetMaxOffsetNumber((char *)header);
int tdSlot = 0;
int nstorage = 0;
int i;
OffsetNumber i;
RpSortData rowptrs[MaxPossibleUHeapTuplesPerPage];
RpSort sortPtr = rowptrs;
RowPtr *rp = NULL;
@ -936,13 +970,13 @@ static void UpageVerifyAllRowptr(UHeapPageHeader header, Relation rel, bool isRe
if (RowPtrIsNormal(rp)) {
sortPtr->start = (int)RowPtrGetOffset(rp);
sortPtr->end = sortPtr->start + (int)SHORTALIGN(RowPtrGetLen(rp));
sortPtr->offset = i;
if (sortPtr->start < header->pd_upper || sortPtr->end > header->pd_special) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ALLROWPTR]corrupted rowptr: offset = %u, rpstart = %u, "
"rplen = %u, pdlower = %u, pdupper = %u.",
i, RowPtrGetOffset(rp), RowPtrGetLen(rp), header->pd_lower, header->pd_upper)));
errmsg("[UPAGE_VERIFY|ALLROWPTR] rpstart = %u, rplen = %u, pdlower = %u, pdupper = %u, "
"rnode[%u,%u,%u], block %u, offnum %u.",
RowPtrGetOffset(rp), RowPtrGetLen(rp), header->pd_lower, header->pd_upper,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, i)));
return;
}
sortPtr++;
@ -950,22 +984,28 @@ static void UpageVerifyAllRowptr(UHeapPageHeader header, Relation rel, bool isRe
tdSlot = RowPtrGetTDSlot(rp);
if (tdSlot == UHEAPTUP_SLOT_FROZEN) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ALLROWPTR]rowptr(offsetnumber = %d) tdslot frozen, tdSlot = %d.", i, tdSlot)));
errmsg("[UPAGE_VERIFY|ALLROWPTR] tdslot frozen, tdSlot = %d, "
"rnode[%u,%u,%u], block %u, offnum %u.", tdSlot,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, i)));
return;
}
UHeapPageTDData *tdPtr = (UHeapPageTDData *)PageGetTDPointer(header);
TD * this_trans = &tdPtr->td_info[tdSlot - 1];
if (tdSlot < 1 || tdSlot > header->td_count) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ALLROWPTR]tdSlot out of bounds, tdSlot = %d, td_count = %d.", tdSlot, header->td_count)));
errmsg("[UPAGE_VERIFY|ALLROWPTR] tdSlot out of bounds, tdSlot = %d, "
"td_count = %d, rnode[%u,%u,%u], block %u, offnum %u.", tdSlot, header->td_count,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, i)));
return;
}
UHeapPageTDData *tdPtr = (UHeapPageTDData *)PageGetTDPointer(header);
TD * this_trans = &tdPtr->td_info[tdSlot - 1];
if (TransactionIdFollows(this_trans->xactid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ALLROWPTR]tdxid invalid: tdSlot %d, tdxid = %lu, nextxid = %lu.",
tdSlot, this_trans->xactid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
errmsg("[UPAGE_VERIFY|ALLROWPTR] tdxid invalid: tdSlot %d, tdxid = %lu, "
"nextxid = %lu, rnode[%u,%u,%u], block %u, offnum %u.", tdSlot, this_trans->xactid,
t_thrd.xact_cxt.ShmemVariableCache->nextXid,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno, i)));
return;
}
}
@ -985,10 +1025,11 @@ static void UpageVerifyAllRowptr(UHeapPageHeader header, Relation rel, bool isRe
RpSort temp_ptr2 = &rowptrs[i + 1];
if (temp_ptr1->end > temp_ptr2->start) {
ereport(ustore_verify_errlevel(), (errcode(ERRCODE_DATA_CORRUPTED),
errmsg("[UPAGE_VERIFY|ALLROWPTR]corrupted line pointer: rp1offset %u, rp1start = %u, rp1end = %u, "
"rp2offset = %u, rp2start = %u, rp2end = %u.",
errmsg("[UPAGE_VERIFY|ALLROWPTR]corrupted line pointer: rp1offnum %u, rp1start = %u, rp1end = %u, "
"rp2offnum = %u, rp2start = %u, rp2end = %u, rnode[%u,%u,%u], block %u.",
temp_ptr1->offset, temp_ptr1->start, temp_ptr1->end,
temp_ptr2->offset, temp_ptr2->start, temp_ptr2->end)));
temp_ptr2->offset, temp_ptr2->start, temp_ptr2->end,
rNode->spcNode, rNode->dbNode, rNode->relNode, blkno)));
return;
}
}

View File

@ -281,7 +281,7 @@ void UHeapXlogInsert(XLogReaderState *record)
Page page = BufferGetPage(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, &targetNode, blkno, true);
}
if (BufferIsValid(buffer.buf)) {
@ -476,7 +476,7 @@ static void UHeapXlogDelete(XLogReaderState *record)
Page page = BufferGetPage(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, &targetNode, blkno, true);
}
if (BufferIsValid(buffer.buf)) {
@ -537,7 +537,7 @@ static void UHeapXlogFreezeTdSlot(XLogReaderState *record)
MarkBufferDirty(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, &rnode, blkno, true);
}
if (BufferIsValid(buffer.buf)) {
@ -582,7 +582,7 @@ static void UHeapXlogInvalidTdSlot(XLogReaderState *record)
PageSetLSN(page, lsn);
MarkBufferDirty(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, NULL, blkno, true);
}
if (BufferIsValid(buffer.buf)) {
@ -731,7 +731,7 @@ static void UHeapXlogClean(XLogReaderState *record)
Page page = BufferGetPage(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, &rnode, blkno, true);
}
if (BufferIsValid(buffer.buf)) {
@ -1318,7 +1318,7 @@ static void UHeapXlogUpdate(XLogReaderState *record)
Page page = BufferGetPage(buffers.newbuffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, &rnode, BufferGetBlockNumber(buffers.newbuffer.buf), true);
}
if (BufferIsValid(buffers.newbuffer.buf) && buffers.newbuffer.buf != buffers.oldbuffer.buf) {
@ -1645,7 +1645,7 @@ static void UHeapXlogMultiInsert(XLogReaderState *record)
Page page = BufferGetPage(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, &rnode, blkno, true);
}
pfree(ufreeOffsetRanges);
@ -1674,7 +1674,7 @@ static void UHeapXlogBaseShift(XLogReaderState *record)
MarkBufferDirty(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, NULL, blkno, true);
}
if (BufferIsValid(buffer.buf)) {
@ -1744,7 +1744,7 @@ static void UHeapXlogExtendTDSlot(XLogReaderState *record)
MarkBufferDirty(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, NULL, blkno, true);
}
if (BufferIsValid(buffer.buf)) {
@ -1821,7 +1821,7 @@ static void UHeapXlogFreeze(XLogReaderState *record)
MarkBufferDirty(buffer.buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, &rnode, blkno, true);
}
if (BufferIsValid(buffer.buf)) {
UnlockReleaseBuffer(buffer.buf);
@ -1997,7 +1997,7 @@ static void UHeapUndoXlogPage(XLogReaderState *record)
MarkBufferDirty(buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, NULL, blkno, true);
}
if (BufferIsValid(buf))
@ -2022,7 +2022,7 @@ static void UHeapUndoXlogResetXid(XLogReaderState *record)
Page page = BufferGetPage(buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, NULL, blkno, true);
}
if (BufferIsValid(buf))
@ -2087,7 +2087,7 @@ static void UHeapUndoXlogAbortSpecinsert(XLogReaderState *record)
Page page = BufferGetPage(buf);
UpageVerify((UHeapPageHeader)page, t_thrd.shemem_ptr_cxt.XLogCtl->RedoRecPtr, NULL,
NULL, true);
NULL, NULL, blkno, true);
}
if (BufferIsValid(buf))

View File

@ -632,22 +632,22 @@ void UndoRecordVerify(_in_ UndoRecord *urec)
{
UNDO_BYPASS_VERIFY;
CHECK_VERIFY_LEVEL(USTORE_VERIFY_DEFAULT)
CHECK_VERIFY_LEVEL(USTORE_VERIFY_FAST)
if (!TransactionIdIsValid(urec->Xid())) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. xid %lu is invalid"), urec->Xid())));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. xid %lu is invalid, urp %lu"), urec->Xid(), urec->Urp())));
}
if (TransactionIdIsValid(urec->Xid()) &&
TransactionIdFollowsOrEquals(urec->Xid(), t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. xid %lu >= nextXid %lu"),
urec->Xid(), t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. xid %lu >= nextXid %lu, urp %lu"),
urec->Xid(), t_thrd.xact_cxt.ShmemVariableCache->nextXid, urec->Urp())));
}
if (TransactionIdIsValid(urec->OldXactId()) &&
TransactionIdFollowsOrEquals(urec->OldXactId(), t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. oldXactId %lu >= nextXid %lu"),
urec->OldXactId(), t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. oldXactId %lu >= nextXid %lu, urp %lu"),
urec->OldXactId(), t_thrd.xact_cxt.ShmemVariableCache->nextXid, urec->Urp())));
}
if (!(IS_VALID_UNDO_REC_PTR(urec->Urp()))) {
ereport(WARNING, (errmodule(MOD_UNDO),
@ -655,6 +655,7 @@ void UndoRecordVerify(_in_ UndoRecord *urec)
return;
}
CHECK_VERIFY_LEVEL(USTORE_VERIFY_COMPLETE)
int zoneId = (int)UNDO_PTR_GET_ZONE_ID(urec->Urp());
undo::UndoZone *uzone = undo::UndoZoneGroup::GetUndoZone(zoneId, false);
Assert(uzone != NULL);
@ -673,37 +674,39 @@ void UndoRecordVerify(_in_ UndoRecord *urec)
undo::UndoZone *blkPrevZone = undo::UndoZoneGroup::GetUndoZone(blkPrevZid, false);
if (urec->Blkprev() > blkPrevZone->GetInsertURecPtr()) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. Blkprev %lu > insertURecPtr %lu, zoneId %d"),
urec->Blkprev(), uzone->GetInsertURecPtr(), zoneId)));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. Blkprev %lu > insertURecPtr %lu, zoneId %d, urp %lu"),
urec->Blkprev(), uzone->GetInsertURecPtr(), zoneId, urec->Urp())));
}
}
if ((urec->Uinfo() & UNDO_UREC_INFO_TRANSAC) != 0 || (urec->Uinfo() & UNDO_UREC_INFO_BLOCK) != 0) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. uinfo %d error"), (int)urec->Uinfo())));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. uinfo %d error, urp %lu"),
(int)urec->Uinfo(), urec->Urp())));
}
if ((urec->Uinfo() & UNDO_UREC_INFO_OLDTD) != 0 && !TransactionIdIsValid(urec->OldXactId())) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. uinfo %d, oldXactId %lu is invalid"),
(int)urec->Uinfo(), urec->OldXactId())));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. uinfo %d, oldXactId %lu is invalid, urp %lu"),
(int)urec->Uinfo(), urec->OldXactId(), urec->Urp())));
}
if ((urec->Uinfo() & UNDO_UREC_INFO_HAS_PARTOID) != 0 && urec->Partitionoid() == InvalidOid) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. urp %lu, uinfo %d, partitionoid is invalid"),
urec->Urp(), (int)urec->Uinfo())));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. uinfo %d, partitionoid is invalid, urp %lu"),
(int)urec->Uinfo(), urec->Urp())));
}
if ((urec->Uinfo() & UNDO_UREC_INFO_HAS_TABLESPACEOID) != 0 && urec->Tablespace() == InvalidOid) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. urp %lu, uinfo %d, tablespace is invalid"),
urec->Urp(), (int)urec->Uinfo())));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. uinfo %d, tablespace is invalid, urp %lu"),
(int)urec->Uinfo(), urec->Urp())));
}
if (urec->Utype() <= UNDO_UNKNOWN || urec->Utype() > UNDO_UPDATE) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. utype %d is invalid"), urec->Utype())));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. utype %d is invalid, urp %lu"),
urec->Utype(), urec->Urp())));
}
if ((urec->Utype() == UNDO_INSERT && urec->PayLoadLen() != 0) ||
(urec->Utype() == UNDO_INSERT && (urec->Uinfo() & UNDO_UREC_INFO_PAYLOAD) != 0)) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. utype %d , payLoadLen %hu, uinfo %d"),
urec->Utype(), urec->PayLoadLen(), (int)urec->Uinfo())));
errmsg(UNDOFORMAT("[UNDO_RECORD_VERIFY]failed. utype %d , payLoadLen %hu, uinfo %d, urp %lu"),
urec->Utype(), urec->PayLoadLen(), (int)urec->Uinfo(), urec->Urp())));
}
}

View File

@ -345,7 +345,7 @@ static void verifyXid(TransactionSlot *slot)
if (TransactionIdIsValid(xid) &&
TransactionIdFollowsOrEquals(xid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)) {
ereport(WARNING, (errmodule(MOD_UNDO),
errmsg(UNDOFORMAT("[VERIFY_UNDO_TRANSLOT]failed. slot xactId %lu >= nextXid%lu"),
errmsg(UNDOFORMAT("[VERIFY_UNDO_TRANSLOT]failed. slot xactId %lu >= nextXid %lu"),
xid, t_thrd.xact_cxt.ShmemVariableCache->nextXid)));
}
}

View File

@ -349,10 +349,11 @@ inline OffsetNumber UHeapPageGetMaxOffsetNumber(char *upage)
#define USTORE_VERIFY_UPAGE_DEFAULT (USTORE_VERIFY_UPAGE_HEADER | USTORE_VERIFY_UPAGE_TUPLE | USTORE_VERIFY_UPAGE_ROWS)
void UpageVerify(UHeapPageHeader header, XLogRecPtr lastRedo, TupleDesc tupDesc, Relation rel,
bool isRedo = false, uint8 mask = USTORE_VERIFY_UPAGE_DEFAULT,
OffsetNumber num = InvalidOffsetNumber /* for single TUPLE and ROW */);
void UpageVerify(UHeapPageHeader header, XLogRecPtr lastRedo, TupleDesc tupDesc, Relation rel,
RelFileNode* rNode, BlockNumber blkno, bool isRedo = false, uint8 mask = USTORE_VERIFY_UPAGE_DEFAULT,
OffsetNumber num = InvalidOffsetNumber);
void UpageVerifyHeader(UHeapPageHeader header, XLogRecPtr lastRedo, Relation rel, bool isRedo = false);
void UpageVerifyHeader(UHeapPageHeader header, XLogRecPtr lastRedo, RelFileNode* rNode,
BlockNumber blkno, bool isRedo = false);
#endif