2010-12-26 5 views
2

私は既存のmysqlデータベースからテーブルを作成するperlスクリプトを持っています。私は何百ものデータベースを持っており、各データベースには何百万ものレコードが含まれているため、インデックス作成に時間がかかることがあります。また、不適切な結合によってディスクスペースが不足することもあります。同じスクリプトでクエリを強制終了してメモリ消費と実行時間を監視する方法はありますか?perlのmysqlクエリをkill

P.S.私はmysqlインターフェイス用のPerlでDBIモジュールを使用しています

+0

['kill'](http://dev.mysql.com/doc/refman/5.0/ja/kill.html)は便利ですか? – ajreal

答えて

2

http://www.perlmonks.org/?node_id=885620

で説明したように、私はこれが私のスクリプトからコード

eval { 
    eval { # Time out and interrupt work 
     my $TimeOut=Sys::SigAction::set_sig_handler('ALRM',sub { 
      $dbh->clone()->do("KILL QUERY ".$dbh->{"mysql_thread_id"}); 
      die "TIMEOUT\n"; 
     }); 
     #Set alarm 
     alarm($seconds); 
     $sth->execute(); 
     # Clear alarm 
     #alarm(0); 
    }; 
    # Prevent race condition 
    alarm(0); 
    die "[email protected]" if [email protected]; 
}; 

このコードは、クエリを殺し、また、すべての一時テーブル

1

実行時間までは、alarm Perlの機能をタイムアウトに使用します。

あなたALRMハンドルのいずれかdieは(以下の例を参照)、またはDBI cancelコールを発行することができます(sub { $sth->cancel };

DBI documentation実際には非常に良い本の議論と同様に例があります。

eval { 
    local $SIG{ALRM} = sub { die "TIMEOUT\n" }; # N.B. \n required 
    eval { 
     alarm($seconds); 
     ... code to execute with timeout here (which may die) ... 
    }; 
    # outer eval catches alarm that might fire JUST before this alarm(0) 
    alarm(0); # cancel alarm (if code ran fast) 
    die "[email protected]" if [email protected]; 
    }; 
    if ([email protected] eq "TIMEOUT\n") { ... } 
    elsif ([email protected]) { ... } # some other error 

メモリを見ている限り、単に死ぬ/取り消すのではなく、ALRMハンドラが必要です。まずスクリプトのメモリ消費をチェックします。

それはそうだった無関係な質問がすでにSO上で総合的に答えていますが、Proc::ProcessTableas described in the Perlmonks snippet Find memory usage of perl programからsize()メソッドを使用することができますので、私は、メモリ消費量を測定する方法の詳細には触れません。

1

があることを付けろ削除されKILL QUERYコマンドを使用テーブルロックのためにスタックされたクエリがある場合、同じ接続ハンドラを使用してクエリを強制終了することはできません。同じユーザーと別の接続を開き、そのスレッドIDを開く必要があります。

もちろん、現在開いているスレッドIDのリストをハッシュで保存する必要があります。

スレッドIDを終了すると、残りのPerlコードはunblessedハンドラで実行されます。