我想知道Postgresql如何处理批量删除的锁。 我的目标是避免操作过程中出现僵局。
目前,我们只进行插入和更新(使用批量 INSERT ON CONFLICT)。通过在保存期间对行进行正确排序可以避免死锁。因此,在更新的情况下(可能导致死锁),不存在交叉锁定数据的风险。
但是,现在我还需要对大量数据进行删除。 我想知道影响多行的单个删除查询是否会导致并行运行 INSERT ON CONFLICT 查询的死锁。
我认为这一切都归结为锁定原子性。受删除查询影响的所有行是否都被原子锁定?
所有语句按照找到行的顺序逐一锁定行。因此,任何以不同顺序修改或删除相同两行的两条语句都可能会彼此死锁。
如果没有任何语句修改相同的行,您将获得最佳性能,但如果它们修改相同的行,则它们应该以相同的顺序修改行。没有直接的方法来影响删除行的顺序,但您可以使用PostgreSQL文档中描述的技巧:
WITH delete_batch AS (
SELECT l.ctid FROM user_logs AS l
WHERE l.status = 'archived'
ORDER BY l.creation_date
FOR UPDATE
LIMIT 10000
)
DELETE FROM user_logs AS dl
USING delete_batch AS del
WHERE dl.ctid = del.ctid;