amcheck: Remove duplicate XID/MXID bounds checks.
authorRobert Haas <rhaas@postgresql.org>
Wed, 7 Apr 2021 16:11:44 +0000 (12:11 -0400)
committerRobert Haas <rhaas@postgresql.org>
Wed, 7 Apr 2021 16:11:44 +0000 (12:11 -0400)
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

contrib/amcheck/verify_heapam.c

index 11ace483d04088802aa4af806d5963025b1ec533..1d769035f1349e127b91caf23584d7077464b3f6 100644 (file)
@@ -1390,136 +1390,18 @@ check_tuple_attribute(HeapCheckContext *ctx)
 static void
 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
-    * within the page cannot be trusted, leaving too much risk of reading
-    * 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.
+    * Check various forms of tuple header corruption, and if the header is too
+    * corrupt, do not continue with other checks.
     */
-   if (fatal)
+   if (!check_tuple_header(ctx))
        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.
+    * 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_header(ctx))
-       return;
-
    if (!check_tuple_visibility(ctx))
        return;