5

職場の DBA が、RAC は正常に動作していると述べていますが、実際にはそうではありません。Toad や SQL Developer などの SQL IDE は、接続をランダムにドロップします (私の疑いは、RAC のネットワーク設定が正しくないためです)。テストで自分の理論を証明したいと思います。私は、perlスクリプトがうまくいくと思います:

ステップ 1. データベースの IP を ping する

ステップ 2. IP が稼働している場合は、データベースへの接続を試みます

ステップ 3. 接続されている場合は、デュアルから sysdate を選択し、接続を閉じます

ステップ 4. しばらく待ってから、最初からやり直してください

DBI を使用して Perl でこれを書くことができましたが、接続とクエリの実行をタイムアウトにする方法がわかりません。それらをタイムアウトするための解決策はありますか?

4

2 に答える 2

7

alarm()およびを使用してタイムアウトを実装するために、DBI に関連するシグナルを使用できます$SIG{ALRM}

cpan およびcpan podのDBIモジュールから

タイムアウト

タイムアウトを実装する従来の方法は、$SIG{ALRM} を設定して ALRM シグナルが到着したときに実行されるコードを参照し、alarm($seconds) を呼び出して ALRM シグナルが $seconds に配信されるようにスケジュールすることです。将来。

例えば:

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

my $sth = $dbh->prepare($query) or 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 は、"実行するコード" が停止し、アラームがキャンセルされる前に発火する可能性は低いが、発生する可能性を回避するために使用されます。外側の eval がないと、これが発生すると、ALRM ハンドラがないか、ローカル以外のアラーム ハンドラが呼び出されると、プログラムが停止します。

于 2013-02-08T09:34:59.403 に答える
3

接続しているDBバックエンドに依存しているようです。たとえば、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 については同じことが文書化されていません。

DBI ドキュメント で、シグナル処理でこれを行うことについての議論を見つけました。

于 2013-02-07T19:54:56.463 に答える