Perl DBI连接并执行超时

Sti*_*ggo 4 perl dbi oracle11g

在工作中我们有一位DBA,他说他的RAC工作得很好,但事实是事实并非如此.像Toad或SQL Developer这样的SQL IDE会随机丢弃它们的连接(我怀疑是因为RAC的网络设置不正确).我想通过测试来证明我的理论.我想perl脚本可以解决问题:

步骤1. ping数据库的IP

步骤2.如果IP正在尝试连接到数据库

步骤3.如果连接,则从双连接和关闭连接中选择sysdate

第4步.等一段时间再重新开始

我已经设法使用DBI在Perl中编写了这个,但我不知道如何超时连接和查询执行.是否有一些解决方案来超时这些东西?

小智 6

您可以使用与DBI相关的信号来使用alarm()和实现超时$SIG{ALRM}.

来自cpan和cpan pod上的DBI模块

超时

实现超时的传统方法是设置$ SIG {ALRM}以引用一些代码,这些代码将在ALRM信号到达时执行,然后调用警报($ seconds)以安排ALRM信号在$未来.

例如:

我的$ dbh = DBI-> connect("DBI:SQLRelay:host = $ hostname; port = $ port; socket =",$ user,$ password)或die DBI-> errstr;

我的$ sth = $ dbh-> prepare($ query)或者死$ 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
Run Code Online (Sandbox Code Playgroud)

第一个(外部)eval用于避免"执行代码"死亡的可能性,但可能会在取消之前触发警报.如果没有外部eval,如果发生这种情况,如果没有ALRM处理程序或者将调用非本地警报处理程序,程序将会死亡.


Cra*_*tow 3

它似乎取决于您要连接到哪个数据库后端。例如,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
Run Code Online (Sandbox Code Playgroud)

在给定的秒数后成功。

但是,我没有看到 Oracle 有相同的记录。

我确实在 DBI 文档中找到了关于通过信号处理执行此操作的讨论。