1

I need suggestions/ideas of handling a issue with deadlocks. I'm having multiple batch inserts commands to same table:

insert into ip (id, p_id, m_type, m_id, sha256, path) VALUES (1,ドル 2,ドル 3,ドル 4,ドル 5,ドル 6,ドル7,ドル8ドル), (9,ドル 10,ドル 11,ドル 12,ドル 13,ドル 14,ドル 15,ドル 16ドル), (17,ドル 18,ドル 19,ドル 20,ドル 21,ドル 22,ドル 23,ドル 24ドル), (25,ドル 26,ドル 27,ドル 28,ドル 29,ドル 30,ドル 31ドル ,32ドル), (33,ドル 34,ドル 35,ドル 36,ドル 37,ドル 38,ドル39,540ドル), (41,ドル 42,ドル 43,ドル44,545,ドル 46,ドル 47,ドル48ドル) ... ON CONFLICT DO NOTHING

And since Insertion order is not honored in database most probably because PostgreSQL is launching several parallel insert threads, I'm getting the following deadlocks:

[1111]:ERROR:deadlock detected 
[1111]:DETAIL: Process 1111 waits for ShareLock on transaction 1423145219; blocked by process 2222.
Process 1111 waits for ShareLock on transaction 1423145222: blocked by process 1111.
Process 1111: insert into ip (id, p_id, m_type, m_id, sha256, path) VALUES (1,ドル 2,ドル 3,ドル 4,ドル 5,ドル 6,ドル7,ドル8ドル), (9,ドル 10,ドル 11,ドル 12,ドル 13,ドル 14,ドル 15,ドル 16ドル), (17,ドル 18,ドル 19,ドル 20,ドル 21,ドル 22,ドル 23,ドル 24ドル), (25,ドル 26,ドル 27,ドル 28,ドル 29,ドル 30,ドル 31ドル ,32ドル), (33,ドル 34,ドル 35,ドル 36,ドル 37,ドル 38,ドル39,540ドル), (41,ドル 42,ドル 43,ドル44,545,ドル 46,ドル 47,ドル48ドル) ... ON CONFLICT DO NOTHING
Process 2222: insert into ip (id, p_id, m_type, m_id, sha256, path) VALUES (1,ドル 2,ドル 3,ドル 4,ドル 5,ドル 6,ドル7,ドル8ドル), (9,ドル 10,ドル 11,ドル 12,ドル 13,ドル 14,ドル 15,ドル 16ドル), (17,ドル 18,ドル 19,ドル 20,ドル 21,ドル 22,ドル 23,ドル 24ドル), (25,ドル 26,ドル 27,ドル 28,ドル 29,ドル 30,ドル 31ドル ,32ドル), (33,ドル 34,ドル 35,ドル 36,ドル 37,ドル 38,ドル39,540ドル), (41,ドル 42,ドル 43,ドル44,545,ドル 46,ドル 47,ドル48ドル) ... ON CONFLICT DO NOTHING

As we can see the bulk inserts acquire ShareLocks which deadlock each other.

On the one hand I don't want to acquire an exclusive lock for each bulk insert on the entire table because I guess it will affect the parallel inserts performance.

On the other hand I'm not 100% sure that enforcing order (by id column which is a PK with a CTE select) is a good solution, because even if I could guarantee insertion order that would NOT ensure a later select statement would return them in that order since it's multiple bulk insertions, and the order might change.

(And also I have to reorder the table for each bulk insert).

asked Sep 3, 2023 at 11:54
1
  • What does 'a later select statement' have to do with your current predicament? Commented Sep 3, 2023 at 19:27

1 Answer 1

3

The best solution would be to make sure that no two of the concurrent statements try to insert rows with the same primary or unique key. And no, ON CONFLICT doesn't do that trick.

The second best solution is to sort the rows inserted by a single statement before inserting them:

WITH r (id, p_id, m_type, m_id, sha256, path) AS
(
 VALUES
 (1,ドル 2,ドル 3,ドル 4,ドル 5,ドル 6,ドル 7,ドル 8ドル),
 (9,ドル 10,ドル 11,ドル 12,ドル 13,ドル 14,ドル 15,ドル 16ドル),
 ...
)
INSERT INTO ip (id, p_id, m_type, m_id, sha256, path)
SELECT * FROM r
ORDER BY r.id;

That should only cause live locks, but no deadlocks.

Of course there are other causes for deadlocks like triggers, but you didn't mention any such details.

answered Sep 3, 2023 at 19:29

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.