fff*_*abs 15 postgresql materialized-view plpgsql
根据文档:
CONCURRENTLY 刷新物化视图而不锁定物化视图上的并发选择。(……)
... 其他内容 ...
即使使用此选项,一次也只能针对任何 一个物化视图运行一个 REFRESH。
我有一个函数可以检查 MATERIALIZED VIEW 的上次刷新时间,如果超过 60 秒,它会刷新它。
但是,如果我尝试同时从两个单独的进程刷新物化视图会发生什么?他们会排队还是会引发错误?
有没有办法检测何时刷新 MATERIALIZED VIEW 从而避免触摸它?
目前,我已经在刷新(设置refreshing
为true
)之前填充表记录,然后false
在过程完成时将其设置为。
EXECUTE 'INSERT INTO refresh_status (last_update, refreshing)
VALUES (clock_timestamp(), true) RETURNING id') INTO refresh_id;
EXECUTE 'REFRESH MATERIALIZED VIEW CONCURRENTLY my_mat_view';
EXECUTE 'UPDATE refresh_status SET refreshing=false WHERE id=$1' USING refresh_id;
Run Code Online (Sandbox Code Playgroud)
然后,每当我调用此过程时,我都会检查最新的last_update
及其refreshing
值。如果refreshing
为 true,则不要尝试刷新物化视图。
EXECUTE 'SELECT
extract(epoch FROM now() - (last_update))::integer,
refreshing
FROM refresh_status
ORDER BY last_update DESC
LIMIT 1' INTO update_seconds_ago, refreshing;
IF(updated_seconds_ago > 60 AND refreshing = FALSE) THEN
-- the refresh block above
END IF;
Run Code Online (Sandbox Code Playgroud)
但是,我不确定刷新标志是否正在同步更新(我的意思是,它确实在等待刷新实际完成)
这种方法是合理的还是我在这里遗漏了什么?
mus*_*cio 16
正如提到的这个答案,“REFRESH MATERIALIZED VIEW CONCURRENTLY
需要一个EXCLUSIVE
锁定”在桌子上。根据文档的 crumb trail我们可以读到,EXCLUSIVE
表上的锁“只允许并发ACCESS SHARE
锁,即只有从表中读取才能继续”。在同一段中,我们可以看到“EXCLUSIVE
与...冲突EXCLUSIVE
”,这意味着另一个REFRESH MATERIALIZED VIEW CONCURRENTLY
请求相同EXCLUSIVE
锁的语句将不得不等待,直到较早的EXCLUSIVE
锁被释放。
如果您想避免在未定义的时间内等待此锁,您可能需要将会话变量lock_timeout
设置为一个合理的值。
正如Mustaccio所指出的,这个问题与Postgres Refresh Materialized View Locks有很大的重叠。
然而,虽然该问题的已接受答案有一个回答该问题的链接,但该问题的答案并未直接包含在该问题中。
因此,具体来说:根据有关显式锁定的 PostgreSQL 手册页(链接到当前版本页面,对于 PostGres 10),REFRESH MATERIALIZED VIEW CONCURRENTLY
需要EXCLUSIVE
锁定。该EXCLUSIVE
锁似乎阻止了所有其他锁,除了 ACCESS SHARE
- 包括其他EXCLUSIVE
锁。
因此,对同一视图的第二个REFRESH MATERIALIZED VIEW CONCURRENTLY
请求将等待第一个请求获得的锁被释放。
归档时间: |
|
查看次数: |
8064 次 |
最近记录: |