检查物化视图的上次刷新时间

spi*_*ike 17 postgresql materialized-views

我有一个物化视图,price_changes用于某些报告.我也有一个cron工作用刷新物化视图refresh materialized view price_changes.一切都很好.

我想让用户在报告中看到一条消息"数据从X开始是新鲜的".当cron运行时,我可以将它存储在某个地方,但是postgres是否已经在某处存储了这些元数据?

rsn*_*n86 17

WITH
        pgdata AS (
                SELECT
                        setting AS path
                FROM
                        pg_settings
                WHERE
                        name = 'data_directory'
        ),
        path AS (
                SELECT
                        CASE
                                WHEN pgdata.separator = '/' THEN '/'    -- UNIX
                                ELSE '\'                                -- WINDOWS
                        END AS separator
                FROM 
                        (SELECT SUBSTR(path, 1, 1) AS separator FROM pgdata) AS pgdata
        )
SELECT
        ns.nspname||'.'||c.relname AS mview,
        (pg_stat_file(pgdata.path||path.separator||pg_relation_filepath(ns.nspname||'.'||c.relname))).modification AS refresh
FROM
        pgdata,
        path,
        pg_class c
JOIN
        pg_namespace ns ON c.relnamespace=ns.oid
WHERE
        c.relkind='m'
;
Run Code Online (Sandbox Code Playgroud)


tha*_*mes 13

我不认为系统中有任何内置的功能,从9.3.4开始提供此功能.当我需要提供上次刷新的日期时,我在物化视图中的select查询中添加了一个名为"last_refresh"的列,因为物化视图中的数据在刷新之前不会更改.

出于安全原因,我也更喜欢这个,因为如果信息存储在那里,你可能不想让sql用户访问系统表.

根据您是否需要时间,您可以使用以下任一方法:

  1. CURRENT_DATE
  2. now()

就在日期:

CREATE MATERIALIZED VIEW mv_address AS 
SELECT *, CURRENT_DATE AS last_refresh FROM address;
Run Code Online (Sandbox Code Playgroud)

随着日期和时间:

CREATE MATERIALIZED VIEW mv_address AS 
SELECT *, now() AS last_refresh FROM address;
Run Code Online (Sandbox Code Playgroud)

更新2017-02-17:

PostgreSQL版本9.4+现在包括CONCURRENTLY选项.如果您使用REFRESH MATERIALIZED VIEW CONCURRENTLY选项,请注意评论中指示的@Smudge.这对于大型且经常更新的数据集来说实际上只是一个问题.如果您的数据集很小或不经常更新,那么您应该没问题.

  • 从现实世界的经验来看 - 这个问题Smudge指的是非常容易的雪球,直到你的数据库花费100%的时间来处理死亡元组的大山并且直到你DROP并重新创建物化视图才能恢复.请谨慎使用此解决方案. (14认同)
  • 抬头:这种方法每次都会导致"REFRESH MATERIALIZED VIEW CONCURRENTLY"更新每一行.对于不经常刷新的较小数据集,这不是一个大问题,但是对于大量数据和/或频繁更新,"DELETE"和"INSERT"的速率可能超过autovacuum守护程序对表的"VACUUM"的能力,导致基本的查询性能急剧下降. (13认同)

ric*_*yen 11

由于物化视图是存储在磁盘上的数据片段,因此它们在文件系统中将有一个相应的文件。当您调用 时REFRESH MATERIALIZED VIEW,磁盘上的数据将以新文件名重新创建。relfilenode因此,您可以通过交叉引用in来查找视图的修改/创建时间戳pg_class

[user@server /]# psql -c "create materialized view myview as select aid from pgbench_accounts where aid < 100"
SELECT 99
[user@server /]# psql -c "select relfilenode from pg_class where relname = 'myview'"
 relfilenode 
-------------
       16445
(1 row)

[user@server /]# ls -l /var/lib/edb/as12/data/base/15369/16445
-rw------- 1 enterprisedb enterprisedb 8192 Jun 14 23:28 /var/lib/edb/as12/data/base/15369/16445
[user@server /]# date
Mon Jun 14 23:29:16 UTC 2021
[user@server /]# psql -c "refresh materialized view myview"
REFRESH MATERIALIZED VIEW
[user@server /]# psql -c "select relfilenode from pg_class where relname = 'myview'"
 relfilenode 
-------------
       16449
(1 row)

[user@server /]# ls -l /var/lib/edb/as12/data/base/15369/16449
-rw------- 1 enterprisedb enterprisedb 8192 Jun 14 23:29 /var/lib/edb/as12/data/base/15369/16449
[user@server /]# 
Run Code Online (Sandbox Code Playgroud)

  • 哇,七年后的答案真是太棒了! (3认同)