Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qn2X8-009kdx-PQ for pgsql-hackers@arkaria.postgresql.org; Sun, 01 Oct 2023 19:55:19 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1qn2X6-00EZGS-OW for pgsql-hackers@arkaria.postgresql.org; Sun, 01 Oct 2023 19:55:16 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qn2X6-00EZGB-36 for pgsql-hackers@lists.postgresql.org; Sun, 01 Oct 2023 19:55:16 +0000 Received: from mail-yb1-xb36.google.com ([2607:f8b0:4864:20::b36]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qn2X3-007f0G-5g for pgsql-hackers@postgresql.org; Sun, 01 Oct 2023 19:55:14 +0000 Received: by mail-yb1-xb36.google.com with SMTP id 3f1490d57ef6-d84f18e908aso16781680276.1 for ; Sun, 01 Oct 2023 12:55:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=leadboat.com; s=google; t=1696189992; x=1696794792; darn=postgresql.org; h=user-agent:content-disposition:mime-version:message-id:subject:to :from:date:from:to:cc:subject:date:message-id:reply-to; bh=xAy/HFNXJn9ONEgj61o8Y1zTEMc/6Xx5kfDtclW3zUQ=; b=IZb0s3AJghDYHQNxVZKJ4ixG5+QAh/K/Uf+0LWiCuSjIonl53S4m098xK7Sep6G+Uf EO4OMnQRKow+cqvaQVgUv6CYOWJg6eiN46Xj+vGB/8PTte6bt0GJ4M3RKTMh0mitKy4i gckB5rYOzhO8npY9CBwrRtBv0q/aI8DqxrE/4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696189992; x=1696794792; h=user-agent:content-disposition:mime-version:message-id:subject:to :from:date:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=xAy/HFNXJn9ONEgj61o8Y1zTEMc/6Xx5kfDtclW3zUQ=; b=ltrYim1RrXNo4+BjenLDCTNmSP2DyqhPmms/J2iHPRFFlAJ96ss+ya64UnFLlfLGjT YWITB7FuRrCqtnuS6RT3k34ocCBUkhlTodMYNwaQLJD7fIkXSfrTygJbMSdkYt8mRBUN +lxAxj+17X9ZEOW1OuHVX/oC3eWnt5Ah9KL8tC6hUhGv/+Y2tkgCToUyo+Ol1tXkoXzS MbZ3l3Qr3oVUVVPw2WBNhEnRBnIjPE5GjvBdY0tbQETPckFL/tZlR2T3iJXGoWVhQLpv QyYBx3gQOCrWwrPEip3tqaPPCdJ1pvz3S5cJoIXvd5GOEu8xEmmdlX4K/TlLFcT14pFl k7Yw== X-Gm-Message-State: AOJu0Yy4lDT62kHFbFu7wiU/joYA9zvkmcLq7GzD5DXa1RAzUP0eQmTS uUuKkuncBrIpmaUYVV4puc8BsE2ZnMsXqCGv3PU= X-Google-Smtp-Source: AGHT+IGfMSWITmmZY4RB0g/tU6GVmVzLs8oLxAx1hVwc6uN0CLNKkPfwKiLC+uMh6x8x1KiF572hqw== X-Received: by 2002:a25:d647:0:b0:d81:7ac8:b18e with SMTP id n68-20020a25d647000000b00d817ac8b18emr9053313ybg.26.1696189992022; Sun, 01 Oct 2023 12:53:12 -0700 (PDT) Received: from google.com ([2600:1702:a20:5750::2e]) by smtp.gmail.com with ESMTPSA id z17-20020a5b0a51000000b00d89679f6d22sm4141648ybq.64.2023.10.01.12.53.11 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 01 Oct 2023 12:53:11 -0700 (PDT) Date: Sun, 1 Oct 2023 12:53:09 -0700 From: Noah Misch To: pgsql-hackers@postgresql.org Subject: pgstatindex vs. !indisready Message-ID: <20231001195309.a3@google.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="vMCPoXwooX6T2m/B" Content-Disposition: inline User-Agent: Mutt/2.2.12 (2023-09-09) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --vMCPoXwooX6T2m/B Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 --vMCPoXwooX6T2m/B Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="unlogged-recovery-funcalls-v0.patch" Author: Noah Misch Commit: Noah Misch 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')"); --vMCPoXwooX6T2m/B--