BUG #18498: Locking a table from a trigger (with using two sessions) causes a deadlock: the bug or the feature?

From: PG Bug reporting form <noreply(at)postgresql(dot)org>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: d(dot)koval(at)postgrespro(dot)ru
Subject: BUG #18498: Locking a table from a trigger (with using two sessions) causes a deadlock: the bug or the feature?
Date: 2024-06-07 07:55:29
Message-ID: 18498-b95f3ee4c156de45@postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 18498
Logged by: Dmitry Koval
Email address: d(dot)koval(at)postgrespro(dot)ru
PostgreSQL version: 17beta1
Operating system: Ubuntu 22.04
Description:

Hi!

I see strange behavior of the LOCK TABLE command when executed from a
trigger.
If LOCK TABLE (for the same table) is executed from a trigger in two
different sessions, then there is a possibility of a “deadlock detected”
error.
Is this correct? (I'm guessing the correct behavior is this one: one session
getting a table lock, and another session waits for the first session's
transaction to complete.)

Example.
--------
1) I wrote a tap-test to reproduce the problem (see attached file
v1-0001-LOCK-TABLE-with-deadlocks.patch in next email).
After applying the patch you need to run the test using the command

PROVE_TESTS=t/006_parallel_inserts.pl make check -C
src/test/modules/test_misc

Test explanations.
------------------
The test creates BEFORE INSERT trigger. Trigger function contains rows:

RAISE LOG 'Before lock (pid %)', pg_backend_pid();
LOCK TABLE test;
RAISE LOG 'After lock (pid %)', pg_backend_pid();

The test starts 4 threads that insert records, causing the trigger.
As a result of running the test, we see several "deadlock detected" errors
with debug messages in the server log, like these:

[219562] 006_parallel_inserts.pl LOG: Before lock (pid 219562)
[219562] 006_parallel_inserts.pl CONTEXT: PL/pgSQL function test_func()
line 5 at RAISE
[219562] 006_parallel_inserts.pl STATEMENT: INSERT INTO test VALUES (10,
'worker_2');
[219563] 006_parallel_inserts.pl LOG: Before lock (pid 219563)
[219563] 006_parallel_inserts.pl CONTEXT: PL/pgSQL function test_func()
line 5 at RAISE
[219563] 006_parallel_inserts.pl STATEMENT: INSERT INTO test VALUES (11,
'worker_1');
[219563] 006_parallel_inserts.pl ERROR: deadlock detected
[219563] 006_parallel_inserts.pl DETAIL: Process 219563 waits for
AccessExclusiveLock on relation 16384 of database 5; blocked by process
219562.
Process 219562 waits for AccessExclusiveLock on relation 16384 of database
5; blocked by process 219563.
Process 219563: INSERT INTO test VALUES (11, 'worker_1');
Process 219562: INSERT INTO test VALUES (10, 'worker_2');
[219563] 006_parallel_inserts.pl HINT: See server log for query details.
[219563] 006_parallel_inserts.pl CONTEXT: SQL statement "LOCK TABLE test"
PL/pgSQL function test_func() line 6 at SQL statement

As we can seen, two sessions 219562 and 2195623 received an
AccessExclusiveLock lock on the the same table, after which a deadlock was
immediately diagnosed.
----

2) I have attached a similar tap-test using the function, but without using
the trigger (file v1-0001-LOCK-TABLE-wo-errors.patch in next email).
When running this test, no "deadlock detected" errors occur.
It's strange because the tests are similar.
----

The main question: is the "deadlock detected" error (1) correct?
(I.e. is it necessary to look for the reason for this behavior?)

--
With best regards,
Dmitry Koval

Postgres Professional: http://postgrespro.com

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Dmitry Koval 2024-06-07 08:47:02 Re: BUG #18498: Locking a table from a trigger (with using two sessions) causes a deadlock: the bug or the feature?
Previous Message Andres Freund 2024-06-07 03:12:58 Re: error "can only drop stats once" brings down database