让我们假设您有一个包含此定义的表:
CREATE TABLE public.positions
(
id serial,
latitude numeric(18,12),
longitude numeric(18,12),
updated_at timestamp without time zone
)
此表中有50,000行。现在出于测试目的,您将运行如下更新:
update positions
set updated_at = now()
where latitude between 234.12 and 235.00;
该语句将从50,000(在此特定数据集中)更新1,000行
如果你在30个不同的线程中运行这样的查询,那么MySQL innodb会成功,而postgres会因很多死锁而失败。
为什么?
答案 0 :(得分:4)
简单的运气,我会说。
如果有30个线程继续并想要更新相同的1000行,他们可以按相同的顺序访问这些行(在这种情况下,它们将相互锁定并按顺序执行)或以不同的顺序(在这种情况下)他们会陷入僵局)。
InnoDB和PostgreSQL的情况相同。
要分析为什么事情在您的情况下有所不同,您应该首先比较执行计划。也许你得到一个线索,为什么PostgreSQL不能以相同的顺序访问所有行。
缺少这些信息,我猜你正在遇到加速并发顺序扫描的feature introduced in version 8.3:
并发大型顺序扫描现在可以共享磁盘读取(Jeff Davis)
这是通过在表格中间启动新的顺序扫描(其中另一个顺序扫描已在进行中)并回绕到开始结束来完成的。这可能会影响未指定
ORDER BY
的查询中返回行的顺序。如果需要,synchronize_seqscans
配置参数可用于禁用此功能。
检查PostgreSQL执行计划是否使用顺序扫描,看看更改synchronize_seqscans
是否可以避免死锁。