【发布时间】:2020-02-23 11:57:30
【问题描述】:
PostgreSQL使用MVCC技术进行数据库并发控制,每次写入创建一个item的新版本,然后通过可见性规则访问那个版本。问题是btree索引是如何实现多版本控制的?当新增btree节点时并且树被分裂,原来的btree结构将被改变。这个时候,PGSQL是怎么处理的?谁能告诉我?
【问题讨论】:
标签: postgresql b-tree
PostgreSQL使用MVCC技术进行数据库并发控制,每次写入创建一个item的新版本,然后通过可见性规则访问那个版本。问题是btree索引是如何实现多版本控制的?当新增btree节点时并且树被分裂,原来的btree结构将被改变。这个时候,PGSQL是怎么处理的?谁能告诉我?
【问题讨论】:
标签: postgresql b-tree
在 PostgreSQL 中,索引不实现 MVCC。索引包含任何人可能感兴趣的每一行,从插入但尚未提交的行到完全过时但尚未清除的行。您必须访问表本身以查看该行是否对您感兴趣。
对此有一些优化。在仅索引扫描中,您有时可以查阅表的可见性映射,而不是表本身的主要部分。此外,如果查询在索引中查找一行,然后转到表并发现该行对于所有用途都已过时,则当它返回索引时,它可以在索引中将其标记为已死,因此以后的查询不需要访问表。
当添加新的btree节点并分裂树时,原来的btree结构会改变。这个时候,PGSQL是怎么处理的?谁能告诉我?
我不认为这真的是一个堆栈溢出类型的问题。所有细节的最佳参考是源代码和源 cmets。也许您只是想知道如果事务回滚会发生什么。页面拆分仍然存在,并且插入的元组一直保留在那里,直到真空将其移除(此时页面拆分仍然存在)。
在崩溃的情况下,描述分裂的 WAL 记录要么被播放,要么不被播放。由于在描述拆分的 WAL 记录被刷新到磁盘之前无法写出被拆分弄脏的页面(在此之前它们被保护在 shared_buffers 中),因此无论哪种方式,系统都将处于一致状态。
【讨论】: