From 0b2f83e079b500370784ae4838b247ab72cc2e82 Mon Sep 17 00:00:00 2001 From: Koval Dmitry Date: Thu, 6 Jun 2024 19:53:15 +0300 Subject: [PATCH v1] LOCK TABLE with deadlocks --- .../test_misc/t/006_parallel_inserts.pl | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/test/modules/test_misc/t/006_parallel_inserts.pl diff --git a/src/test/modules/test_misc/t/006_parallel_inserts.pl b/src/test/modules/test_misc/t/006_parallel_inserts.pl new file mode 100644 index 0000000000..e8185ea188 --- /dev/null +++ b/src/test/modules/test_misc/t/006_parallel_inserts.pl @@ -0,0 +1,77 @@ +use strict; +use warnings; + +use threads; +use IPC::Run; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +my $THREADS = 4; +my $ROWS = 365; + +# Initialize new node. +my $node = PostgreSQL::Test::Cluster->new("node"); +$node->init(); +$node->start; + +# Initial queries. +$node->safe_psql("postgres", " +CREATE TABLE test(i int, t text); +CREATE TABLE test2(i int, t text); + +CREATE FUNCTION test_func() RETURNS trigger AS +\$BODY\$ +DECLARE + q text; +BEGIN + RAISE LOG 'Before lock (pid %)', pg_backend_pid(); + LOCK TABLE test; + RAISE LOG 'After lock (pid %)', pg_backend_pid(); + q = 'INSERT INTO test2 SELECT ((\$1)::test).*'; + EXECUTE q USING NEW; + RETURN NULL; +END; +\$BODY\$ LANGUAGE plpgsql SECURITY DEFINER; + +CREATE TRIGGER test_trigger BEFORE INSERT ON test FOR EACH ROW EXECUTE PROCEDURE test_func(); +"); + +# Invoke psql. +sub psql_worker +{ + my ($worker_name) = @_; + + for (my $j = 1; $j <= $ROWS; $j += 1) + { + my $query = qq[INSERT INTO test VALUES ($j, '$worker_name');]; + my @cmd = ['psql', '-XAtq', '-d', $node->connstr('postgres'), '-v', 'ON_ERROR_STOP=1', '-c', $query]; + + print("# Executing: $query\n"); + IPC::Run::run @cmd; + } +} + +# Start the workers. +my @workers; +for (my $i = 1; $i <= $THREADS; $i += 1) +{ + my $worker_name_i = "worker_$i"; + print("# Worker: $worker_name_i\n"); + push @workers, threads->create('psql_worker', $worker_name_i); +} + +# Wait for the workers to finish. +foreach my $thr (@workers) +{ + $thr->join(); +} + +# Check rows. +my $psql_stdout; +$node->psql('postgres', q(SELECT count(*) FROM test2;), stdout => \$psql_stdout); +is($psql_stdout, $ROWS * $THREADS, 'rows amount'); + +# Done. +$node->stop; +done_testing(); -- 2.34.1