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