微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决在 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 举报,一经查实,本站将立刻删除。