postgresql - 尝试理解 MVCC

标签 postgresql mvcc

我试图理解 MVCC 但无法理解。例如。 Transaction1 (T1) 尝试读取一些数据行。在同一时间,T2 更新同一行。

交易流程是

T1 begin -> T2 begin -> T2 commit -> T1 commit

所以第一个事务获取数据库快照并返回用户结果,他将在该结果上构建其他计算。但据我了解,客户获得旧数据值(value)?据我了解 MVCC,在 T1 事务开始后,该事务不知道其他一些事务更改数据。因此,如果现在用户在此之后进行一些计算(不涉及数据库),那么他是在错误的数据上进行计算吗?或者我不对,第一笔交易有一些机制可以知道该行已更改?

现在让我们改变交易流程。

T2beg -> T1beg -> T2com -> T1com

在 2PL 中,用户由于锁定而获得较新版本的数据(T1 必须等待排他锁释放)。但在 MVCC 的情况下,它仍然是旧数据,据我了解 postgresql MVCC 模型。所以我可以获得陈旧的数据以换取速度。我对吗?或者我错过了什么?

谢谢

最佳答案

是的,您可能会从数据库中读取一些旧数据(并发事务已修改),并据此执行计算并将“过时”数据存储在数据库中。

这不是问题,因为逻辑顺序比交易发生的实际顺序更重要:

如果T1读取了一些数据,然后T2修改了数据,然后T1根据读取的内容修改了数据库,可以说逻辑上T1发生在T2之前,没有不一致。

只有当 T1 和 T2 修改相同的数据时才会出现异常:T1 读取数据,T2 修改数据,然后 T1 根据读取的内容修改相同的数据。这种异常称为“丢失更新”。

丢失的更新只能发生在最弱的(默认)隔离级别 READ COMMITTED

如果您想更好地隔离并发事件,您至少需要使用REPEATABLE READ 隔离。然后,当 T1 尝试更新数据时,它会收到一个序列化错误,您将不得不重复该事务。在第二次尝试时,它会读取新数据,一切都会保持一致。

关于postgresql - 尝试理解 MVCC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57746567/

相关文章:

oracle - Oracle 是否具有与 Postgres 的 text_pattern_ops opclass 等效的功能?

node.js - 正确的 Sequelize 流程以避免重复行?

postgresql - postgresql 中 case 语句的总和返回 false

mysql - MVCC 如何与 MySql 中的 Lock 一起工作?

database - PostgreSQL - MVCC(多版本并发控制) - 何时获取实际锁?

Mysql InnoDB 行锁定读取

python - 计算 postgresql 中返回的行数

performance - Postgres 优化 UPDATE

postgresql - Postgres pg_dump 对生产数据库的影响