web-dev-qa-db-ja.com

MySQL接続がどこからともなく急上昇

私たちは3つのサーバーにまたがるウェブサイトを運営しています。それらのうちの2つは負荷分散されたWebサーバーであり、最後は専用のmysqlサーバーです。 mysqlサーバーは、2.6.18-92.1.6.el5#1SMPカーネルとMySQL5.0.45を使用してRHEL564ビットを実行しています。 Xeon L5420と8ギガのRAMを備えた、かなり頑丈なサーバーでもあります。 Webサーバーのphpページは、mysqliを使用するように構成されています。

通常、与えられたすべてのリソースを実際に利用するわけではありません。日中は1秒間に20〜25回のクエリを実行します。ただし、頻繁に、データベース接続の最大制限に真っ向からぶつかり、それによってサイトが不正になります。さらに、それはサイトのトラフィックが最小限であるはずの夜に起こるようです。

最初は最大100接続でしたが、300に増やしましたが、それでも発生します。それが違いを生む場合、眠っているMySQLプロセスが大量にあることがありますが、データベースに接続するものは永続的な接続を利用していません。それは毎晩起こるわけではなく、毎晩鳴くという問題があり、それから今日まで約1週間半は大丈夫でした。

一度に数分間データベースを拘束するようなモンスタークエリはありません。 SLOW_QUERYログを一瞥してみました。そこに表示されるクエリがいくつかありますが、通常、それらは1〜2秒以上持続せず、それらは非常にまれです。

それは特に何かのように聞こえますか?問題の診断に関して、ここからどのように進めますか?

6
AlexMax

私の推測では、アプリケーションには長時間実行されるクエリがいくつかあります。それらが実行されると、接続がプールから長時間チェックアウトされたままになり(通常の使用パターンと比較して)、これによりプールが使い果たされ、成長し、最大値まで成長し続けます。その時点で残りのワーカーは、接続が解放されるのを待つことをブロックします。

最初に追跡することですいつこれが発生します。つまり、周期的なイベントであるか、ランダムであるかです。前者の場合は運が良ければ、準備ができているのでそれが起こります。パターンを特定できない場合は、警戒する必要があります。

これは、Webサイトの監視ログ、またはデータベースのsarを調べて、相関するスパイクがあるかどうかを確認することで理解できる場合があります。

負荷がかかっているときにデータベースをキャッチできる場合は、mysqlサーバーで次のコマンドを実行する必要があります

show innodb status;
show processlist;

前者はinnodbエンジンに関する診断情報を出力し(innodbを使用していますか?)、後者は実行されていたクエリの最初の数百文字を出力します。長期間実行されているクエリ、ディスク上に一時テーブルを生成するクエリ、およびリソースでブロックされているクエリを探します。

その後、ハードワークが始まります。 EXPLAINを使用して、クエリのコストとクエリが使用するリソースを見積もります。 tmpテーブルを介してディスク上でソートする必要があるクエリは避けてください。長時間実行されるレポートジョブ、またはデータベースを定期的にロックまたは飽和させるその他のスケジュールされたメンテナンスタスクを探します。これは、バックアップタスクのような単純なものでも、古い発注書データをロールアップするジョブでもかまいません。

/etc/my.cnfにこれらの3つの設定を含めることをお勧めします

log_slow_queries
log-queries-not-using-indexes
set-variable = long_query_time=1

1秒あたり20〜30のリクエストを実行するWebアプリケーションの場合、これらのログに何も表示する余裕はありません。

ところで、IMHOは、接続プールのサイズを元のサイズを超えて増やすことは無意味です。これは、プールの枯渇の開始をせいぜい数秒遅らせるだけであり、必要のないときにデータベースにさらに圧力をかけるだけです。

5
Dave Cheney

私はこれを以前に見たことがあります。

MyISMテーブルを使用してデータベースのmysqldumpを実行するcronがありました。 MyISMのため、mysqlダンプはテーブル全体をロックします。クエリ(したがって接続)がキューに入れられます。

2
Shaw

AlexMax、この問題をどこで解決できますか?微妙な違いはありますが、現在、14台のWebサーバーが8台のmysqlサーバーに負荷分散されている(各WebサイトはWebサーバーの1つにコード化されています)という同様の問題が発生しています。接続が急増し、mysqlのプロセスリストにある接続の90%以上がクエリNULLでスリープとしてリストされます。これにより、mysqlは接続の許可を停止し、約持続します。 2〜3分。 Mysql5.0.70およびPHP 5.28(ただし、32ビット)。

1
tebruno99