Postgresql deadlock

Sometimes postgresql causes error blocking.

In the trigger for the table set for UPDATE.

Comment in the table:

http://pastebin.com/L1a8dbn4

Journal (INSERT sentences cut):

2012-01-26 17:21:06 MSK ERROR:  deadlock detected
2012-01-26 17:21:06 MSK DETAIL:  Process 2754 waits for ExclusiveLock on tuple (40224,15) of relation 735493 of database 734745; blocked by process 2053.
Process 2053 waits for ShareLock on transaction 25162240; blocked by process 2754.
Process 2754: INSERT INTO comment (user_id, content_id, reply_id, text) VALUES (1756235868, 935967, 11378142, 'text1') RETURNING comment.id;
Process 2053: INSERT INTO comment (user_id, content_id, reply_id, text) VALUES (4071267066, 935967, 11372945, 'text2') RETURNING comment.id;
2012-01-26 17:21:06 MSK HINT:  See server log for query details.
2012-01-26 17:21:06 MSK CONTEXT:  SQL statement "SELECT comments_count FROM content WHERE content.id = NEW.content_id FOR UPDATE"
PL/pgSQL function "increase_comment_counter" line 5 at SQL statement
2012-01-26 17:21:06 MSK STATEMENT:  INSERT INTO comment (user_id, content_id, reply_id, text) VALUES (1756235868, 935967, 11378142, 'text1') RETURNING comment.id;

And the trigger by the table comment:

CREATE OR REPLACE FUNCTION increase_comment_counter() RETURNS TRIGGER AS $$
DECLARE
comments_count_var INTEGER;
BEGIN
    SELECT INTO comments_count_var comments_count FROM content WHERE content.id = NEW.content_id FOR UPDATE;
    UPDATE content SET comments_count = comments_count_var + 1, last_comment_dt = now()  WHERE content.id = NEW.content_id;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;



CREATE TRIGGER increase_comment_counter_trigger AFTER INSERT ON comment FOR EACH ROW EXECUTE PROCEDURE increase_comment_counter();

Why can this happen?

Thank!

+5
source share
1 answer

These are two comments inserted with the same content_id. A simple attachment of a comment will bring up a SHARE lock on the content line to stop another transaction, deleting this line before the first transaction is completed.

However, the trigger is then turned on to update the lock to EXCLUSIVE, and this can be blocked by a parallel transaction executing the same process. Consider the following sequence of events:

Txn 2754                      Txn 2053
Insert Comment
                              Insert Comment
Lock Content#935967 SHARE
  (performed by fkey)
                              Lock Content#935967 SHARE
                                (performed by fkey)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2053 share lock)
                              Trigger
                              Lock Content#935967 EXCLUSIVE
                              (blocks on 2754 share lock)

So-deadlock.

. .

SELECT 1 FROM content WHERE content.id = 935967 FOR UPDATE
INSERT INTO comment(.....)

" ", , , . , -, . . , . , , memcached . , , -, , .

+10

All Articles