Postgresql

檢測 CREATE INDEX CONCURRENTLY 何時在 PostgreSQL 中完成

  • January 10, 2020

如果我在 PostgreSQL 中同時創建一個索引,我如何才能看到它何時完成?

我正在嘗試重建索引以解決索引膨脹問題,我需要將舊索引保留一段時間,直到新索引完成,所以我需要知道它什麼時候完成。

這是 PostgreSQL 9.2/3ish

結合@Rory 的評論和@Zaytsev Dmitry 的回答中的資訊:

CREATE INDEX CONCURRENTLY索引完成建構之前不會返回。所以你知道當你的查詢返回時索引已經完成。

但是,如果您正在建構一個大型索引,您可能想知道它是否“真的”仍在執行。

您可以將查詢用於“無效”索引:

SELECT * FROM pg_class, pg_index WHERE pg_index.indisvalid = false AND pg_index.indexrelid = pg_class.oid;

…如果您的索引出現在結果中,那麼它要麼失敗,要麼仍在進行中

確認後者的另一種方法是檢查 locks 表:

SELECT a.datname,
        l.relation::regclass,
        l.transactionid,
        l.mode,
        l.GRANTED,
        a.usename,
        a.query,
        a.query_start,
        age(now(), a.query_start) AS "age",
        a.pid
FROM pg_stat_activity a
JOIN pg_locks l ON l.pid = a.pid
WHERE mode = 'ShareUpdateExclusiveLock'
ORDER BY a.query_start;

儘管 CONCURRENTLY 不會對錶採取排他鎖,但它會持有較弱的鎖ShareUpdateExclusiveLock,您應該在此查詢的結果中看到這一點。

如果沒有鎖,則意味著索引已完成建構,或者創建失敗並留下無效索引。

因此,在這兩個查詢之間,您可以確定您的索引處於三種可能狀態(已完成/正在進行/失敗)中的哪一個。

您可以獲得無效索引的列表。

SELECT * FROM pg_class, pg_index WHERE pg_index.indisvalid = false AND pg_index.indexrelid = pg_class.oid;

如果您在此查詢中看到您的索引,則意味著該索引將不起作用,您必須重新創建索引。

不要做REINDEX。它不會同時重新創建索引,它會在創建索引時鎖定表以進行寫入,最好的解決方案是刪除無效索引並使用CONCURRENTLY標誌重新創建它

引用自:https://dba.stackexchange.com/questions/131945