SDR*_*yes 0 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
)
Run Code Online (Sandbox Code Playgroud)
你在这样的表中有 50,000 行。现在出于测试目的,您将运行如下更新:
update positions
set updated_at = now()
where latitude between 234.12 and 235.00;
Run Code Online (Sandbox Code Playgroud)
该语句将更新 50,000 行中的 1,000 行(在此特定数据集中)
如果您在 30 个不同的线程中运行这样的查询,MySQL innodb 将成功,而 postgres 将因大量死锁而失败。
为什么?
我会说,普通的老运气。
如果 30 个线程继续并想要更新相同的 1000 行,它们可以以相同的顺序访问这些行(在这种情况下它们将相互锁定并按顺序执行)或以不同的顺序访问这些行(在这种情况下它们将死锁)。
InnoDB 和 PostgreSQL 也是如此。
要分析为什么在您的情况下事情会有所不同,您应该从比较执行计划开始。也许你会知道为什么 PostgreSQL 不会以相同的顺序访问所有行。
如果缺少这些信息,我猜您会遇到8.3 版中引入的一项功能,该功能可以加速并发顺序扫描:
并发大型顺序扫描现在可以共享磁盘读取(Jeff Davis)
这是通过在表的中间开始新的顺序扫描(另一个顺序扫描已经在进行中)并从头开始到结束来完成的。这可能会影响未指定的查询中返回行的顺序
ORDER BY。synchronize_seqscans如有必要,配置参数可用于禁用此功能。
检查您的 PostgreSQL 执行计划是否使用顺序扫描并查看更改是否synchronize_seqscans避免了死锁。
| 归档时间: |
|
| 查看次数: |
163 次 |
| 最近记录: |