选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.0 已于 2015 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

REINDEX

REINDEX — rebuild indexes

大纲

REINDEX { INDEX | TABLE | DATABASE | SYSTEM } name [ FORCE ]

描述

REINDEX使用索引所属表中存储的数据重建索引, 并替换索引的旧副本。以下几种场景适合使用REINDEX

  • 一个索引已经损坏,不再包含有效数据。尽管理论上这不该发生, 但在实践中索引可能因软件缺陷或硬件故障而损坏。 REINDEX提供了一种恢复方法。

  • 一个索引已经膨胀,也就是说其中包含许多空页或几乎为空 的页。在 PostgreSQL 中,B-树索引在某些不常见 的访问模式下可能出现这种情况。REINDEX可通过写入一个 不含死页的新版本索引来减少索引的空间消耗。详见第 23.2 节

  • 你修改了某个索引的存储参数(例如 fillfactor),并希望确保该更改已经 完全生效。

  • 使用 CONCURRENTLY 选项构建索引失败后,会留下一个无效索引。这类索引没有用处,但用 REINDEX 重建它们可能很方便。注意,REINDEX 不会进行并发构建。要在不干扰生产运行的情况下构建索引,应删除该索引并重新执行 CREATE INDEX CONCURRENTLY 命令。

参数

INDEX

重新创建指定的索引。

TABLE

重新创建指定表的所有索引。如果该表有一个辅助TOAST表,也会对其重新索引。

DATABASE

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

SYSTEM

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

name

要重新索引的特定索引、表或数据库的名称。索引名和表名可以带模式限 定。目前,REINDEX DATABASEREINDEX SYSTEM只能对当前数据库重新索引,所以其参数必须与当前数据库名匹配。

FORCE

在每个索引被重建时打印进度报告。

注解

如果怀疑某个用户表上的索引已经损坏,可以使用 REINDEX INDEXREINDEX TABLE 直接重建该索引,或者重建该表上的所有索引。

如果需要从系统表上的索引损坏中恢复,情况就更复杂了。在这种情况下, 重要的是系统本身没有使用任何可疑索引。(事实上,在这种场景下,你可 能会发现服务器进程在启动时立即崩溃,因为它依赖损坏的索引。)要安 全恢复,必须用-P选项启动服务器,该选项会阻止服务器 在查找系统目录时使用索引。

一种做法是关闭服务器,并在命令行中包含-P选项来启 动单用户 PostgreSQL 服务器。然后可以根据 希望重建的范围,执行REINDEX DATABASEREINDEX SYSTEMREINDEX TABLEREINDEX INDEX。如果拿不准,就使用 REINDEX SYSTEM来重建该数据库中的所有系统索引。然 后退出单用户服务器会话并重新启动常规服务器。关于如何与单用户服务器接 口交互的更多信息,参见postgres参考页。

另一种方法是启动一个常规服务器会话,并在其命令行选项中包含 -P。具体做法因客户端而异,但对于所有基于 libpq的客户端,都可以在启动客户端之前将环 境变量PGOPTIONS设置为-P。注意,尽 管这种方法不需要阻止其他客户端,但在修复完成之前,阻止其他用户连接到 受损数据库可能仍然更稳妥。

REINDEX类似于删除并重新创建索引,因为索引内容都是 从头重建的。不过,两者在锁方面的考量相当不同。 REINDEX会阻止该索引所属表上的写入,但不阻止读取。它 还会对正在处理的特定索引获取独占锁, 从而阻塞试图使用该索引的读取。相比之下, DROP INDEX会短暂地对父表获取独占锁,同时阻塞写入和读取。随后的 CREATE INDEX会阻止写入但不阻止读取;由于索引不存 在,读取不会尝试使用它,因此不会发生阻塞,但读取可能被迫使用代价高昂 的顺序扫描。

对单个索引或表重新索引,要求用户是该索引或表的拥有者。对数据库重新索引,则要求用户是该数据库的拥有者(因此,拥有者可以重建其他用户所拥有表的索引)。当然,超级用户始终可以重新索引任何对象。

PostgreSQL 8.1 之前,REINDEX DATABASE只处理系统索引,而不是像其名字所暗示的那样处理所有索引。这一行为已被更改,以减少出人意料的因素。旧的行为可以通过REINDEX SYSTEM使用。

重建表my_table上的所有索引: REINDEX TABLE my_table;

示例

重建单个索引:

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

兼容性

在 SQL 标准中没有REINDEX命令。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。