« ウェブサービスにおける SSD 導入にむけて〜検索サービスの可能性 | メイン | ウェブアプリケーションのインストーラジェネレータ »

2008年11月04日

ウェブサービスにおけるダメージコントロール (MySQL のスロークエリを自動的に kill する方法)

 適切な設計によって、信頼性の高いソフトウェアやサービスを構築することが重要なのは、言うまでもないことです。一方で、なんらかの原因で問題が発生した際に、障害を局所化し、損害を小さく食い止める「ダメージコントロール」という概念もあります。ウェブサービスの場合も、特に検索や集計といった、計算量がクエリの種類によって大幅に異なるようなケースでは、次善の策として後者の手法が有効に働く場合もあるかと思います。

 ともかくそういうわけで、MySQL のスロークエリを強制終了するようなタスクを書きやすくする Perl モジュール MySQL::KillQuery (svn link) を書いてみました。以下のようにして使います。

use MySQL::KillQuery qw/mysql_killquery/;

# ルート権限で mysql に接続
my $dbh = DBI->connect(
    'DBI:mysql:database=foo',
    'root',
    'root-password',
) or die $DBI::errstr;

# 10 秒以上経過した、ロック状態にない root 以外の権限の SELECT クエリを強制終了
while (1) {
    mysql_killquery({
        dbh         => $dbh,
        should_kill => sub {
            my $proc = shift;
            $proc->{User} ne 'root'
                && $proc->{Time} && $proc->{Time} >= 10
                && $proc->{Command} && $proc->{Command} ne 'Killed'
                && $proc->{State} eq 'Locked'
                && $proc->{Info} && $proc->{Info} =~ /^select /i;
        },
    });
    sleep 5;
}

 備えあれば憂いなし。Tritonn を SSD ベースで運用したりする場合は、[Tritonn-dev 126] 全文検索中に KILL CONNECTION を有効にするパッチ と併せて運用するのがいいかな、と思っています。後者は、(中長期的にはブロックデバイスむけのチューニングを行うべきという話は脇におくとしても) まだ不完全ですが...

投稿者 kazuho : 2008年11月04日 21:45 このエントリーを含むはてなブックマーク このエントリーを含むはてなブックマーク

トラックバック

このエントリーのトラックバックURL:
http://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/2052