!6067 upage ubtree校验增加打印rnode block offset信息
Merge pull request !6067 from 徐达标/0817
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)));
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user