Thread

  1. [PATCH 2/3] one more stress test for repack concurrently

    Mikhail Nikalayeu <mihailnikalayeu@gmail.com> — 2025-12-13T17:46:46Z

    ---
     contrib/amcheck/meson.build       |   1 +
     contrib/amcheck/t/008_repack_2.pl | 111 ++++++++++++++++++++++++++++++
     2 files changed, 112 insertions(+)
     create mode 100644 contrib/amcheck/t/008_repack_2.pl
    
    diff --git a/contrib/amcheck/meson.build b/contrib/amcheck/meson.build
    index cb4bc32e98a..6799df214f9 100644
    --- a/contrib/amcheck/meson.build
    +++ b/contrib/amcheck/meson.build
    @@ -51,6 +51,7 @@ tests += {
           't/005_pitr.pl',
           't/006_verify_gin.pl',
           't/007_repack_1.pl',
    +      't/008_repack_2.pl',
         ],
       },
     }
    diff --git a/contrib/amcheck/t/008_repack_2.pl b/contrib/amcheck/t/008_repack_2.pl
    new file mode 100644
    index 00000000000..a287ee2bb71
    --- /dev/null
    +++ b/contrib/amcheck/t/008_repack_2.pl
    @@ -0,0 +1,111 @@
    +# Copyright (c) 2021-2026, PostgreSQL Global Development Group
    +
    +# Test REPACK CONCURRENTLY with concurrent modifications
    +use strict;
    +use warnings FATAL => 'all';
    +
    +use PostgreSQL::Test::Cluster;
    +use PostgreSQL::Test::Utils;
    +
    +use Test::More;
    +
    +# PG_TEST_EXTRA carries a numerical stress value; 0 disables the test,
    +# 1 means the test takes about 6 seconds, and the increase should be
    +# roughly linear.
    +my $matched = ($ENV{PG_TEST_EXTRA} // '') =~ /\bstress_concurrently(?:=(?<stressval>[0-9]*))?\b/;
    +my $stressval = $+{stressval} // 1;
    +if (!$matched or $stressval == 0)
    +{
    +	plan skip_all => 'skipping disabled REPACK CONCURRENTLY stress test';
    +}
    +
    +my $node;
    +
    +#
    +# Test set-up
    +#
    +$node = PostgreSQL::Test::Cluster->new('CIC_test');
    +$node->init;
    +$node->append_conf('postgresql.conf',
    +	'lock_timeout = ' . (1000 * $PostgreSQL::Test::Utils::timeout_default));
    +$node->append_conf(
    +	'postgresql.conf', qq(
    +wal_level = logical
    +));
    +
    +my $duration = 6 * $stressval;
    +my $no_hot = int(rand(2));
    +
    +$node->start;
    +$node->safe_psql('postgres', q(CREATE TABLE tbl(id SERIAL PRIMARY KEY, val int)));
    +if ($no_hot)
    +{
    +	$node->safe_psql('postgres', q(CREATE INDEX test_idx ON tbl(val);));
    +}
    +else
    +{
    +	$node->safe_psql('postgres', q(CREATE INDEX test_idx ON tbl(id);));
    +}
    +
    +# Load amcheck
    +$node->safe_psql('postgres', q(CREATE EXTENSION amcheck));
    +
    +my $sum = $node->safe_psql('postgres', q(
    +	SELECT SUM(val) AS sum FROM tbl
    +));
    +
    +$node->safe_psql('postgres', q(CREATE UNLOGGED SEQUENCE last_j START 1 INCREMENT 1;));
    +
    +
    +$node->pgbench(
    +"--no-vacuum --client=30 --jobs=4 --exit-on-abort -T $duration",
    +0,
    +[qr{actually processed}],
    +[qr{^$}],
    +'concurrent operations with REINDEX/CREATE INDEX CONCURRENTLY',
    +{
    +	'concurrent_ops' => qq(
    +		SELECT pg_try_advisory_lock(42)::integer AS gotlock \\gset
    +		\\if :gotlock
    +			REPACK (CONCURRENTLY) tbl USING INDEX tbl_pkey;
    +			SELECT bt_index_parent_check('tbl_pkey', heapallindexed => true);
    +			SELECT bt_index_parent_check('test_idx', heapallindexed => true);
    +			\\sleep 10 ms
    +
    +			REPACK (CONCURRENTLY) tbl USING INDEX test_idx;
    +			SELECT bt_index_parent_check('tbl_pkey', heapallindexed => true);
    +			SELECT bt_index_parent_check('test_idx', heapallindexed => true);
    +			\\sleep 10 ms
    +
    +			REPACK (CONCURRENTLY) tbl;
    +			SELECT bt_index_parent_check('tbl_pkey', heapallindexed => true);
    +			SELECT bt_index_parent_check('test_idx', heapallindexed => true);
    +			\\sleep 10 ms
    +
    +			SELECT pg_advisory_unlock(42);
    +		\\else
    +			SELECT pg_advisory_lock(43);
    +				BEGIN;
    +				INSERT INTO tbl(val) VALUES (nextval('last_j')) RETURNING val \\gset p_
    +				COMMIT;
    +			SELECT pg_advisory_unlock(43);
    +			\\sleep 1 ms
    +
    +			BEGIN
    +			--TRANSACTION ISOLATION LEVEL REPEATABLE READ
    +			;
    +			SELECT 1;
    +			\\sleep 1 ms
    +			SELECT COUNT(*) AS count FROM tbl WHERE val <= :p_j \\gset p_
    +			\\if :p_count != :p_j
    +				COMMIT;
    +				SELECT (:p_count) / 0;
    +			\\endif
    +
    +			COMMIT;
    +		\\endif
    +	)
    +});
    +
    +$node->stop;
    +done_testing();
    -- 
    2.47.3
    
    
    --tbdehtstrqwksfdh
    Content-Type: text/x-diff; charset=utf-8
    Content-Disposition: attachment;
    	filename="0003-Distinguish-properly-when-database-specific-transact.patch"