@@ -818,6 +818,9 @@ main(int argc, char *argv[])
818
818
* names matching the expectations of verify_heap_slot_handler, which will
819
819
* receive and handle each row returned from the verify_heapam() function.
820
820
*
821
+ * The constructed SQL command will silently skip temporary tables, as checking
822
+ * them would needlessly draw errors from the underlying amcheck function.
823
+ *
821
824
* sql: buffer into which the heap table checking command will be written
822
825
* rel: relation information for the heap table to be checked
823
826
* conn: the connection to be used, for string escaping purposes
@@ -827,10 +830,10 @@ prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
827
830
{
828
831
resetPQExpBuffer (sql );
829
832
appendPQExpBuffer (sql ,
830
- "SELECT blkno, offnum, attnum, msg FROM %s.verify_heapam("
831
- "\nrelation := %u, on_error_stop := %s, check_toast := %s, skip := '%s'" ,
833
+ "SELECT v.blkno, v.offnum, v.attnum, v.msg "
834
+ "FROM pg_catalog.pg_class c, %s.verify_heapam("
835
+ "\nrelation := c.oid, on_error_stop := %s, check_toast := %s, skip := '%s'" ,
832
836
rel -> datinfo -> amcheck_schema ,
833
- rel -> reloid ,
834
837
opts .on_error_stop ? "true" : "false" ,
835
838
opts .reconcile_toast ? "true" : "false" ,
836
839
opts .skip );
@@ -840,7 +843,10 @@ prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
840
843
if (opts .endblock >= 0 )
841
844
appendPQExpBuffer (sql , ", endblock := " INT64_FORMAT , opts .endblock );
842
845
843
- appendPQExpBufferChar (sql , ')' );
846
+ appendPQExpBuffer (sql ,
847
+ "\n) v WHERE c.oid = %u "
848
+ "AND c.relpersistence != 't'" ,
849
+ rel -> reloid );
844
850
}
845
851
846
852
/*
@@ -851,6 +857,10 @@ prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
851
857
* functions do not return any, but rather return corruption information by
852
858
* raising errors, which verify_btree_slot_handler expects.
853
859
*
860
+ * The constructed SQL command will silently skip temporary indexes, and
861
+ * indexes being reindexed concurrently, as checking them would needlessly draw
862
+ * errors from the underlying amcheck functions.
863
+ *
854
864
* sql: buffer into which the heap table checking command will be written
855
865
* rel: relation information for the index to be checked
856
866
* conn: the connection to be used, for string escaping purposes
@@ -860,27 +870,31 @@ prepare_btree_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
860
870
{
861
871
resetPQExpBuffer (sql );
862
872
863
- /*
864
- * Embed the database, schema, and relation name in the query, so if the
865
- * check throws an error, the user knows which relation the error came
866
- * from.
867
- */
868
873
if (opts .parent_check )
869
874
appendPQExpBuffer (sql ,
870
- "SELECT * FROM %s.bt_index_parent_check("
871
- "index := '%u'::regclass, heapallindexed := %s, "
872
- "rootdescend := %s)" ,
875
+ "SELECT %s.bt_index_parent_check("
876
+ "index := c.oid, heapallindexed := %s, rootdescend := %s)"
877
+ "\nFROM pg_catalog.pg_class c, pg_catalog.pg_index i "
878
+ "WHERE c.oid = %u "
879
+ "AND c.oid = i.indexrelid "
880
+ "AND c.relpersistence != 't' "
881
+ "AND i.indisready AND i.indisvalid AND i.indislive" ,
873
882
rel -> datinfo -> amcheck_schema ,
874
- rel -> reloid ,
875
883
(opts .heapallindexed ? "true" : "false" ),
876
- (opts .rootdescend ? "true" : "false" ));
884
+ (opts .rootdescend ? "true" : "false" ),
885
+ rel -> reloid );
877
886
else
878
887
appendPQExpBuffer (sql ,
879
- "SELECT * FROM %s.bt_index_check("
880
- "index := '%u'::regclass, heapallindexed := %s)" ,
888
+ "SELECT %s.bt_index_check("
889
+ "index := c.oid, heapallindexed := %s)"
890
+ "\nFROM pg_catalog.pg_class c, pg_catalog.pg_index i "
891
+ "WHERE c.oid = %u "
892
+ "AND c.oid = i.indexrelid "
893
+ "AND c.relpersistence != 't' "
894
+ "AND i.indisready AND i.indisvalid AND i.indislive" ,
881
895
rel -> datinfo -> amcheck_schema ,
882
- rel -> reloid ,
883
- ( opts . heapallindexed ? "true" : "false" ) );
896
+ ( opts . heapallindexed ? "true" : "false" ) ,
897
+ rel -> reloid );
884
898
}
885
899
886
900
/*
@@ -1088,15 +1102,17 @@ verify_btree_slot_handler(PGresult *res, PGconn *conn, void *context)
1088
1102
1089
1103
if (PQresultStatus (res ) == PGRES_TUPLES_OK )
1090
1104
{
1091
- int ntups = PQntuples (res );
1105
+ int ntups = PQntuples (res );
1092
1106
1093
- if (ntups != 1 )
1107
+ if (ntups > 1 )
1094
1108
{
1095
1109
/*
1096
1110
* We expect the btree checking functions to return one void row
1097
- * each, so we should output some sort of warning if we get
1098
- * anything else, not because it indicates corruption, but because
1099
- * it suggests a mismatch between amcheck and pg_amcheck versions.
1111
+ * each, or zero rows if the check was skipped due to the object
1112
+ * being in the wrong state to be checked, so we should output some
1113
+ * sort of warning if we get anything more, not because it
1114
+ * indicates corruption, but because it suggests a mismatch between
1115
+ * amcheck and pg_amcheck versions.
1100
1116
*
1101
1117
* In conjunction with --progress, anything written to stderr at
1102
1118
* this time would present strangely to the user without an extra
@@ -1896,10 +1912,16 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
1896
1912
"\nAND (c.relam = %u OR NOT ep.btree_only OR ep.rel_regex IS NULL)" ,
1897
1913
HEAP_TABLE_AM_OID , BTREE_AM_OID );
1898
1914
1915
+ /*
1916
+ * Exclude temporary tables and indexes, which must necessarily belong to
1917
+ * other sessions. (We don't create any ourselves.) We must ultimately
1918
+ * exclude indexes marked invalid or not ready, but we delay that decision
1919
+ * until firing off the amcheck command, as the state of an index may
1920
+ * change by then.
1921
+ */
1922
+ appendPQExpBufferStr (& sql , "\nWHERE c.relpersistence != 't'" );
1899
1923
if (opts .excludetbl || opts .excludeidx || opts .excludensp )
1900
- appendPQExpBufferStr (& sql , "\nWHERE ep.pattern_id IS NULL" );
1901
- else
1902
- appendPQExpBufferStr (& sql , "\nWHERE true" );
1924
+ appendPQExpBufferStr (& sql , "\nAND ep.pattern_id IS NULL" );
1903
1925
1904
1926
/*
1905
1927
* We need to be careful not to break the --no-dependent-toast and
@@ -1951,7 +1973,8 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
1951
1973
"\nON ('pg_toast' ~ ep.nsp_regex OR ep.nsp_regex IS NULL)"
1952
1974
"\nAND (t.relname ~ ep.rel_regex OR ep.rel_regex IS NULL)"
1953
1975
"\nAND ep.heap_only"
1954
- "\nWHERE ep.pattern_id IS NULL" );
1976
+ "\nWHERE ep.pattern_id IS NULL"
1977
+ "\nAND t.relpersistence != 't'" );
1955
1978
appendPQExpBufferStr (& sql ,
1956
1979
"\n)" );
1957
1980
}
@@ -1969,7 +1992,8 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
1969
1992
"\nINNER JOIN pg_catalog.pg_index i "
1970
1993
"ON r.oid = i.indrelid "
1971
1994
"INNER JOIN pg_catalog.pg_class c "
1972
- "ON i.indexrelid = c.oid" );
1995
+ "ON i.indexrelid = c.oid "
1996
+ "AND c.relpersistence != 't'" );
1973
1997
if (opts .excludeidx || opts .excludensp )
1974
1998
appendPQExpBufferStr (& sql ,
1975
1999
"\nINNER JOIN pg_catalog.pg_namespace n "
@@ -2007,7 +2031,8 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
2007
2031
"INNER JOIN pg_catalog.pg_index i "
2008
2032
"ON t.oid = i.indrelid"
2009
2033
"\nINNER JOIN pg_catalog.pg_class c "
2010
- "ON i.indexrelid = c.oid" );
2034
+ "ON i.indexrelid = c.oid "
2035
+ "AND c.relpersistence != 't'" );
2011
2036
if (opts .excludeidx )
2012
2037
appendPQExpBufferStr (& sql ,
2013
2038
"\nLEFT OUTER JOIN exclude_pat ep "
0 commit comments