Running pgstatindex on some !indisready indexes fails with "ERROR: XX001: could not read block 0 in file". This reproduces it:
begin; drop table if exists not_indisready_t; create table not_indisready_t (c int); insert into not_indisready_t values (1),(1); commit; create unique index concurrently not_indisready_i on not_indisready_t(c); begin; create extension pgstattuple; \set VERBOSITY verbose select * from pgstatindex('not_indisready_i'); \set VERBOSITY default rollback; Since XX001 = ERRCODE_DATA_CORRUPTED appears in the "can't-happen" class, it's not a good fit for this scenario. I propose to have pgstatindex fail early on !indisready indexes. We could go a step further and also fail on indisready&&!indisvalid indexes, which are complete enough to accept inserts but not complete enough to answer queries. I don't see a reason to do that, but maybe someone else will. This made me wonder about functions handling unlogged rels during recovery. I used the attached hack to test most regclass-arg functions. While some of these errors from src/test/recovery/tmp_check/log/001_stream_rep_standby_2.log may deserve improvement, there were no class-XX messages: 2023-10-01 12:24:05.992 PDT [646914:11] 001_stream_rep.pl ERROR: 58P01: could not open file "base/5/16862": No such file or directory 2023-10-01 12:24:05.996 PDT [646914:118] 001_stream_rep.pl ERROR: 22023: fork "main" does not exist for this relation Thanks, nm
Author: Noah Misch <n...@leadboat.com> Commit: Noah Misch <n...@leadboat.com> diff --git a/src/test/recovery/Makefile b/src/test/recovery/Makefile index c60314d..ad54859 100644 --- a/src/test/recovery/Makefile +++ b/src/test/recovery/Makefile @@ -10,6 +10,14 @@ #------------------------------------------------------------------------- EXTRA_INSTALL=contrib/pg_prewarm contrib/pg_stat_statements contrib/test_decoding +EXTRA_INSTALL += \ + contrib/pg_visibility \ + contrib/amcheck \ + contrib/pgstattuple \ + contrib/btree_gin \ + contrib/pg_surgery \ + contrib/pg_freespacemap \ + contrib/pgrowlocks subdir = src/test/recovery top_builddir = ../../.. diff --git a/src/test/recovery/t/001_stream_rep.pl b/src/test/recovery/t/001_stream_rep.pl index 0c72ba0..e441cb2 100644 --- a/src/test/recovery/t/001_stream_rep.pl +++ b/src/test/recovery/t/001_stream_rep.pl @@ -45,6 +45,24 @@ $node_standby_2->start; # Create some content on primary and check its presence in standby nodes $node_primary->safe_psql('postgres', "CREATE TABLE tab_int AS SELECT generate_series(1,1002) AS a"); +$node_primary->safe_psql('postgres', " +create extension pg_visibility; +create extension amcheck; +create extension pgstattuple; +create extension btree_gin; +create extension pg_surgery; +create extension pg_prewarm; +create extension pg_freespacemap; +create extension pgrowlocks; + +create unlogged sequence useq; +create unlogged table u (c text); +insert into u values ('foo'); +create index ubtree on u (c); +create index ugin on u using gin (c); +create index uhash on u using hash (c); +create index ubrin on u using brin (c); +"); # Wait for standbys to catch up $node_primary->wait_for_replay_catchup($node_standby_1); @@ -60,6 +78,88 @@ $result = print "standby 2: $result\n"; is($result, qq(1002), 'check streamed content on standby 2'); +# Call regclass-arg functions on unlogged objects. Function list from: +# +# DO $$ +# DECLARE +# extname text; +# BEGIN +# FOR extname in SELECT name from pg_available_extensions LOOP +# EXECUTE format('CREATE EXTENSION IF NOT EXISTS %I CASCADE', extname); +# END LOOP; +# END +# $$; +# select oid::regprocedure from pg_proc +# where proargtypes::oid[] @> array['regclass'::regtype::oid] +# order by oid::regprocedure::text; +# +# Removed pageinspect functions, since the superuser might choose to run them +# in cases we wouldn't expect. Added pgrowlocks(text). +$node_standby_2->psql('postgres', <<'EOSQL', on_error_stop => 0); +\set utable '''u''::regclass' +\set VERBOSITY verbose +SET log_error_verbosity = verbose; +SET log_min_messages = debug1; -- for amcheck +SET client_min_messages = debug1; + +SELECT * FROM pgrowlocks(:utable::text); +SELECT brin_desummarize_range('ubrin',1); +SELECT brin_summarize_new_values('ubrin'); +SELECT brin_summarize_range('ubrin',1); +SELECT bt_index_check('ubtree'); +SELECT bt_index_check('ubtree',true); +SELECT bt_index_parent_check('ubtree'); +SELECT bt_index_parent_check('ubtree',true); +SELECT bt_index_parent_check('ubtree',true,true); +SELECT gin_clean_pending_list('ugin'); +SELECT heap_force_freeze(:utable,array['(0,1)'::tid]); +SELECT heap_force_kill(:utable,array['(0,1)'::tid]); +SELECT nextval('useq'); +SELECT currval('useq'); +SELECT pg_check_frozen(:utable); +SELECT pg_check_visible(:utable); +SELECT pg_column_is_updatable(:utable,'1',true); +--SELECT pg_extension_config_dump(:utable,'select 1'); +SELECT pg_freespace(:utable); +SELECT pg_freespace(:utable,1); +SELECT pg_get_replica_identity_index(:utable); +SELECT pg_index_column_has_property(:utable,1,'asc'); +SELECT pg_indexes_size(:utable); +SELECT pg_index_has_property('ubrin','asc'); +--SELECT pg_nextoid(:utable,name,:utable); +SELECT pg_partition_ancestors(:utable); +SELECT pg_partition_root(:utable); +SELECT pg_partition_tree(:utable); +SELECT pg_prewarm(:utable); +SELECT pg_relation_filenode(:utable); +SELECT pg_relation_filepath(:utable); +SELECT pg_relation_is_publishable(:utable); +SELECT pg_relation_is_updatable(:utable,true); +SELECT pg_relation_size(:utable); +SELECT pg_relation_size(:utable,'main'); +SELECT pg_relpages(:utable); +SELECT pg_sequence_last_value('useq'); +SELECT pgstatginindex('ugin'); +SELECT pgstathashindex('uhash'); +SELECT pgstatindex('ubtree'); +SELECT pgstattuple_approx(:utable); +SELECT pgstattuple(:utable); +SELECT pg_table_size(:utable); +SELECT pg_total_relation_size(:utable); +SELECT pg_truncate_visibility_map(:utable); +SELECT pg_visibility_map(:utable); +SELECT pg_visibility_map(:utable,1); +SELECT pg_visibility_map_summary(:utable); +SELECT pg_visibility(:utable); +SELECT pg_visibility(:utable,1); +SELECT setval('useq',1); +SELECT setval('useq',1,true); +SELECT table_to_xml_and_xmlschema(:utable,true,true,'nsp'); +SELECT table_to_xml(:utable,true,true,'nsp'); +SELECT table_to_xmlschema(:utable,true,true,'nsp'); +SELECT verify_heapam(:utable); +EOSQL + # Likewise, but for a sequence $node_primary->safe_psql('postgres', "CREATE SEQUENCE seq1; SELECT nextval('seq1')");