为DBD :: Pg数据库连接设置超时

时间:2015-10-07 16:28:10

标签: perl postgresql timeout dbi

我在我的Perl代码中尝试过此操作,但timeout不起作用:

 my $dbh = DBI->connect($db, $db_user, $db_pass,{ timeout => 5 });

我想在与postgresql数据库的连接上设置超时:我该怎么做?

2 个答案:

答案 0 :(得分:2)

也许你可以使用闹钟。

local $SIG{ALRM} = sub { print "timeout occurred\n" }; # NB: \n required 
alarm $timeout; # set your value here 
my $dbh = DBI->connect($db, $db_user, $db_pass);
alarm 0;

详情请见: http://perldoc.perl.org/functions/alarm.html

稍后编辑:

这似乎有效,请看看它是否符合您的要求:

use DBI;

my $timeOut = 5;
$SIG{ALRM} = \&timeout;
$SIG{CHLD} = 'IGNORE',
alarm($timeOut);

my $pid = fork();
if ($pid) { # Parent
   print "Started child process id: $pid\n";
} elsif ($pid == 0) { # Child
  my $dbh = DBI->connect($db, $db_user, $db_pass);
} else { # Unable to fork
   die "ERROR: Could not fork new process: $!\n\n";
}

waitpid ($pid, 0);
alarm(0);

sub timeout {
     print "timeout occured";
     kill 9, $pid;
}

第二次编辑: 警报的主要问题可能是您使用的是Windows。 见Why doesn't die in alarm signal handler kill the process?

答案 1 :(得分:1)

据我所知,使用构造函数无法做到这一点。但是,这可以使用PostgreSQL客户端配置参数完成 - 您可以使用配置文件或环境变量来更改连接设置。

一般来说,DBD::Pg确实允许通过使用连接和查询缓存进行大量“透明”超时处理。这种排序方法的一个示例是基于MojoliciousDBD::Pg的{​​{3}}模块。

在PostgreSQL客户端配置中设置connect_timeout

NB:您还可以使用环境变量或service参数(请参阅Mojo::Pg)在调用时将您的连接句柄引用到DBD::Pg documentation你的构造函数。使用service参数或$PGSERVICE,您可以调整该配置文件中的超时值。 pg_service.conf文件是系统范围或用户特定的文件,可以为特定的PostgreSQL“服务”设置值。

例如,您可以设置pg_service.conf file值。后一种方法适用于与libpq链接的任何客户端库。我不确定DBD::Pg如何使用其中设置的值,或者DBI应用程序是否可以使用它们。目前还不清楚这是你想要的。

您可以尝试查看现有DBD::Pg perl应用程序的任何可用代码,以了解其他开发人员如何处理超时和数据库连接。 Django,PHP以及使用libpq连接到PostgreSQL的其他语言都可以直接使用connect_timeout环境变量。在您的shell中或通过$ENV{PGCONNECT_TIMEOUT}设置此功能也适用于您的情况。

您的申请中

“超时”

如果要控制应用程序在数据库变得不可用时尝试重新建立与数据库的连接,或者如果数据库服务器没有响应则要停止尝试连接(比如在启动时),那么设置{ {1}}并使用{ RaiseError=>1 }eval(请参阅PGCONNECT_TIMEOUT)检查应用程序中的错误 - 正如DBI "Timeout" documentation所示,是标准方法 - 至少UNIX平台上的

对于简单的启动超时,您可以执行以下操作:

alarm

并避免钻研信号。在您的应用程序运行时,您可以使用最小的测试查询检查连接手动

use DBI;

sub dbh_connect { 
  my $dbh = DBI->connect("dbi:Pg:dbname=test", '', '',); 
}

my $timeout = 5;
my $time    = time + $timeout;
while ( ! dbh_connect() ) { 
   say "connecting"; 
   sleep 1;
   if ( time >= $time ) { 
     die "unable to connect after $timeout seconds" ;  
   } 
}

如果您想定期检查您的连接是否正常并且有效,那么@Heto$dbh->ping功能都很有用。