mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
amcheck: Remove duplicate XID/MXID bounds checks.
Commit 3b6c1259f9ca8e21860aaf24ec6735a8e5598ea0 resulted in the same xmin and xmax bounds checking being performed in both check_tuple() and check_tuple_visibility(). Remove the duplication. While at it, adjust some code comments that were overlooked in that commit. Mark Dilger Discussion: http://postgr.es/m/AC5479E4-6321-473D-AC92-5EC36299FBC2@enterprisedb.com
This commit is contained in:
parent
3c3b8a4b26
commit
4573f6a9af
@ -1390,136 +1390,18 @@ check_tuple_attribute(HeapCheckContext *ctx)
|
|||||||
static void
|
static void
|
||||||
check_tuple(HeapCheckContext *ctx)
|
check_tuple(HeapCheckContext *ctx)
|
||||||
{
|
{
|
||||||
TransactionId xmin;
|
|
||||||
TransactionId xmax;
|
|
||||||
bool fatal = false;
|
|
||||||
uint16 infomask = ctx->tuphdr->t_infomask;
|
|
||||||
|
|
||||||
/* If xmin is normal, it should be within valid range */
|
|
||||||
xmin = HeapTupleHeaderGetXmin(ctx->tuphdr);
|
|
||||||
switch (get_xid_status(xmin, ctx, NULL))
|
|
||||||
{
|
|
||||||
case XID_INVALID:
|
|
||||||
case XID_BOUNDS_OK:
|
|
||||||
break;
|
|
||||||
case XID_IN_FUTURE:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("xmin %u equals or exceeds next valid transaction ID %u:%u",
|
|
||||||
xmin,
|
|
||||||
EpochFromFullTransactionId(ctx->next_fxid),
|
|
||||||
XidFromFullTransactionId(ctx->next_fxid)));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
case XID_PRECEDES_CLUSTERMIN:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("xmin %u precedes oldest valid transaction ID %u:%u",
|
|
||||||
xmin,
|
|
||||||
EpochFromFullTransactionId(ctx->oldest_fxid),
|
|
||||||
XidFromFullTransactionId(ctx->oldest_fxid)));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
case XID_PRECEDES_RELMIN:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("xmin %u precedes relation freeze threshold %u:%u",
|
|
||||||
xmin,
|
|
||||||
EpochFromFullTransactionId(ctx->relfrozenfxid),
|
|
||||||
XidFromFullTransactionId(ctx->relfrozenfxid)));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmax = HeapTupleHeaderGetRawXmax(ctx->tuphdr);
|
|
||||||
|
|
||||||
if (infomask & HEAP_XMAX_IS_MULTI)
|
|
||||||
{
|
|
||||||
/* xmax is a multixact, so it should be within valid MXID range */
|
|
||||||
switch (check_mxid_valid_in_rel(xmax, ctx))
|
|
||||||
{
|
|
||||||
case XID_INVALID:
|
|
||||||
report_corruption(ctx,
|
|
||||||
pstrdup("multitransaction ID is invalid"));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
case XID_PRECEDES_RELMIN:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("multitransaction ID %u precedes relation minimum multitransaction ID threshold %u",
|
|
||||||
xmax, ctx->relminmxid));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
case XID_PRECEDES_CLUSTERMIN:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("multitransaction ID %u precedes oldest valid multitransaction ID threshold %u",
|
|
||||||
xmax, ctx->oldest_mxact));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
case XID_IN_FUTURE:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("multitransaction ID %u equals or exceeds next valid multitransaction ID %u",
|
|
||||||
xmax,
|
|
||||||
ctx->next_mxact));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
case XID_BOUNDS_OK:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* xmax is not a multixact and is normal, so it should be within the
|
|
||||||
* valid XID range.
|
|
||||||
*/
|
|
||||||
switch (get_xid_status(xmax, ctx, NULL))
|
|
||||||
{
|
|
||||||
case XID_INVALID:
|
|
||||||
case XID_BOUNDS_OK:
|
|
||||||
break;
|
|
||||||
case XID_IN_FUTURE:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("xmax %u equals or exceeds next valid transaction ID %u:%u",
|
|
||||||
xmax,
|
|
||||||
EpochFromFullTransactionId(ctx->next_fxid),
|
|
||||||
XidFromFullTransactionId(ctx->next_fxid)));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
case XID_PRECEDES_CLUSTERMIN:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("xmax %u precedes oldest valid transaction ID %u:%u",
|
|
||||||
xmax,
|
|
||||||
EpochFromFullTransactionId(ctx->oldest_fxid),
|
|
||||||
XidFromFullTransactionId(ctx->oldest_fxid)));
|
|
||||||
fatal = true;
|
|
||||||
break;
|
|
||||||
case XID_PRECEDES_RELMIN:
|
|
||||||
report_corruption(ctx,
|
|
||||||
psprintf("xmax %u precedes relation freeze threshold %u:%u",
|
|
||||||
xmax,
|
|
||||||
EpochFromFullTransactionId(ctx->relfrozenfxid),
|
|
||||||
XidFromFullTransactionId(ctx->relfrozenfxid)));
|
|
||||||
fatal = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cannot process tuple data if tuple header was corrupt, as the offsets
|
* Check various forms of tuple header corruption, and if the header is too
|
||||||
* within the page cannot be trusted, leaving too much risk of reading
|
* corrupt, do not continue with other checks.
|
||||||
* garbage if we continue.
|
|
||||||
*
|
|
||||||
* We also cannot process the tuple if the xmin or xmax were invalid
|
|
||||||
* relative to relfrozenxid or relminmxid, as clog entries for the xids
|
|
||||||
* may already be gone.
|
|
||||||
*/
|
|
||||||
if (fatal)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check various forms of tuple header corruption. If the header is too
|
|
||||||
* corrupt to continue checking, or if the tuple is not visible to anyone,
|
|
||||||
* we cannot continue with other checks.
|
|
||||||
*/
|
*/
|
||||||
if (!check_tuple_header(ctx))
|
if (!check_tuple_header(ctx))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check tuple visibility. If the inserting transaction aborted, we
|
||||||
|
* cannot assume our relation description matches the tuple structure, and
|
||||||
|
* therefore cannot check it.
|
||||||
|
*/
|
||||||
if (!check_tuple_visibility(ctx))
|
if (!check_tuple_visibility(ctx))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user