5

Perl fork manager と DBI を試しました。しかし、エラーDBD::mysql::st execute failed: Lost connection to MySQL server during query が発生しました。

ここにサンプルコード:低い値から高い値までのクエリを作成したい(int 10kレコードを吐き出しました)

use Parallel::ForkManager;
my $pm = new Parallel::ForkManager(50);
my $db = krish::DB->new or die $!; # its has all connection details 
while ( $low < $high  ) {
    # Some value manipulation 

    my $pid = $pm->start and next; 
    #db_execution returns execution 
    while ( my $sth = db_execution ( $db, $low , $high ) ) {
        ...
        #fetch row operation 
        ...
    }
    $pm->finish;
}

sub db_execution {
    ...
    my $dbh = $db->connect( 'students' ) or die $!;
    my $sth = $dbh->prepare( $sql ) or die "$!:" . $dbh->errstr;
    $sth->execute or die "$!:" . $sth->errstr;
    ...
}

同じコードが並列処理なしで実行されています。どうした?これを解決する方法は?

4

2 に答える 2

9

プロセス間でデータベース接続を共有する場合 (これは fork で行っていることです)、あるプロセスが他のプロセスの下でそれを閉じないようにする必要があります。接続も変数であるため、Perl インタープリターがシャットダウンすると、そのオブジェクトの DESTROY メソッドが呼び出され、この場合は接続が閉じられます。

そのため、子のいずれかが db 接続を閉じると (終了してシャットダウンしたときに発生します)、親プロセスの下からそれを強制終了します。これを防ぐ方法はInactiveDestroy、フォークの前に親プロセスで true に設定し、完了したら親プロセスで明示的に接続を閉じることです。

https://metacpan.org/pod/DBI#InactiveDestroy

于 2009-07-28T14:49:54.560 に答える
0

すべての子プロセスで同じ db ハンドルを同時に使用することで問題が発生しています。各子に新しい接続を作成する必要があります。

気にしないで...残りのコードを読みました。

于 2009-07-28T16:31:08.553 に答える