REINDEX使用索引的表里存储的数据重建一个索引, 并且替换该索引的旧拷贝。有一些场景需要使用REINDEX:
一个索引已经损坏,并且不再包含合法数据。尽管理论上这不会发生, 实际上索引会因为软件缺陷或硬件失效损坏。 REINDEX提供了一种恢复方法。
一个索引变得"臃肿",其中包含很多空的或者近乎为空的页面。 PostgreSQL中的 B-树索引在特定的非 常规访问模式下可能会发生这种情况。REINDEX 提供了一种方法来减少索引的空间消耗,即制造一个新版本的索引,其中没有 死亡页面。详见Section 23.2。
修改了一个索引的存储参数(例如填充因子),并且希望确保这种修改完全 生效。
用CONCURRENTLY选项进行的一次索引创建失败,留下了 一个"无效的"索引。这类索引是没有用处的,但是可以用 REINDEX来重建它们。注意, REINDEX将不会执行一次并发构建。要构建该索引并且 不干扰生产,应该先删除索引并且重新发出 CREATE INDEX CONCURRENTLY命令。
重新创建指定的索引。
重新创建指定表的所有索引。如果该表有一个二级 "TOAST"表,它也会被重索引。
重新创建当前数据库内的所有索引。共享的系统目录上的索引也会被 处理。这种形式的REINDEX不能在一个 事务块内执行。
重新创建当前数据库中在系统目录上的所有索引。共享系统目录上的 索引也被包括在内。用户表上的索引则不会被处理。这种形式的 REINDEX不能在一个事务块内执行。
要被重索引的特定索引、表或者数据库的名字。索引和表名可以被 模式限定。当前,REINDEX DATABASE和 REINDEX SYSTEM只能重索引当前数据库,因此 它们的参数必须匹配当前数据库的名称。
这是一个废弃的选项。如果指定会被忽略。
如果怀疑一个用户表上的索引损坏,可以使用 REINDEX INDEX或者 REINDEX TABLE简单地重建该索引 或者表上的所有索引。
如果你需要从一个系统表上的索引损坏中恢复,就更困难一些。在 这种情况下,对系统来说重要的是没有使用过任何可疑的索引本身( 实际上,这种场景中,你可能会发现服务器进程会在启动时立刻崩溃, 这是因为对于损坏的索引的依赖)。要安全地恢复,服务器必须用 -P选项启动,这将阻止它使用索引来进行系统 目录查找。
这样做的一种方法是关闭服务器,并且启动一个单用户的 PostgreSQL服务器,在其命令行 中包括-P选项。然后,可以发出 REINDEX DATABASE、REINDEX SYSTEM、 REINDEX TABLE或者REINDEX INDEX, 具体使用哪个命令取决于你想要重构多少东西。如果有疑问,可以使用 REINDEX SYSTEM来选择重建数据库中的所有系统索引。 然后退出单用户服务器会话并且重启常规的服务器。更多关于如何与 单用户服务器接口交互的内容请见postgres参考页。
在另一种方法中,可以开始一个常规的服务器会话,在其命令行选项 中包括-P。这样做的方法与客户端有关,但是在 所有基于libpq的客户端中都可以在开始客户端 之前设置PGOPTIONS环境变量为-P。 注意虽然这种方法不要求用锁排斥其他客户端,在修复完成之前避免 其他用户连接到受损的数据库才是更加明智的。
REINDEX类似于删除索引并且重建索引,在其中 索引内容会被从头开始建立。不过,锁定方面的考虑却相当不同。 REINDEX会用锁排斥写,但不会排斥在索引的父表上的读。 它也会在被处理的索引上取得一个排他锁,该锁将会阻塞对该索引的使用尝试。 相反,DROP INDEX 会暂时在附表上取得一个排他锁,阻塞 写和读。后续的CREATE INDEX会排斥写但不排斥读,由于 该索引不存在,所以不会有读取它的尝试,这意味着不会有阻塞但是读操作可能 被强制成昂贵的顺序扫描。
重索引单独一个索引或者表要求用户是该索引或表的拥有者。重索引一个 数据库要求用户是该数据库的拥有者(注意拥有者因此可以重建由其他 用户拥有的索引或者表)。当然,超级用户总是能够重索引任何东西。