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