为什么MySQL InnoDB可以处理并发更新而PostgreSQL不能?

时间:2016-10-09 06:47:16

标签: mysql postgresql deadlock isolation-level

让我们假设您有一个包含此定义的表:

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会因很多死锁而失败。

为什么?

1 个答案:

答案 0 :(得分:4)

简单的运气,我会说。

如果有30个线程继续并想要更新相同的1000行,他们可以按相同的顺序访问这些行(在这种情况下,它们将相互锁定并按顺序执行)或以不同的顺序(在这种情况下)他们会陷入僵局)。

InnoDB和PostgreSQL的情况相同。

要分析为什么事情在您的情况下有所不同,您应该首先比较执行计划。也许你得到一个线索,为什么PostgreSQL不能以相同的顺序访问所有行。

缺少这些信息,我猜你正在遇到加速并发顺序扫描的feature introduced in version 8.3

  
      
  • 并发大型顺序扫描现在可以共享磁盘读取(Jeff Davis)

         

    这是通过在表格中间启动新的顺序扫描(其中另一个顺序扫描已在进行中)并回绕到开始结束来完成的。这可能会影响未指定ORDER BY的查询中返回行的顺序。如果需要,synchronize_seqscans配置参数可用于禁用此功能。

  •   

检查PostgreSQL执行计划是否使用顺序扫描,看看更改synchronize_seqscans是否可以避免死锁。