在工作中,我们有一位DBA,他说他的RAC工作得很好,但事实是事实并非如此。像Toad或SQL Developer这样的SQL IDE会随机丢弃它们的连接(我怀疑是因为RAC的网络设置不正确)。 我想通过测试来证明我的理论。我想perl脚本可以解决问题:
步骤1. ping数据库的IP
步骤2.如果IP已尝试连接到db
步骤3.如果连接,则从双连接和关闭连接中选择sysdate
步骤4.等待一段时间再重新开始
我已经设法使用DBI在Perl中编写了这个,但我不知道如何超时连接和查询执行。是否有一些解决方案来超时这些东西?
答案 0 :(得分:5)
您可以使用与DBI相关的信号,使用alarm()
和$SIG{ALRM}
实现超时。
超时
实现超时的传统方法是将$ SIG {ALRM}设置为 参考ALRM信号到达时将执行的一些代码 然后调用警报($秒)来安排ALRM信号 未来交付$秒。
例如:
我的$ dbh = DBI-> connect(“DBI:SQLRelay:host = $ hostname; port = $ port; socket =”, $ user,$ password)或死DBI-> errstr;
my $ sth = $ dbh-> prepare($ query)或die $ dbh-> errstr;
eval { local $SIG{ALRM} = sub { die "TIMEOUT\n" }; # \n is required eval { alarm($seconds); if(! $sth->execute() ) { # execute query print "Error executing query!\n" } }; # outer eval catches alarm that might fire JUST before this alarm(0) alarm(0); # cancel alarm (if code ran fast) die "$@" if $@; }; if ( $@ eq "TIMEOUT\n" ) { ... } elsif ($@) { ... } # some other error
第一个(外部)eval用于避免不太可能但可能的情况 “执行代码”死亡并且警报在它之前触发的可能性 取消。没有外部评估,如果这发生在你的程序中 如果您没有ALRM处理程序或非本地警报处理程序将会死亡 被称为。
答案 1 :(得分:2)
它似乎取决于您要连接的数据库后端。例如,DBD::mysql确实记录了这样的超时值:
mysql_connect_timeout
If your DSN contains the option "mysql_connect_timeout=##", the connect request to the server will timeout if it has not been
在给定的秒数后成功。
但是,我没有看到Oracle记录的相同内容。
我确实找到了使用信号处理in the DBI documentation执行此操作的讨论。