REINDEX

REINDEX —重建索引

Synopsis

REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } name

Description

REINDEX使用存储在索引表中的数据重建索引,替换索引的旧副本。在几种情况下可以使用REINDEX

  • 索引已损坏,并且不再包含有效数据。尽管从理论上讲这永远不会发生,但实际上索引可能由于软件错误或硬件故障而损坏。 REINDEX提供了一种恢复方法。

  • 索引已变得“膨胀”,即它包含许多空页面或近空页面。在某些不常见的访问模式下,PostgreSQL 中的 B 树索引可能会发生这种情况。 REINDEX提供了一种方法,可通过编写没有死页的新版本索引来减少索引的空间消耗。有关更多信息,请参见Section 24.2

  • 您已更改了索引的存储参数(例如 fillfactor),并希望确保所做的更改已完全生效。

  • 使用CONCURRENTLY选项构建索引失败,留下“无效”索引。这样的索引是没有用的,但是使用REINDEX重建它们会很方便。请注意,REINDEX将不会执行并发构建。要构建索引而不干扰生产,您应该删除索引并重新发出CREATE INDEX CONCURRENTLY命令。

Parameters

  • INDEX

    • 重新创建指定的索引。
  • TABLE

    • 重新创建指定表的所有索引。如果该表具有辅助“ TOAST”表,则该表也将重新编制索引。
  • SCHEMA

    • 重新创建指定架构的所有索引。如果此架构的表具有辅助“ TOAST”表,则该表也将重新编制索引。共享系统目录上的索引也将被处理。 REINDEX的这种形式不能在事务块内执行。
  • DATABASE

    • 重新创建当前数据库中的所有索引。共享系统目录上的索引也将被处理。 REINDEX的这种形式不能在事务块内执行。
  • SYSTEM

    • 在当前数据库内的系统目录上重新创建所有索引。包括共享系统目录上的索引。用户表上的索引未处理。 REINDEX的这种形式不能在事务块内执行。
  • name

    • 要重新构建索引的特定索引,表或数据库的名称。索引和表名可以是模式限定的。当前,REINDEX DATABASEREINDEX SYSTEM只能重新索引当前数据库,因此它们的参数必须与当前数据库的名称匹配。
  • VERBOSE

    • 在重新索引每个索引时打印进度报告。

Notes

如果您怀疑用户表上的索引损坏,则可以使用REINDEX INDEXREINDEX TABLE来重建该索引或表上的所有索引。

如果需要从系统表上的索引损坏中恢复,事情会变得更加困难。在这种情况下,重要的是系统不要使用任何可疑索引本身。 (实际上,在这种情况下,您可能会发现服务器进程由于依赖于损坏的索引而在启动时立即崩溃.)为了安全地恢复,必须使用-P选项启动服务器,以防止其使用系统目录查找的索引。

一种方法是关闭服务器,并使用命令行中包含的-P选项启动单用户 PostgreSQL 服务器。然后,可以发出REINDEX DATABASEREINDEX SYSTEMREINDEX TABLEREINDEX INDEX,这取决于您要重构多少。如有疑问,请使用REINDEX SYSTEM选择重建数据库中所有系统索引。然后退出单用户服务器会话并重新启动常规服务器。有关如何与单用户服务器界面进行交互的更多信息,请参见postgres参考页。

或者,可以使用其命令行选项中包含的-P来启动常规服务器会话。这样做的方法因 Client 端而异,但是在所有基于 libpq 的 Client 端中,可以在启动 Client 端之前将PGOPTIONS环境变量设置为-P。请注意,尽管此方法不需要锁定其他 Client 端,但在完成修复之前,防止其他用户连接到损坏的数据库可能仍然是明智的选择。

REINDEX与删除索引和重新创建索引相似,因为索引内容是从头开始重建的。但是,锁定注意事项却大不相同。 REINDEX锁定对索引的父表的写入但不对其进行读取。它还对正在处理的特定索引采取排他锁,这将阻止尝试使用该索引的读取。相反,DROP INDEX暂时在父表上获得排他锁,同时阻止写入和读取。随后的CREATE INDEX锁定写但不读;由于索引不存在,因此不会进行任何读取尝试,这意味着不会有阻塞,但可能会将读取强制进行昂贵的 Sequences 扫描。

重新索引单个索引或表要求是该索引或表的所有者。重新索引数据库需要成为数据库的所有者(请注意,所有者可以因此重建其他用户拥有的表的索引)。当然,超级用户可以随时重新索引任何内容。

Examples

重建一个索引:

REINDEX INDEX my_index;

重建表my_table上的所有索引:

REINDEX TABLE my_table;

在不信任系统索引已经有效的情况下,重建特定数据库中的所有索引:

$ export PGOPTIONS="-P"
$ psql broken_db
...
broken_db=> REINDEX DATABASE broken_db;
broken_db=> \q

Compatibility

SQL 标准中没有REINDEX命令。