我试图了解 PostgreSQL 如何构建索引 concurrently没有写锁。
有人可以描述 PostgreSQL 在连续写入表数据时执行此操作的步骤吗?
最佳答案
相关细节在源码注释中。请参阅the comments on validate_index
in src/backend/catalog/index.c
around line 2607 :
We do a concurrent index build by first inserting the catalog entry for the index via index_create(), marking it not indisready and not indisvalid. Then we commit our transaction and start a new one, then we wait for all transactions that could have been modifying the table to terminate.
...还有很多很多。基本上“这很复杂”。我会尝试解释它,但我还没有详细阅读代码,也不知道代码库的这一部分,所以唯一正确的解释是注释和源代码。
我的理解是,它基于表状态的 MVCC 快照进行初始构建,并在完成后提交。然后,它会等待,直到所有事务都可以看到(损坏的)索引,此时当它们更改表中的内容时,它们都会更新它。然后,它将构建索引时可见的内容与现在可见的内容进行比较,并更新索引以反射(reflect)快照之间的差异。然后,它会等待以确保没有事务可以在索引处于无效状态时看到该索引,将索引标记为有效,然后再次提交。
整个过程严重依赖 MVCC 快照和可见性。在 I/O、CPU 和 RAM 方面,它也比常规索引构建要昂贵得多。
validate_index
由 DefineIndex
in src/backend/commands/indexcmds.c 调用,其中包含有关整个过程的详细信息。
关于sql - Postgresql并发索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18378710/