运行时:
REINDEX DATABASE CONCURRENTLY mydb;
Run Code Online (Sandbox Code Playgroud)
这可能需要几个小时,甚至几天,具体取决于数据库的大小,是否有办法粗略估计其进度?
我看到一些论坛帖子声称您可以使用如下查询来查询索引创建状态:
SELECT
now()::TIME(0),
a.query,
p.phase,
p.blocks_total,
p.blocks_done,
p.tuples_total,
p.tuples_done,
FROM pg_stat_progress_create_index p
JOIN pg_stat_activity a ON p.pid = a.pid;
Run Code Online (Sandbox Code Playgroud)
_done / _total 列与阶段相结合确实提供了粗略的进度百分比。但是,这仅列出当前更新索引的进度。它不会告诉您有多少其他索引正在等待更新,更不用说每个索引需要做多少工作了。
编辑:我尝试将 views 结合起来pg_index
,其中列出了*_ccnew
并发进程使用的临时索引,例如pg_stat_progress_create_index
:
SELECT relname,
CASE WHEN blocks_total > 0 THEN (ci.blocks_done/ci.blocks_total::numeric*100)::int ELSE NULL END as blocks_percent,
i.*
FROM pg_class as pgc
inner join pg_index as i on i.indexrelid = pgc.oid
left outer join pg_stat_progress_create_index as ci on ci.index_relid = i.indexrelid
WHERE i.indisvalid = false;
Run Code Online (Sandbox Code Playgroud)
但这显示了奇怪的结果。对于我的数据库,它在 pg_index 中列出了大约 300 个临时索引,等待更新。然而,pg_stat_progress_create_index 交叉引用的一个从未更新的索引被标记为有效。它处理了 100% 的块,然后消失,pg_stat_progress_create_index
但它indisvalid
仍然是错误的。为什么是这样?
Postgres 12 或更高版本具有系统视图pg_stat_progress_create_index
。
据报道...
每个正在运行的后端占一行
CREATE INDEX
或REINDEX
,显示当前进度。
详细信息请参见手册的CREATE INDEX 进度报告一章。
这在繁忙的服务器上可能非常昂贵!
REINDEX DATABASE CONCURRENTLY mydb;
Run Code Online (Sandbox Code Playgroud)
该手册有一章CREATE INDEX Phases描述了列的状态phase
。特别要考虑:
waiting for old snapshots
CREATE INDEX CONCURRENTLY
或者REINDEX CONCURRENTLY
正在等待可能看到该表的事务来释放其快照。当不处于并发模式时,将跳过此阶段。列lockers_total
,lockers_done
和current_locker_pid
包含此阶段的进度信息。
长时间运行的事务可能会阻碍进度。考虑REINDEX CONCURRENTLY
在选定的索引上运行。在REINDEX DATABASE
非工作时间,您可以专门锁定桌子。
如果您的服务器实际上并不繁忙,请使用以下命令检查长时间运行的事务:
SELECT * FROM pg_stat_activity;
Run Code Online (Sandbox Code Playgroud)
那些state = 'idle in transaction'
是主要的麻烦制造者(通常暗示编程错误,其中事务未提交或回滚)。这些可能会出现在pg_stat_progress_create_index.current_locker_pid
停滞的指数中。
有关的: