Perl5:有没有办法从“内存故障(coredump)”错误中恢复?

时间:2011-01-11 03:27:11

标签: perl

我试图连接到某个数据库并获取一些数据。并且要求是:如果数据库连接失败,我将回归到一些基于文件的方法。

问题是:每次数据库连接失败时,程序最终都会出现“内存故障(coredump)"错误,它不会继续采用基于文件的方法。

我已尝试" eval {}或做{};"它也不起作用(即停在内存故障错误)。 关于如何从记忆故障(coredump)中恢复的任何想法"?非常感谢。

基本上,这是有问题的代码:

 my $db =
 "dbi:Sybase:server=$dbserver;database=$dbname;kerberos=$dbKerbPrincipal";
 my $dbh = DBI->connect($db, '', ''); 
 # BANG! if $dbname doesn't exist, you get the Memory fault,
 # and can't recover from it.

所以我明确选择了一个错误的数据库名称,只是为了使数据库连接失败,然后验证后续操作"故障转移"功能。但我无法从上面找到恢复" DBI-> connect()"调用

2 个答案:

答案 0 :(得分:4)

Perl + DBI + DBD :: Sybase不应该崩溃。周期。

您应该在正确的论坛上报告问题 - dbi-users@perl.org邮件列表。报告问题时,必须引用操作系统,Perl,DBI,DBD :: Sybase,Sybase库和Sybase服务器的版本(是的,在使用Perl时,您需要了解许多内容的版本和DBI)。

您是否能够使用与Perl发生故障的同一台计算机上的常规Sybase程序可靠地连接到您的数据库服务器?您是否使用Kerberos连接进行连接?

这些信息可能很关键。可以想象你正在测试以前没有经过测试的东西;我不确定Kerberos认证的连接有多广泛。

答案 1 :(得分:2)

首先,我同意以前的海报和评论者 - 通常情况下,你不应该从这种情况中获得段错误,并且正确的解决方法是弄清楚它为什么会出现段错和纠正(很可能是库错误)乔纳森说。)

但是,要回答您的直接技术问题,一旦发生段错误,您就无法恢复Perl解释器(或该主管的任何其他程序)。无论如何你都不想 - 它可能处于凌乱的状态。

因此,您可以通过第二个流程的“备份”机制解决您的问题,准备好接收破碎的碎片,并确保该节目继续进行,如下所示:

  • 在尝试数据库连接之前,您需要分叉子进程。

    请注意,您可能需要在分叉后立即对儿童过程进行守护,因为父母的死亡会导致孩子死亡。现在是早上2点,所以我的大脑太睡了,无法确定是否是这种情况。如果是这样的话,就可以在SO上多次覆盖守护进程。

  • 父进程尝试通过标准Perl警报进行数据库连接,超时(设置为10秒或任何你想要的)。

  • 如果连接成功,它会向子节点发送一个信号,表明数据库连接正常,父代码可以照常进行。

    如果连接失败,父母要么coredumps,要么发出die假设连接以非coredump方式失败或超时。

  • 子进程在分叉后立即设置信号处理程序以捕获父进程的“数据库连接成功”信号,然后将警报设置为10+ epsilon 秒。

  • 如果子进程捕获父进程的“数据库连接成功”信号,则子进程将终止。

  • 另一方面,如果触发子进程警报处理程序,则表示父进程无法连接到DB。因此,子进程向父母发送信号“我即将进行故障转移”;然后根据需要执行故障转移逻辑

上述逻辑非常粗糙,可能需要进行细化以处理竞争条件,可能是因为在使用数据之前两个进程都获得了锁定。

<强>更新

如评论中所述,上述CHILD进程尝试建立数据库连接并且父进程捕获问题并作为回退的变体可能更容易实现。