REINDEX
REINDEX — 重建索引
大纲
REINDEX { DATABASE | TABLE | INDEX } name [ FORCE ]描述
REINDEX根据表中存储的数据重建一个索引,替换索引的旧副本。使用REINDEX的主要原因有两个:
一个索引已经损坏,不再包含有效数据。尽管理论上这不应该发生,但在实践中,索引可能因软件缺陷或硬件故障而损坏。
REINDEX提供了一种恢复方法。该索引包含大量未被回收的死索引页。在 PostgreSQL中,B-tree 索引在某些访问模式下可能出现这种情况。
REINDEX提供了一种通过写入不含死页的新版本索引来减少索引空间占用的方法。更多信息见第 21.2 节。
参数
DATABASE重建指定数据库的所有系统索引。用户表上的索引不被处理。此外,共享系统目录上的索引也会被跳过(独立模式除外,见下文)。
TABLE重建指定表的所有索引。如果该表有次级“TOAST”表,该表也会被重建索引。
INDEX重建一个指定的索引。
name要重建索引的特定数据库、表或索引的名称。表名和索引名可以是模式限定的。
FORCE这是一个已废弃的选项;如果指定它将被忽略。
注解
如果你怀疑用户表上的某个索引损坏了,可以简单地用
REINDEX INDEX或REINDEX
TABLE重建该索引或该表的所有索引。处理损坏的用户表索引的另一种方法就是删除并重新创建它。如果你希望在此期间维持表面上正常的表操作,这实际上可能更可取。REINDEX获取表的排他锁,而CREATE
INDEX只锁定表的写而不锁定读。
如果你需要从系统表索引的损坏中恢复,事情就更困难了。在这种情况下,重要的是系统自身没有使用过任何可疑的索引。(事实上,在这种场景下你可能会发现服务器进程在启动时立即崩溃,因为依赖了损坏的索引。)要安全地恢复,服务器必须以
-P选项启动,该选项阻止它在系统目录查找中使用索引。
做到这一点的一种方法是关闭 postmaster,然后启动一个独立的
PostgreSQL服务器,并在其命令行中包含-P选项。然后可以根据你想重建多少,发出REINDEX DATABASE、REINDEX TABLE或REINDEX INDEX。如果不确定,使用REINDEX DATABASE来选择重建该数据库的所有系统索引。然后退出独立服务器会话并重启常规服务器。关于如何与独立服务器界面交互的更多信息,见postgres参考页。
或者,可以在常规服务器会话的命令行选项中包含
-P来启动它。具体的做法因客户端而异,但在所有基于libpq的客户端中,都可以在启动客户端之前把PGOPTIONS环境变量设置为-P。注意,虽然这种方法不需要锁定其他客户端,但在修复完成之前,阻止其他用户连接到受损的数据库可能仍是明智的。
如果怀疑任何共享系统目录(pg_database、pg_group或
pg_shadow)的索引损坏,则必须使用独立服务器来修复。REINDEX在多用户模式下不处理共享目录。
对于除共享系统目录之外的所有索引,REINDEX是崩溃安全且事务安全的。REINDEX对共享索引不是崩溃安全的,这就是正常操作期间禁止这种情况的原因。如果在独立模式下重建这些目录之一时发生故障,在问题得到纠正之前将无法重启常规服务器。(部分重建的共享索引的典型症状是“index
is not a btree”错误。)
在PostgreSQL 7.4 之前,REINDEX
TABLE不会自动处理 TOAST 表,因此必须用单独的命令重建这些表的索引。现在仍然可以这样做,但已是多余的。
示例
重建表my_table上的索引:
REINDEX TABLE my_table;
重建单个索引:
REINDEX INDEX my_index;
重建特定数据库中的所有系统索引,不信任它们已经是有效的:
$export PGOPTIONS="-P"$psql broken_db... broken_db=> REINDEX DATABASE broken_db; broken_db=> \q
兼容性
SQL 标准中没有REINDEX命令。