我使用的是Postgresql 9.6。我有一个存储的proc,由Scala调用。这个存储的proc是一个包装器,即它将为每个传入包装器的输入列表调用另一个存储的proc。例如,包装器有100个元素的输入列表,所以内部存储的proc将被每个元素调用100次。内部进程是数据密集型进程,它创建4-5个临时表,并处理数据和返回。因此,包装器将收集所有数据并最终完成。
get_data_synced(date, text, integer[])这里的文本是逗号分隔的项目(10-1000取决于使用-case)。
基本上,问题是如果我传递一个更大的100-200项,即在一个循环中,我们多次调用内部procs,它就会抛出错误:
SQL execution failed (Reason: ERROR: out of shared memory
Hint: You might need to increase max_locks_per_transaction.我知道在内部函数中创建temp table将创建锁。但是每次调用proc时,第一件事就是删除,然后创建临时表。
DROP TABLE IF EXISTS _temp_data_1;
CREATE TEMP TABLE _temp_data_1 AS (...);
DROP TABLE IF EXISTS _temp_data_2;
CREATE TEMP TABLE _temp_data_2 AS (...);
..
..
..因此,即使这个proc被调用了1000次,它做的第一件事就是drop table (应该释放锁吗?)然后创建表。
max_locks_per_transaction设置为256。
现在,直到我的包装器函数(外部函数)结束,事务才结束,对吗?所以这意味着即使我删除临时表,锁也不会被释放?
有没有办法在我的函数完成后立即解除对临时表的锁定?
发布于 2020-01-08 06:18:59
您的诊断是正确的,锁将一直存活到事务结束。即使它是在创建它的同一事务中删除的,即使它是一个临时表。也许这是可以优化的,但这就是它目前的工作方式。
对于变通方法,如果表已经存在,为什么不直接截断它,而不是删除并重新创建它呢?
https://stackoverflow.com/questions/59635283
复制相似问题