循环中的PostgreSQL DROP TABLE失败,出现ERROR:共享内存
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了循环中的PostgreSQL DROP TABLE失败,出现ERROR:共享内存相关的知识,希望对你有一定的参考价值。
我有一个数据库,其中有很多(3000+)架构在结构上相同。我正在尝试从每个架构中删除两个表。所以我编写了一个循环遍历模式并尝试删除这些表的函数。
当我执行我的函数时,我得到错误:共享内存,没有表被删除。
是否有可能强制PostgreSQL批量提交drop table语句?
这是我的功能(简化为问题):
CREATE OR REPLACE FUNCTION utils.drop_webstat_from_schema(schema_name character varying default '')
RETURNS SETOF record AS
$BODY$
declare
s record;
sql text;
BEGIN
for s in
select distinct t.table_schema from information_schema.tables t
where
schema_name <> '' and t.table_schema = schema_name
or
schema_name = '' and t.table_schema like 'myprefix_%'
loop
sql := 'DROP TABLE IF EXISTS ' || s.table_schema || '.webstat_hit, ' || s.table_schema || '.webstat_visit';
execute sql;
raise info '%; -- OK', sql;
return next s;
end loop;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
如您所见,该函数循环遍历模式集,并且对于每个模式,构造并执行以下SQL。
DROP TABLE IF EXISTS <schema_name>.webstat_hit, <schema_name>.webstat_visit
我想PostgreSQL试图在丢弃之前锁定所有这些表,并且它达到了最大配置限制。可能如果我将max_locks_per_transaction增加到某个固定数字,我可能会设法锁定所有表并删除它们。
但我正在寻找一种解决方案,它将逐步删除表并仅锁定步骤中的那些表。与每10个模式一样,锁定和删除批处理。
我可以在PostgreSQL中做到这一点,如果是这样,怎么样?谢谢。
我会使用drop从函数中取出模式循环。
所以我们假设fn_loop
plpgsql循环模式并调用fn_drop
。如果在dblink上执行fn_drop
,则可以在plpgsql中批量提交。
另一种在模式之间进行提交的方法,在bash中循环,例如:
for i in $(psql -c "select nspname form pg_namespaces where blah blah"); do
psql -c "drop damn table";
done;
使用dblink在不同事务中进行本地调用的示例(在同一数据库中注意now()的差异):
t=# do
$$
declare
_t text;
begin
for _r in 1..2 loop
select t into _t from dblink('dbname=t'::text,'select now()::text'::text) rtn (t text);
raise info '%',concat('local: ',now(),', dblink: ',_t);
end loop;
end;
$$
;
INFO: local: 2017-04-28 07:38:11.352026+00, dblink: 2017-04-28 07:38:11.355149+00
INFO: local: 2017-04-28 07:38:11.352026+00, dblink: 2017-04-28 07:38:11.358211+00
DO
Time: 6.811 ms
以上是关于循环中的PostgreSQL DROP TABLE失败,出现ERROR:共享内存的主要内容,如果未能解决你的问题,请参考以下文章
postgresql如何禁止在数据库执行drop table操作