REINDEX

Name

REINDEX -- 重建索引

Synopsis

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

描述

REINDEX使用索引的表里存储的数据重建一个索引, 并且替换该索引的旧拷贝。有一些场景需要使用REINDEX

参数

INDEX

重新创建指定的索引。

TABLE

重新创建指定表的所有索引。如果该表有一个二级 "TOAST"表,它也会被重索引。

DATABASE

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

SYSTEM

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

name

要被重索引的特定索引、表或者数据库的名字。索引和表名可以被 模式限定。当前,REINDEX DATABASEREINDEX SYSTEM只能重索引当前数据库,因此 它们的参数必须匹配当前数据库的名称。

FORCE

这是一个废弃的选项。如果指定会被忽略。

注解

如果怀疑一个用户表上的索引损坏,可以使用 REINDEX INDEX或者 REINDEX TABLE简单地重建该索引 或者表上的所有索引。

如果你需要从一个系统表上的索引损坏中恢复,就更困难一些。在 这种情况下,对系统来说重要的是没有使用过任何可疑的索引本身( 实际上,这种场景中,你可能会发现服务器进程会在启动时立刻崩溃, 这是因为对于损坏的索引的依赖)。要安全地恢复,服务器必须用 -P选项启动,这将阻止它使用索引来进行系统 目录查找。

这样做的一种方法是关闭服务器,并且启动一个单用户的 PostgreSQL服务器,在其命令行 中包括-P选项。然后,可以发出 REINDEX DATABASEREINDEX SYSTEMREINDEX TABLE或者REINDEX INDEX, 具体使用哪个命令取决于你想要重构多少东西。如果有疑问,可以使用 REINDEX SYSTEM来选择重建数据库中的所有系统索引。 然后退出单用户服务器会话并且重启常规的服务器。更多关于如何与 单用户服务器接口交互的内容请见postgres参考页。

在另一种方法中,可以开始一个常规的服务器会话,在其命令行选项 中包括-P。这样做的方法与客户端有关,但是在 所有基于libpq的客户端中都可以在开始客户端 之前设置PGOPTIONS环境变量为-P。 注意虽然这种方法不要求用锁排斥其他客户端,在修复完成之前避免 其他用户连接到受损的数据库才是更加明智的。

REINDEX类似于删除索引并且重建索引,在其中 索引内容会被从头开始建立。不过,锁定方面的考虑却相当不同。 REINDEX会用锁排斥写,但不会排斥在索引的父表上的读。 它也会在被处理的索引上取得一个排他锁,该锁将会阻塞对该索引的使用尝试。 相反,DROP INDEX 会暂时在附表上取得一个排他锁,阻塞 写和读。后续的CREATE INDEX会排斥写但不排斥读,由于 该索引不存在,所以不会有读取它的尝试,这意味着不会有阻塞但是读操作可能 被强制成昂贵的顺序扫描。

重索引单独一个索引或者表要求用户是该索引或表的拥有者。重索引一个 数据库要求用户是该数据库的拥有者(注意拥有者因此可以重建由其他 用户拥有的索引或者表)。当然,超级用户总是能够重索引任何东西。

示例

重建单个索引:

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命令。