2

我试图了解 PostgreSQL 如何在没有写锁的情况下同时构建索引。

有人可以描述 PostgreSQL 在不断写入表数据的同时执行此操作的步骤吗?

4

1 回答 1

2

相关细节在源代码注释中。请参阅第2607 行附近评论validate_indexsrc/backend/catalog/index.c

我们通过首先通过 index_create() 插入索引的目录条目来进行并发索引构建,将其标记为不是 indisready 并且不是 indisvalid。然后我们提交我们的事务并开始一个新的事务,然后我们等待所有可能正在修改表的事务终止。

....还有很多很多。基本上“这很复杂”。我会尝试解释一下,但是我没有详细阅读代码,也不知道这部分代码库,所以唯一正确的解释是注释和源代码。

我的理解是,它基于表状态的 MVCC 快照进行初始构建,并在完成后提交。然后它会等到所有事务都可以看到(损坏的)索引,此时它们都会在更改表中的内容时更新它。然后,它将建立索引时可见的内容与现在可见的内容进行比较,并更新索引以反映快照之间的差异。然后它等待以确保在索引处于无效状态时没有可以看到索引的事务,将索引标记为有效,然后再次提交。

整个过程在很大程度上依赖于 MVCC 快照和可见性。它在 I/O、CPU 和 RAM 方面也常规索引构建要贵得多。

validate_indexDefineIndex在 src/backend/commands/indexcmds.c中调用,其中包含有关整个过程的详细信息。

于 2013-08-22T12:55:13.880 回答