监控PostgreSQL索引构建进度

mya*_*hya 57 postgresql index

有没有办法监控在 PostgreSQL 中创建索引的进度。我正在一个大表上创建一个索引,我想看看这发生的速度有多快。

有没有办法监控这个?

小智 32

根据Postgres Wiki 的索引维护页面,您可以通过以下方式了解所有索引的当前状态:

SELECT
  t.tablename,
  indexname,
  c.reltuples AS num_rows,
  pg_size_pretty(pg_relation_size(quote_ident(t.tablename)::text)) AS table_size,
  pg_size_pretty(pg_relation_size(quote_ident(indexrelname)::text)) AS index_size,
  CASE WHEN indisunique THEN 'Y'
    ELSE 'N'
  END AS UNIQUE,
  idx_scan AS number_of_scans,
  idx_tup_read AS tuples_read,
  idx_tup_fetch AS tuples_fetched
FROM pg_tables t
  LEFT OUTER JOIN pg_class c ON t.tablename=c.relname
  LEFT OUTER JOIN
    ( SELECT c.relname AS ctablename, ipg.relname AS indexname, x.indnatts AS number_of_columns, idx_scan, idx_tup_read, idx_tup_fetch, indexrelname, indisunique FROM pg_index x
      JOIN pg_class c ON c.oid = x.indrelid
      JOIN pg_class ipg ON ipg.oid = x.indexrelid
      JOIN pg_stat_all_indexes psai ON x.indexrelid = psai.indexrelid )
    AS foo
  ON t.tablename = foo.ctablename
WHERE t.schemaname='public'
ORDER BY 1,2;
Run Code Online (Sandbox Code Playgroud)

该列num_rows指示您的索引覆盖了多少行,index_size并将随着索引的构建而增长。

  • 我怀疑这可能不适用于 _new_ 索引,在提交创建它的事务之前,它可能在目录中不可见。 (13认同)
  • 这不是一个非常有用的查询。它既不会告诉您索引当前是否正在重建,也不会告诉您是否需要重建。它只是告诉你有多少个索引,这不是 Op 所要求的。 (4认同)
  • @mustaccio你是对的。我正在创建一个需要很长时间的索引,并且上面的命令仅显示已经创建的索引;它不会显示“CREATE INDEX”仍在进行中的索引。 (2认同)
  • REINDEX TABLE 会阻止此查询。至少,当我在 9.6 上运行它时是这样。 (2认同)

Env*_*vek 26

自 PostgreSQL 12 版本(2019 年 10 月 3 日发布)以来,这是可能的。

SELECT 
  now()::TIME(0), 
  a.query, 
  p.phase, 
  p.blocks_total, 
  p.blocks_done, 
  p.tuples_total, 
  p.tuples_done,
  ai.schemaname,
  ai.relname,
  ai.indexrelname
FROM pg_stat_progress_create_index p 
JOIN pg_stat_activity a ON p.pid = a.pid
LEFT JOIN pg_stat_all_indexes ai on ai.relid = p.relid AND ai.indexrelid = p.index_relid;
Run Code Online (Sandbox Code Playgroud)

这可用于检查哪个索引正在根据REINDEX DATABASE命令重建。

有关详细信息,请参阅pg_stat_progress_create_index 视图的文档depesz 的博客文章


xzi*_*lla 12

因此,在Postgres 12 之前没有好的方法可以做到这一点,但是如果您真的需要知道......首先根据数据大小 * 行 + 开销计算索引应该占用的空间量。然后,您可以使用 pfiles 或 pgtruss 之类的东西来查找正在写入 $PGDATA 中的文件;如果您的索引超过 1GB,它将是一系列文件,例如 nnnnn.n,其中第一组 n 是一致的,并且每个 GB 文件的最后 n 组递增。一旦您知道创建了多少文件,您就可以观察增长情况并确定您离完成还有多远。粗略估计,但也许有帮助。


ara*_*nid 5

不,没有,即使您在并发模式下构建它。尽管过去我一直关注数据库目录中文件的大小,但这并不是很有用,因为您只能猜测它有多大。