刷新物化视图:并发、事务行为

Posted

技术标签:

【中文标题】刷新物化视图:并发、事务行为【英文标题】:Refresh materialized views: Concurrency, transactional behaviour 【发布时间】:2013-09-19 15:02:46 【问题描述】:

REFRESH MATERIALIZED VIEW 上的 PostgreSQL 9.3 官方文档尚未详细描述。

引用此blog:

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

mailing list 中帖子的另一句话:

如果我理解正确,REFRESH MATERIALIZED VIEW 将锁定 具有 AccessExclusiveLock 的物化视图,即使该视图已经 包含数据。

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

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

【问题讨论】:

【参考方案1】:

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

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

它们背后的理念是将它们视为create table as ...的更智能变体:

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

就我阅读refresh materialized view 命令或我在它们上找到的文档而言,它们不会自动更新,我和你一样理解流程。

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

有什么方法可以知道刷新何时完成,我想在物化视图刷新完成后触发加入 面对REFRESH CONCURRENTLY 应该锁定会话(所以它不像问题所暗示的那样异步)。 CUNCURRENTLY 只是表示 table 没有被锁定。

以上是关于刷新物化视图:并发、事务行为的主要内容,如果未能解决你的问题,请参考以下文章

oracle物化视图不会自动更新是怎么回事

物化视图 - 识别最后一次刷新

如何获得oracle物化视图 定时刷新时 刷新所用的时间 或者是监控 物化视图在jobs中建立的job任务的执行时间

Oracle SQL 面试关于物化视图的问题?

红移物化视图刷新是不是会锁定基表?

Oracle设置物化视图的自动刷新