sql - Postgresql并发索引

标签 sql database postgresql

我试图了解 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_indexDefineIndex in src/backend/commands/indexcmds.c 调用,其中包含有关整个过程的详细信息。

关于sql - Postgresql并发索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18378710/

相关文章:

java - 将 JDateChooser 中的日期插入 Oracle DB

要格式化的 SQL 列

java - 如何从特定行检索数据 SQLiteAssetHelper

postgresql - Postgres : relation does not exist error when table exists on public schema

sql - 如果不是今天的日期,则条件查询返回时间戳,否则返回时间

SQL 查询 - 多列合并为一列

sql - 如何通过C-API运行SQLite3 'PRAGMA'命令?

java - 我如何摆脱 "MySQLSyntaxErrorException"

android - SQLite openOrCreateDatabase 未知错误(代码 14): Could not open database

ruby-on-rails - 使用 Rails 和 Postgres 时日期格式的数字