编写者如何不阻止 PostgreSql 中的读取

pai*_*998 0 postgresql transaction acid snapshot-isolation mvcc

由于读者不会阻止编写者,编写者也不会阻止读者就是 MVCC 的全部内容,那么 postgresql 如何防止正在将更改提交到块/页面的编写者阻止读者读取这些不一致的数据呢?

因此,根据我对 PostgreSQL MVCC 的理解,每个表都表示为一个堆文件,每个堆文件包含页面/块的集合,这些页面/块是 8 kb 的信息段。

所以说两个事务T1并发T2运行并T1决定对block1. 因此,首先,在内存中T1读取并对其进行修改,当最终完成时,它决定提交;block1即实际上将这些内存中的更改写回block1. 所以我知道xmax它修改的先前条目被设置为id(T1),并且创建了一个新条目并xmin设置为id(T1)。现在我发现困难的是,当实际的提交过程发生时T1,比如说T2读取(而写入T1已经开始但尚未结束)。此案如何处理?

任何答案将不胜感激

SQL*_*tor 5

这就是 MVCC 的全部思想——多版本并发控制。

每当数据被修改时,同时有其他活动事务正在读取该数据,或者之前已读取该数据(取决于读取器事务的隔离级别),就会为这些事务保留一份预修改数据的副本,以免阻塞它们。该副本将保留到所有读者事务完成为止,以便他们可以看到一致的版本。

这是您使用 MVCC 所付出的代价,因为服务器需要维护相同数据的多个副本,而基于锁(悲观)的隔离仅使用一份数据副本,但会引入潜在的阻塞。没有免费餐点:-)

您可以在这里阅读有关它的所有详细信息https://www.postgresql.org/docs/11/mvcc.html

我还邀请您参加关于这个主题的pluralsight 课程,该课程通过现实生活中的示例深入讨论 MVCC 和隔离级别。个人可以获得1 个月的pluralsight 免费试用

  • 如果您了解 MVCC 实现的内部原理,我建议您购买或租用本文。https://dl.acm.org/itation.cfm?id=356842.356846。对于这个论坛来说太复杂了,老实说我不记得每个实现的所有位和字节。抱歉...这似乎也是一个有趣的资源,您可能会发现有用[TLDR] - https://momjian.us/main/writings/pgsql/mvcc.pdf (2认同)