Обсуждение: Bug: Deferred FKey Check Happening on Double Update, Not Single

Поиск
Список
Период
Сортировка

Bug: Deferred FKey Check Happening on Double Update, Not Single

От
Doug Safreno
Дата:
Hello all,

I have what appears to be a bug to report. Basically, foreign key deferred locking behavior on update is inconsistent between single updates and double updates in transactions.

Imagine I have done the following setup:

DROP TABLE B;
DROP TABLE A;

CREATE TABLE A (
    ID int NOT NULL PRIMARY KEY,
    Payload int
);

CREATE TABLE B (
    ID int NOT NULL PRIMARY KEY,
    AID int REFERENCES A(ID) DEFERRABLE INITIALLY DEFERRED,
    Payload int
);

INSERT INTO A (ID, Payload) VALUES (1, 100);
INSERT INTO B (ID, AID, Payload) VALUES (1, 1, 200);

Now, in process 1, I do:

BEGIN;
SELECT * FROM A WHERE ID = 1 FOR UPDATE;

Now consider the versions A and B of process 2.

Version A:

BEGIN;
UPDATE B SET "payload" = 1000 WHERE ID = 1;
COMMIT;

Version B:

BEGIN;
UPDATE B SET "payload" = 1000 WHERE ID = 1;
UPDATE B SET "payload" = 1000 WHERE ID = 1;
COMMIT;

In process 2, if I do version A, it goes through immediately. If I do version B, it hangs, waiting for process 1 to release its lock. I would expect consistent behavior.

I was unsure from documentation which of two behaviors was the "expected" behavior.

Version: PostgreSQL 10.6 (Ubuntu 10.6-1.pgdg16.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609, 64-bit

Which one is expected? And is this really a bug?

Best,
Doug

Re: Bug: Deferred FKey Check Happening on Double Update, Not Single

От
Sergei Kornilov
Дата:
Hi

> Which one is expected?

Both are expected. This is foreign key check optimisation: we can safely skip FK trigger check if row was inserted not
inthis transaction and update does not touch FK fields:
https://github.com/postgres/postgres/blob/REL_11_STABLE/src/backend/utils/adt/ri_triggers.c#L1769

> And is this really a bug?
 
so no, this is not bug.

regards, Sergei


Re: Bug: Deferred FKey Check Happening on Double Update, Not Single

От
Doug Safreno
Дата:
Hey Sergei,

Neither transaction touches FK fields - so shouldn't they both skip FK trigger check?

Best,
Doug


On Thu, Feb 14, 2019 at 11:42 PM Sergei Kornilov <sk@zsrv.org> wrote:
Hi

> Which one is expected?

Both are expected. This is foreign key check optimisation: we can safely skip FK trigger check if row was inserted not in this transaction and update does not touch FK fields: https://github.com/postgres/postgres/blob/REL_11_STABLE/src/backend/utils/adt/ri_triggers.c#L1769

> And is this really a bug?

so no, this is not bug.

regards, Sergei

Re: Bug: Deferred FKey Check Happening on Double Update, Not Single

От
Andrew Gierth
Дата:
>>>>> "Doug" == Doug Safreno <doug@avinetworks.com> writes:

 Doug> Hey Sergei,

 Doug> Neither transaction touches FK fields - so shouldn't they both
 Doug> skip FK trigger check?

The optimization that lets the check be skipped only applies on the
_first_ modification of the row within the transaction. On the second or
subsequent modifications, the code can't easily tell whether the row was
inserted in the current transaction (in which case the optimization must
be skipped) or just modified, so it assumes the worst.

-- 
Andrew (irc:RhodiumToad)


Re: Bug: Deferred FKey Check Happening on Double Update, Not Single

От
Doug Safreno
Дата:
Gotcha, thanks for explanation.

Best,
Doug


On Fri, Feb 15, 2019 at 3:15 PM Andrew Gierth <andrew@tao11.riddles.org.uk> wrote:
>>>>> "Doug" == Doug Safreno <doug@avinetworks.com> writes:

 Doug> Hey Sergei,

 Doug> Neither transaction touches FK fields - so shouldn't they both
 Doug> skip FK trigger check?

The optimization that lets the check be skipped only applies on the
_first_ modification of the row within the transaction. On the second or
subsequent modifications, the code can't easily tell whether the row was
inserted in the current transaction (in which case the optimization must
be skipped) or just modified, so it assumes the worst.

--
Andrew (irc:RhodiumToad)