10

PostgreSQL 9.3 的官方文档REFRESH MATERIALIZED VIEW还没有详细描述它。

此博客的引述:

Postgres 9.3 中的物化视图有一个严重的限制,即在刷新时使用排他锁。这基本上阻止了在使用来自其父关系的新数据进行刷新时读取物化视图的任何尝试

邮件列表中帖子的另一句话:

如果我理解正确,即使视图已经包含数据,REFRESH MATERIALIZED VIEW 也会使用 AccessExclusiveLock 锁定物化视图。

我的问题:以下顺序是否正确:

  1. 查询正在访问物化视图
  2. 一个作业执行REFRESH MATERIALIZED VIEW。它在视图上加锁,并等待所有使用 matview 运行的查询都完成
  3. matview 正在开始刷新;如果 matview 上有索引,它会同时更新(因此完全刷新发生在一个事务中)
  4. 使用 matview 的查询正在等待刷新完成。如果这花费的时间太长,则会出现“等待锁定超时错误”之类的东西。
  5. 刷新完成,解除锁定
  6. 一直在等待matview的查询继续
4

2 回答 2

10

在 Postgres 9.4 发布时,情况并非完全如此。您现在可以使用该REFRESH MATERIALIZED VIEW CONCURRENTLY命令同时刷新实体化视图。从功能上讲,这会刷新视图,但在没有读锁的情况下这样做。就计算而言,这是一个更昂贵的操作,但如果锁对你来说是个问题(就像对我来说,这让我走上了这条路),那么这不是一个糟糕的方法。

以下是发行说明中的​​更多信息:https ://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.4#REFRESH_MATERIALIZED_VIEW_CONCURRENTLY

于 2015-07-17T16:38:39.050 回答
4

用一粒盐来回答,因为我还没有玩过垫子视图,但基于此:

http://www.postgresql.org/docs/current/static/sql-creatematerializedview.html

它们背后的理念是将它们视为更聪明的变体create table as ...

CREATE MATERIALIZED VIEW 与 CREATE TABLE AS 类似,不同之处在于它还记住了用于初始化视图的查询,以便以后可以根据需要对其进行刷新。物化视图具有许多与表相同的属性,但不支持临时物化视图或自动生成 OID。

就我阅读refresh materialized view命令或在它们上找到的文档而言,它们不会自动更新,我以与您相同的方式理解流程。

我想,排他锁来自这样一个事实,即您不能轻易知道(除了在琐碎的情况下)哪些行是脏的,哪些不是。如果开发人员确定了一种有效的方法,物化视图可能会自动并同时更新。

于 2013-09-15T21:44:17.280 回答