简体   繁体   English

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

[英]Why MySQL InnoDB can handle concurrent updates and PostgreSQL can't?

Let's imagine you have a table with this definition: 假设您有一个具有以下定义的表:

CREATE TABLE public.positions
(
   id serial,
   latitude numeric(18,12),
   longitude numeric(18,12),
   updated_at timestamp without time zone
)

And you have 50,000 rows in such table. 这样的表中有50,000行。 now for testing purposes you will run an update like this: 现在出于测试目的,您将运行以下更新:

update positions
set  updated_at = now()
where latitude between 234.12 and 235.00;

that statement will update 1,000 rows from the 50,000 (in this specific dataset) 该语句将更新50,000条中的1,000行(在此特定数据集中)

if you run such query in 30 different threads, MySQL innodb will succeed and postgres will fail with lots of deadlocks. 如果您在30个不同的线程中运行此类查询,则MySQL innodb将成功,而postgres将失败,并出现大量死锁。

why? 为什么?

Plain old luck, I would say. 我会说过去的运气平淡。

If thirty threads go ahead and want to update the same 1000 rows, they can either access these rows in the same order (in which case they will lock out each other and do it sequentially) or in different orders (in which case they will deadlock). 如果继续执行三十个线程并希望更新相同的1000行,则它们可以以相同的顺序(在这种情况下它们将彼此锁定并依次执行)或以不同的顺序(在这种情况下它们将死锁)访问这些行。 )。

That's the same for InnoDB and PostgreSQL. InnoDB和PostgreSQL都是一样的。

To analyze why things work out different in your case, you should start by comparing the execution plans. 要分析为什么情况不同的原因,您应该先比较执行计划。 Maybe then you get a clue why PostgreSQL does not access all rows in the same order. 也许然后您可能会发现为什么PostgreSQL不按相同顺序访问所有行。

Lacking this information, I'd guess that you are experiencing a feature introduced in version 8.3 that speeds up concurrent sequential scans: 缺少此信息,我想您正在体验8.3版中引入的一项功能,功能可以加速并发顺序扫描:

  • Concurrent large sequential scans can now share disk reads (Jeff Davis) 并发大型顺序扫描现在可以共享磁盘读取(Jeff Davis)

    This is accomplished by starting the new sequential scan in the middle of the table (where another sequential scan is already in-progress) and wrapping around to the beginning to finish. 这是通过在表的中间开始新的顺序扫描(已经在进行另一个顺序扫描)并从头到尾完成来完成的。 This can affect the order of returned rows in a query that does not specify ORDER BY . 这可能会影响未指定ORDER BY的查询中返回行的顺序。 The synchronize_seqscans configuration parameter can be used to disable this if necessary. 如有必要,可以使用synchronize_seqscans配置参数禁用此功能。

Check if your PostgreSQL execution plan uses sequential scans and see if changing synchronize_seqscans avoids the deadlocks. 检查您的PostgreSQL执行计划是否使用顺序扫描,并查看是否更改synchronize_seqscans可以避免死锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM