Postgres并发处理

本文,我们将深入探讨并发的概念以及Postgres中是如何处理它的。让我们开始吧!

并发及其角色

计算机科学史上最受追捧的词汇之一是并发[1]并行[2]。如果没有这两者的需求,我们可以简单地一次运行一个程序,不需要操作系统资源(RAM、CPU)在应用程序之间进行调度,从而使内核变得更简单。内核的核心目的是调度和协调计算机资源和应用程序,使并发和并行成为可能。尽管没有这些概念,整体复杂性可以减少95%,但显然,95%的开发无法在没有这些概念的情况下进行。

3cdeed221b956926b084aa3290e8c4f3.jpeg
1*AE7bfqf5RJNy4df04PaYWA.jpeg

并发 vs 并行

并发是处理多个任务的能力,但不一定是同时执行它们。并行涉及同时执行多个任务,通常使用多个处理单元。虽然并发和并行被认为是*不同[3]*概念,但它们实质上宣扬相同的原则,即在给定的时间内处理多个操作。我们可以坚持使用“并发”这个词。要具体解释并发是如何在实现它的所有领域中处理的是不可能的,因为我们处理的所有计算机系统都是以并发作为基本概念构建的。但我们可以谈论最主要的领域,即数据库系统。每个数据库系统都采用不同的策略实现并发,但最终,我们可以将其归结为三种策略:

1.锁[4] — 限制对特定数据或资源的访问,确保只有一个用户/进程/事务可以同时修改/查看特定记录或记录集。2.多版本并发控制[5](MVCC) — 为每个用户/进程/事务维护多个版本(下文更多介绍)。3.基于时间戳的协议[6] — 使用时间戳确定事务的序列化顺序,确保事务以维护一致性的方式执行。

Postgres如何处理并发 ⛁

Postgres同时使用锁和MVCC,但更倾向于其MVCC架构。

MVCC[7] 提供了事务之间的强大隔离[8]。这意味着每个事务都获得其数据库的快照或版本,其中包含有关已提交、进行中或尚未启动的事务ID的信息。

因此,每个快照包括:

•当前事务的事务ID。•活动事务ID列表 — 那些已经开始但尚未提交或回滚的事务。•在拍摄快照时提交的最高事务ID。在此之后的任何ID都被视为从快照的角度来看处于“未来”。

其目的是为每个事务创建一致的视图,以避免读写之间的冲突。

b3b20d49e8781d6493fd0d323599bec9.png

Image.png

MVCC事务内部流程

所有未提交的更改都在共享缓冲区缓存和Write-Ahead Logging(WAL)系统中进行跟踪,直到它们提交。一旦提交,这些更改就会被刷新到数据库中。为了更好地解释MVCC的目的,考虑两个并发事务:一个更新了行的列,另一个查询了该行。如果第一个事务更新但尚未提交,而第二个在第一个提交之前进行查询,可能会导致获取未提交的更新行数据,这是不正确的,因为第一个事务有可能被中止。这种状态称为脏读。Postgres如何解决这个问题呢?每个表都有带有两个系统列的行标头:

xmin — 创建行的事务ID。•xmax — 删除行的事务ID。

由于MVCC快照具有事务ID(xmin)列表,因此每个事务都知道所有并发事务。在脏读的情况下,第二个事务的快照中有第一个事务的ID在其并发事务列表中,因此Postgres会过滤该行并获取所有其余的符合条件的行。

c540fd3cb7727ec0fcb3b94254e6d123.jpeg
1*5X4CLbM4am5Ymf9a6L4qrQ.jpeg

有无MVCC的区别

更详细地说,Postgres在运行时进行了多个检查,以确定行是否对当前事务可见。仅当满足以下xmin条件之一时,行才可见:

xmin小于最高已提交事务ID。•它是当前事务的ID。

还应遵守以下xmax条件之一:

xmax应为未设置状态。•它引用一个截至事务快照时尚未提交或启动的事务。

这些检查在运行时进行,但目前尚不清楚它们是如何高效地进行的,以确保不影响性能。

使用MVCC模型而不是锁的主要优势在于,在MVCC中,用于写入数据的锁不会阻塞读取数据,反之亦然。

Postgres MVCC不能处理的事情 💔

MVCC旨在防止并发的读/写冲突,但它不能处理并发的写操作,这由传统的锁来管理。Postgres在不同层次(行、表)上提供了各种锁定机制,但对于同一行的写操作,它们应该按顺序进行。

虽然MySQL也通过其默认存储引擎InnoDB提供MVCC功能,但Postgres是首个将这一概念引入数据库世界的。这种早期采用使Postgres在读写负载方面比MySQL更具性能优势,因为MySQL没有同等优化。然而,在读重型系统中,MySQL更受欢迎,因为它已被证明比Postgres更为高效。

引用链接

[1] 并发: https://www.notion.so/How-concurrency-handled-in-postgres-0d9b873c9a6e45dabfbf5d21d1947c94?pvs=4
[2] 并行: https://www.notion.so/How-concurrency-handled-in-postgres-0d9b873c9a6e45dabfbf5d21d1947c94?pvs=4
[3] 不同: https://www.google.com/search?q=concurrency+vs+parallelism&sca_esv=599372071&sxsrf=ACQVn09k-k_w7TlIT8VC8wFgW6QmAVZdDw%3A1705555740621&ei=HLeoZfjKJeiRseMP5J-K8AY&ved=0ahUKEwj4yMGgmuaDAxXoSGwGHeSPAm4Q4dUDCBA&uact=5&oq=concurrency+vs+parallelism&gs_lp=Egxnd3Mtd2l6LXNlcnAiGmNvbmN1cnJlbmN5IHZzIHBhcmFsbGVsaXNtMhEQABiABBiKBRiRAhixAxiDATILEAAYgAQYigUYkQIyCxAAGIAEGIoFGJECMgsQABiABBiKBRiRAjIFEAAYgAQyBRAAGIAEMgUQABiABDIFEAAYgAQyBRAAGIAEMgUQABiABEi5CVCJBViRB3ACeAGQAQCYAXCgAdABqgEDMS4xuAEDyAEA-AEBwgIKEAAYRxjWBBiwA8ICDRAAGIAEGIoFGEMYsAPCAg0QABiABBgNGLEDGIMBwgIGEAAYBxgewgIHEAAYgAQYDeIDBBgAIEGIBgGQBgo&sclient=gws-wiz-serp
[4] 锁: https://blog.dbwatch.com/database-locks-how-to-monitor-and-manage-it
[5] 多版本并发控制: https://www.postgresql.org/docs/7.1/mvcc.html
[6] 基于时间戳的协议: https://studyglance.in/dbms/display.php?tno=45&topic=Timestamp-Based-Protocols-in-DBMS#:~:text=Timestamp%2Dbased%20protocols%20are%20concurrency,without%20the%20need%20for%20locking.
[7] MVCChttps://www.postgresql.org/docs/7.1/mvcc.html
[8] 隔离: https://www.postgresql.org/docs/7.1/transaction-iso.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小技术君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值