在 postgres 中使用 plperl/plpython 的全局变量实现抛出内存不足

问题描述

我们实际上是将 db 从 oracle 迁移到 postgres。我们正在使用 postgreSQL 11。 因此,包被相应地转换为过程/函数。

对于全局变量的实现,我们使用了如下的本地配置设置

SET pkg.variable = value;
select current_setting('pkg.variable');

但是,如果这些值进入异常块,这些值就会变空,我们需要该值在异常块中可用,以便在失败时继续执行其他一些逻辑。

所以我们采用了一种使用全局变量的方法,使用扩展名 plperl/plpython,如下所示,

CREATE OR REPLACE FUNCTION set_var(name text,val text)
    RETURNS void
    LANGUAGE 'plperl'
AS $BODY$
    undef $_SHARED{$_[0]};
    $_SHARED{$_[0]} = $_[1];
$BODY$;

CREATE OR REPLACE FUNCTION get_var(name text)
    RETURNS text
    LANGUAGE 'plperl'
AS $BODY$
    return $_SHARED{$_[0]};
$BODY$;

plpython如下

CREATE OR REPLACE FUNCTION set_var(var text,val text)
 RETURNS void
 LANGUAGE plpythonu
AS $function$
    if var not in GD:
        GD[var] = val 
    else:
        del GD[var]
        GD[var] = val
$function$ ;

    CREATE OR REPLACE FUNCTION get_var(var text)
 RETURNS text
 LANGUAGE plpythonu
AS $function$
    if var in GD:
        return GD[var]
    else:
        return None
$function$ 

我们设置值并检索值,如

PERFORM set_var('pkg.variable',value) -- to set the variable
select get_var('pkg.variable') --to get the value.

我们正在调用的过程内部有一个 for 循环,inreturn 会调用许多其他过程,这些过程将为每个循环总共设置大约 270 个这样的全局变量。全局变量的值将更新为我们已经在第一个循环中创建的相同 270 个变量的新值。这必须在 for 循环中的大约 300,000 行中发生。

但是,使用此实现时,内存消耗会非常高,并且在某一时刻达到内存不足状态并在第 157000 行左右停止。

我对 perl 或 python 了解不多,但根据我从网上了解到的内容,我分别为 perl 和 python 添加了 undef() 和 del,它们会释放内存。然而事实并非如此。

我们还获取了变量集的地址,以查看它是否在同一地址上更新或在每次调用时获取新的内存地址。创建变量时,它正在更新同一地址上的值。

但是内存会不断累积,直到它用完所有可用的 RAM 并因内存不足而抛出错误。

如果有人能帮助我理解我做错了什么或者我可以改变什么以使其正常工作,那将是非常有帮助的。提前致谢。

更新:问题是因为使用程序。我们将代码更改为函数,内存消耗问题不存在。我还没有弄清楚为什么在使用过程和函数时会有如此巨大的差异。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...