函数获取数据库级别的锁以防止在完全不相关的表上进行自动清理和索引创建是否正常?
我有一个长期运行的存储过程,该存储过程从一个表中读取并将SUM()
/ AVG()
数据写入到另一个表中。在脚本执行期间(在大型系统上可能需要一个小时的时间),所有自动清理操作都会停止,并尝试在不相关的上创建索引(CREATE UNIQUE INDEX CONCURRENTLY
) / strong>表以阻止。一旦存储过程完成,被阻止的进程就会完成。
认为这是存储过程中错误地锁定了某些资源的东西,我重新编写它实际上只是一个睡眠:
CREATE OR REPLACE FUNCTION summarize_day(p_agg_date date)
RETURNS int AS
$$
BEGIN
SELECT pg_sleep(120);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
即使此存储的操作都不执行,也会阻止自动清理和其他数据库操作。
在此长时间运行的过程运行期间,是否有任何方法可以对其进行编码以不将数据库锁定用于其他操作?
答案 0 :(得分:1)
VACUUM
被长时间运行的事务阻止标记死元组。系统会跟踪在任何快照中仍然可能可见(即使不涉及竞争锁)的最旧交易ID(xid
)。稍后xid
将无法删除,直到阻塞交易完成。在这方面,长期运行的交易可能会使VACUUM
停滞不前。
相关:
但是,我想不出如何直接影响不相关表上的CREATE UNIQUE INDEX
的方法。可能还有其他事务因长时间运行的事务的锁而停止,而这些事务又依次持有锁定CREATE UNIQUE INDEX
的锁。长时间运行的事务锁可以以这种方式增加。因此,在并发写入负载下保持事务简短。
相关:
进一步阅读:
"When autovacuum does not vacuum"(Thomas Vondra的博客帖子)
答案 1 :(得分:0)
回答问题的人对我的原始问题进行了相当多的编辑,并回答了一个非常笼统的问题,而不是我所问的具体问题。
最初的问题是PostgreSQL存储过程是否可以支持小型事务,而不是一个长时间运行的事务。从版本11开始,它可以: