【问题标题】:How does Postgres atomically updates secondary indices?Postgres 如何以原子方式更新二级索引?
【发布时间】:2020-11-28 19:38:02
【问题描述】:

我了解当事务执行更改时,Postgres mvcc 方案会存储一个包含更新数据的新行以及相关版本。

其他事务知道他们应该看到哪些版本,然后选择适当的行。

我还了解到,表的主索引存储行的所有版本。 我可以看到如何更新主索引(您将其锁定以进行写入、追加行并解锁。我不确定它是否是这样工作的,但这是一种潜在的方式)。

但是 Postgres 是如何自动更新二级索引的呢? 我想当事务提交时,所有索引都需要使用行中的新数据进行更新。

Postgres 是否会锁定所有二级索引以自动更新它们? 如果有,锁的粒度是在索引级别还是在值级别(只锁定特定值的索引部分)?

其他数据库引擎(如 InnoDB)中的方法是否相同?

我正在构建一个玩具数据库,但我很难理解如何有效地更新二级索引。 也欢迎任何有关该主题的论文!

非常感谢!

【问题讨论】:

    标签: postgresql indexing mvcc


    【解决方案1】:

    PostgreSQL 不支持索引组织表。所以所有的索引都是二级索引。

    索引不会自动更新。在索引中看到有趣条目的进程将把它追到表中。在表中,它看到该元组尚未提交,因此忽略它。系统安排给用户一种原子性的体验,但在索引操作的层面上并没有真正的原子性。

    【讨论】:

    • 仅索引扫描怎么样?索引不需要为那些存储交易ID吗?
    • 对于 IOS,它会参考每页一个位的可见性映射,说明相应页面上的所有元组是否可见。 (最近的版本每页有第二个位用于另一个目的)这就是为什么清理对于有效的 IOS 如此重要。
    • 非常感谢!所以,如果我理解正确的话,一旦行数据被更新,一个条目就会被添加到所有索引中。此时的索引仍将忽略该行,因为它未标记为已提交。一旦该行被标记为已提交,所有通过索引的查询都将开始显示该行。那正确吗?不应该看到新元组的旧事务如何访问索引?它会去元组检查版本吗?此外,清理很重要,因为它会删除旧行并压缩有效行,因此页位更有可能是真的?
    • 忽略行的不是索引,而是查询索引的过程。如果它发现要提交的行但最近无法对其快照可见,那么它也会忽略该行。我认为吸尘是将可见性位设置为 true 的唯一过程。 (理论上,其他一些过程有时可以做到,但我认为他们永远不会做到)
    猜你喜欢
    • 1970-01-01
    • 2016-06-07
    • 2014-12-06
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多