【问题标题】:How does the btree index of PostgreSQL achieve multi-version concurrency control?PostgreSQL的btree索引是如何实现多版本并发控制的?
【发布时间】:2020-02-23 11:57:30
【问题描述】:

PostgreSQL使用MVCC技术进行数据库并发控制,每次写入创建一个item的新版本,然后通过可见性规则访问那个版本。问题是btree索引是如何实现多版本控制的?当新增btree节点时并且树被分裂,原来的btree结构将被改变。这个时候,PGSQL是怎么处理的?谁能告诉我?

【问题讨论】:

    标签: postgresql b-tree


    【解决方案1】:

    在 PostgreSQL 中,索引不实现 MVCC。索引包含任何人可能感兴趣的每一行,从插入但尚未提交的行到完全过时但尚未清除的行。您必须访问表本身以查看该行是否对您感兴趣。

    对此有一些优化。在仅索引扫描中,您有时可以查阅表的可见性映射,而不是表本身的主要部分。此外,如果查询在索引中查找一行,然后转到表并发现该行对于所有用途都已过时,则当它返回索引时,它可以在索引中将其标记为已死,因此以后的查询不需要访问表。

    当添加新的btree节点并分裂树时,原来的btree结构会改变。这个时候,PGSQL是怎么处理的?谁能告诉我?

    我不认为这真的是一个堆栈溢出类型的问题。所有细节的最佳参考是源代码和源 cmets。也许您只是想知道如果事务回滚会发生什么。页面拆分仍然存在,并且插入的元组一直保留在那里,直到真空将其移除(此时页面拆分仍然存在)。

    在崩溃的情况下,描述分裂的 WAL 记录要么被播放,要么不被播放。由于在描述拆分的 WAL 记录被刷新到磁盘之前无法写出被拆分弄脏的页面(在此之前它们被保护在 shared_buffers 中),因此无论哪种方式,系统都将处于一致状态。

    【讨论】:

    • 谢谢你的回答,也就是说索引在访问的时候需要有一个可见性映射表才能获取哪些元祖先是可见的,但是我对清理还是不太了解和索引上的可见性细节,有没有什么文章或者博客可以介绍这方面的细节?
    • 不要乱扔诸如“元祖先”之类的未定义术语——你想理解,而不是留下深刻印象。 Jeff 解释得很好:索引不关心可见性。如果您想知道是否可以看到索引条目,则必须在表中查找引用的行版本(除非您可以使用提到的快捷方式)。
    猜你喜欢
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2022-01-14
    • 2020-11-28
    • 2011-03-12
    • 2011-05-10
    相关资源
    最近更新 更多