如何释放 plpgsql 中的内存?
How to free memory in plpgsql?
我在 PostgreSQL 中写了一个 UDF 来测试我的索引效率,像这样
CREATE OR REPLACE PROCEDURE query()
LANGUAGE plpgsql
AS
$$
DECLARE
i int;
exp text;
temprow RECORD;
t timestamp;
cnt int;
sum int;
BEGIN
set max_parallel_workers_per_gather = 0;
set enable_seqscan = false;
drop table if exists query_ranges;
create table query_ranges(box boxndf, ts timestamp, te timestamp);
FOR i IN 1 .. 5000 LOOP
INSERT INTO query_ranges SELECT something;
END LOOP;
sum = 0;
t = clock_timestamp();
FOR temprow IN
SELECT * FROM query_ranges
LOOP
select count(*) from data_table where something into cnt;
sum = sum + cnt;
COMMIT;
END LOOP;
RAISE NOTICE '%', clock_timestamp() - t;
END;
$$;
但是我发现内存使用量不断增加,然后出现 OOM。我想查询 select count(*) from data_table where something into cnt;
可能会分配一些内存。如果我只是 运行 一个查询,内存很快就会被释放。但是,如果我使用此 UDF,则不会在查询循环之间释放内存。
有什么方法可以释放这些分配的内存或避免 OOM 吗?
您无法控制 PL/pgSQL 中的内存。 Postgres 具有分层内存控制 - 当 a) 处理行、处理查询、处理事务时释放内存的某些部分。 Postgres 中的程序有点奇怪,因为它们一半是内部事务,一半是外部事务,因此 Postgres 程序可能会出现一些问题。
有很多与程序相关的已修复错误,因此请检查您的 Postgres 是否最新并已更新。如果没有帮助,请将此作为 Postgres 错误报告给 Postgres 社区。
我在 Postgres 13.4 上测试了以下示例,它运行没有任何问题:
postgres=# create or replace procedure foo()
as $$
declare r record; cnt int; s int;
begin
s := 0;
for r in select * from pg_proc union all select * from pg_proc loop
select count(*) from pg_proc into cnt;
s := s + cnt; commit;
end loop;
end;
$$ language plpgsql;
也许您使用了一些扩展程序。我不知道数据类型 boxndf
。此扩展中也可能存在一些问题。
我在 PostgreSQL 中写了一个 UDF 来测试我的索引效率,像这样
CREATE OR REPLACE PROCEDURE query()
LANGUAGE plpgsql
AS
$$
DECLARE
i int;
exp text;
temprow RECORD;
t timestamp;
cnt int;
sum int;
BEGIN
set max_parallel_workers_per_gather = 0;
set enable_seqscan = false;
drop table if exists query_ranges;
create table query_ranges(box boxndf, ts timestamp, te timestamp);
FOR i IN 1 .. 5000 LOOP
INSERT INTO query_ranges SELECT something;
END LOOP;
sum = 0;
t = clock_timestamp();
FOR temprow IN
SELECT * FROM query_ranges
LOOP
select count(*) from data_table where something into cnt;
sum = sum + cnt;
COMMIT;
END LOOP;
RAISE NOTICE '%', clock_timestamp() - t;
END;
$$;
但是我发现内存使用量不断增加,然后出现 OOM。我想查询 select count(*) from data_table where something into cnt;
可能会分配一些内存。如果我只是 运行 一个查询,内存很快就会被释放。但是,如果我使用此 UDF,则不会在查询循环之间释放内存。
有什么方法可以释放这些分配的内存或避免 OOM 吗?
您无法控制 PL/pgSQL 中的内存。 Postgres 具有分层内存控制 - 当 a) 处理行、处理查询、处理事务时释放内存的某些部分。 Postgres 中的程序有点奇怪,因为它们一半是内部事务,一半是外部事务,因此 Postgres 程序可能会出现一些问题。
有很多与程序相关的已修复错误,因此请检查您的 Postgres 是否最新并已更新。如果没有帮助,请将此作为 Postgres 错误报告给 Postgres 社区。
我在 Postgres 13.4 上测试了以下示例,它运行没有任何问题:
postgres=# create or replace procedure foo()
as $$
declare r record; cnt int; s int;
begin
s := 0;
for r in select * from pg_proc union all select * from pg_proc loop
select count(*) from pg_proc into cnt;
s := s + cnt; commit;
end loop;
end;
$$ language plpgsql;
也许您使用了一些扩展程序。我不知道数据类型 boxndf
。此扩展中也可能存在一些问题。