REINDEX

Name

REINDEX -- 重建索引

Synopsis

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

描述

REINDEX 基於儲存在索引的資料表上的資料重建索引, 替換舊的索引拷貝。使用 REINDEX 有兩個主要原因:

參數

DATABASE

恢復一個聲明了的資料庫的所有系統索引。 不包含用戶資料表上的索引。同樣,除非在獨立執行模式下,也會忽略在共享系統資料表上的索引(見下文)。

TABLE

重新建立聲明的資料表的所有索引。如果資料表有個從屬的"TOAST"資料表,那麼這個資料表也會重新索引。

INDEX

重新建立聲明了的索引。

name

要重建的所聲明的資料庫,資料表或者索引的名稱。 資料表和索引名可以有模式修飾。 目前,REINDEX DATABASE 只能重建目前資料庫的索引, 因此其參數必須匹配目前資料庫的名字。

FORCE

這是一個廢棄的選項,如果聲明,會被忽略。

注意

如果您懷疑一個用戶資料表上的索引崩潰了,您可以簡單地重建該索引, 或者該資料表上地所有索引,使用 REINDEX INDEX 或者 REINDEX TABLE

如果您從一個崩潰的系統資料表索引上恢復,事情會更棘手一些。 這種情況下,系統必須不能使用任何有疑問的索引。 (實際上,在這種情況下,您可能發現伺服器進程在啟動之後馬上就崩潰了, 因為依賴於崩潰了的索引。)要想安全恢復,伺服器必須帶著 -P 選項啟動, 它禁止伺服器在查找系統資料表的時候使用索引。

這麼做個一個辦法事停止 postmaster 然後帶著 -P 命令行選項啟動一個獨立的 PostgreSQL 伺服器。 然後,根據您希望恢復的程度,可以發出 REINDEX DATABASEREINDEX TABLE,或者 REINDEX INDEX。 如果還有懷疑,使用 REINDEX DATABASE 選擇重新構造資料庫中全部的系統索引。 然後退出獨立伺服器會話並且重啟普通的伺服器。參閱 postgres 手冊頁獲取有關如何與獨立伺服器交互的訊息。

另外,一個普通的會話可以在其命令行選項裡帶著 -P 啟動。 這麼做的方法因不同的客戶端而異,但是在所有基於 libpq 的客戶端上, 我們都可以透過在啟動客戶端之前設置 PGOPTIONS 環境變量為 -P 來實現。 請注意儘管這個方法並不要求鎖住其它客戶端,但是禁止其它客戶端連接受損的資料庫, 直到完成修補應該事一個明智的選擇。

如果懷疑任何共享的系統資料表的索引損壞((pg_databasepg_grouppg_shadow 或者 pg_tablespace), 那麼必須用獨立伺服器的方式來修復它。REINDEX 不能在多用戶環境下處理共享系統資料表。

除了共享系統資料表之外的所有索引,REINDEX 是抗崩潰並且是交易安全的。 REINDEX 對於共享的索引而言不是抗崩潰的,這就是為什麼不允許在正常操作中這麼使用的原因。 如果在重新對一個共享資料表進行索引的時候發生了崩潰,那麼在糾正問題之前,就不可能重新啟動普通的伺服器。 (一個建立了一部分的共享索引的典型症狀是"index is not a btree/索引不是 btree 索引"錯誤。)

REINDEX 類似與刪除再重建索引,資料表現在它們都是從零開始重建。 不過,從鎖的角度考慮,兩者是有區別的。REINDEX 鎖住對索引的父資料表的寫操作, 但是不會鎖主讀操作。並且它還在被處理的特定索引上保持一個排他鎖, 這樣它將阻止試圖使用該索引的讀操作。相比之下,DROP INDEX 在父資料表上短暫的保持一個排他鎖,鎖住讀和寫操作。隨後的 CREATE INDEX 鎖住寫操作但是不會鎖住讀操作;因為索引還不存在,所以不會有試圖使用它的讀操作, 意味著操作中不會有阻塞,只不過讀操作會被迫只能使用順序掃瞄。 另外一個重要的環節是刪除/重建的方法讓所有使用索引的緩衝的查詢規劃都失效, 而 REINDEX 不會。

PostgreSQL 7.4 之前,REINDEX TABLE 並不自動處理 TOAST 資料表,因此這些資料表必須用獨立的命令進行處理。這麼做仍然可以,但是已經多餘了。

例子

重建資料表 mytable 上的索引:

REINDEX TABLE mytable;

重建單個索引:

REINDEX INDEX my_index;

重建一個資料庫上的所有系統索引,不管他們是否有效:

$ export PGOPTIONS="-P"
$ psql broken_db
...
broken_db=> REINDEX DATABASE broken_db;
broken_db=> \q

相容性

SQL92裡沒有 REINDEX