↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

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 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0
历史版本PostgreSQL 8.4 已于 2014 年 7 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

REINDEX

REINDEX — 重建索引

大纲

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 DATABASE和 REINDEX SYSTEM只能对当前数据库重新索引,所以其参数必须与当前数据库名匹配。

FORCE

这是一个已废弃的选项;如果指定了它,它会被忽略。

注解

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

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

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

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

如果怀疑任何共享系统目录(即pg_authid、 pg_auth_members、pg_database、 pg_pltemplate、pg_shdepend、 pg_shdescription和pg_tablespace) 上的索引已经损坏,则必须使用独立服务器来修复。REINDEX在多用户模式下不会处理共享目录。

对于除共享系统目录之外的所有索引,REINDEX都是崩溃安全且事务安全的。REINDEX对共享索引并不崩溃安全,这正是正常操作期间不允许这种情况的原因。如果在独立模式下重建这类目录之一时发生故障,在问题得到纠正之前,将无法重新启动常规服务器。(部分重建的共享索引的典型症状是“index is not a btree”错误。)

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

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

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

在PostgreSQL 7.4 之前,REINDEX TABLE不会自动处理 TOAST 表,因此那时需要用单独的命令对 TOAST 表 重新索引。现在仍然可以这样做,但已是多余的。

示例

重建单个索引:

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 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。