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')");

Reply via email to