1. ホーム
  2. php

MySql Proccesslist が "Sleep" エントリでいっぱいになり、"Too many Connections" になる?

2023-11-20 04:50:10

質問

php/mysqlの接続に関する長年の問題について、あなたの助けを求めたいと思います。

私が "SHOW PROCESSLIST" コマンドを実行するたびに、私たちの 5 つの Web サーバーから現れたデータベース サーバーへのアイドル (Status: Sleep) 接続が約 400 個表示されます。

これは、最近トラフィック数が増加するまであまり問題にはならなかった (そして、迅速な解決策も見つからなかった) し、それ以来 MySQL は、350 以上の接続がスリープ状態であるにもかかわらず、繰り返し "to many connections" 問題を報告しています。また、サーバーは、同じサーバーにスリープ状態の接続がある場合でも、MySQL 接続を取得することはできません。

これらの接続はすべて、apache サーバーが再起動されたときに消滅します。

データベース接続を作成するために使用される PHP コードは、通常の "mysql" モジュール、 "mysqli" モジュール、 PEAR::DB および Zend Framework Db Adapter を使用しています。(異なるプロジェクト)。どのプロジェクトも持続的な接続を使用しません。

接続制限を上げることは可能ですが、現在450で、一度に20~100の"real"接続しかないので、良い解決策とは思えません。

私の質問です。

なぜスリープ状態の接続が多いのでしょうか、また、それを防ぐにはどうしたらよいのでしょうか。

-- 更新しました。

一度に実行されるApacheのリクエストの数が50を超えることはないので、接続を閉じる際に問題があるか、Apacheがphpscriptを添付せずにポートを開いたままにしているか、何か(?)

my.cnfが参考になると思います。

innodb_buffer_pool_size = 1024M

max_allowed_packet = 5M
net_buffer_length = 8K

read_buffer_size = 2M
read_rnd_buffer_size = 8M

query_cache_size = 512M
myisam_sort_buffer_size = 128M

max_connections = 450
thread_cache = 50
key_buffer_size = 1280M
join_buffer_size = 16M

table_cache = 2048
sort_buffer_size = 64M
tmp_table_size = 512M
max_heap_table_size = 512M

thread_concurrency = 8

log-slow-queries = /daten/mysql-log/slow-log
long_query_time = 1
log_queries_not_using_indexes

innodb_additional_mem_pool_size = 64M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table

どのように解決するのですか?

基本的に、スリープ状態のコネクションを取得するのは、:

  • PHP スクリプトが MySQL に接続した場合
  • いくつかのクエリが実行されます。
  • その後、PHP スクリプトは時間のかかる処理を行います。
    • DBとの接続を切断することなく
  • そして最後に、PHPスクリプトは終了します
    • これは、MySQL サーバーとの接続を解除することを意味します。

そのため、多くの PHP プロセスが接続されたまま、実際にはデータベース側で何もしていない場合、一般に多くのプロセスがスリープ状態になってしまいます。

基本的な考え方ですが、長時間稼働するPHPプロセスを持たないようにするか、データベースにアクセスする必要がなくなったらすぐに強制的に切断するようにします。



もうひとつ、サーバーに何らかの負荷がかかっているときによく見かけるのが :

  • Apache に来るリクエストの数が増えている
    • これは生成するページが多いことを意味します。
  • 各PHPスクリプトは、ページを生成するために、DBに接続し、いくつかのクエリを実行します。
  • これらのクエリは、DBサーバーの負荷が増加するにつれて、より多くの時間を要します。
  • つまり、より多くのプロセスが蓄積され続ける

解決策としては、クエリにかかる時間を短縮すること、つまり、長いクエリを最適化することです。