vpsで実行されているmysqlの接続と致命的なエラーを解決する方法


9

私はlinodeサーバーでアプリケーションPHPlistを実行しています。同時に12個のPHPスクリプトを実行しています。それぞれがMySQL接続を開きます。PHPlistにアクセスすると、次のエラーが表示されることがよくあります。

致命的なエラー:サーバーは現在ビジー状態です。しばらくしてからもう一度お試しください。

phpMyAdminにアクセスしようとすると、#1040エラーが表示されます。cronジョブを実行する私のPHPスクリプトの出力は次のとおりです。

PHP警告:mysqli_connect():(HY000 / 1040):接続が多すぎます

私はサーバーのLAMPスタックをphpMyAdminで使用しています。top端末の出力は、mysqld100〜130%のCPUの使用を示しています。この問題をトラブルシューティングしようとすると、いくつかの手掛かりが得られました。

  • max_connection変数を増やします:私は200(デフォルトでは100)を使用しています
  • オープンテーブルキャッシュ:512(デフォルトでは400)

設定する変数はたくさんありますが、具体的な変数を特定できません参照先が 多すぎます。接続が多すぎるhttp://dev.mysql.com/doc/refman/5.5/en/table-cache。 html

しかし、私の使用法によると、メモリを増やす方法と、私にとって最大のメモリはどれほど難しいかです。

私のサーバーでは、約12のPHPスクリプト、メール送信用のPHPlistアプリケーション、およびユーザー登録用の主要なデータベースを使用しています。

この問題の解決を手伝ってください。

回答:


12

まず、次のクエリを実行する必要があります。

SELECT user,host FROM mysql.user
WHERE super_priv='Y' AND
CONCAT(user,'@',host) <> 'root@localhost';

これにより、SUPER特権を持つすべてのユーザーがリストされます。アプリケーション関連のDB処理を行うほとんどのユーザーには、この特権は必要ありません。MySQLドキュメントによると、SUPER権限を持つユーザーは次のことができます。

  • レプリケーション座標を制御するためにCHANGE MASTER TOを実行します
  • KILLまたはmysqladmin kill他のアカウントに属するスレッドを強制終了する
  • バイナリログをパージして、バイナリログを体系的に削除します
  • SET GLOBALを使用して構成を変更し、グローバルシステム変数を変更する
  • mysqladmin debugコマンド
  • ロギングの有効化または無効化
  • * read_only *システム変数が有効な場合でも更新を実行する
  • スレーブサーバーでのレプリケーションの開始と停止
  • ストアドプログラムおよびビューのDEFINER属性でのアカウントの指定
  • ここがあなたの問題にとって最も重要なものです::max_connectionsシステム変数によって制御される接続制限に達した場合でも、(一度だけ)接続することができます。

root @ localhostとしてログインし、次のようにSUPER権限を取り消す必要があります。

UPDATE mysql.user SET super_priv='N'
WHERE super_priv='Y' AND
CONCAT(user,'@',host) <> 'root@localhost';
FLUSH PRIVILEGES;

これを行うと、すべてのユーザーがmysql接続をフラッディングするたびに、root@localhostログインのみが可能になります。結局のところ、みんなと彼の祖母がSUPER特権を持っていれば、これはroot@localhost他の誰よりも先に接続することを妨げるでしょう。max_connectionsが200で、mysqldを再起動せずに300に上げる必要がある場合は、次のコマンドでmax_connectionsを動的に増やすことができます。

mysql> SET GLOBAL max_connections = 300;

これにより、より多くの接続がすぐに有効になりますが、気まぐれに任意に数を増やすだけではありません。mysqlが増加に対応するのに十分なRAMを持っていることを確認する必要があります。

警告:max_connectionsを動的に300に変更する場合は、/ etc / my.cnfに配置してください

[mysqld]
max_connections=300

MySQL DBサーバーでmysqltuner.plを実行できます。それがない場合は、次を実行します。

cd
wget mysqltuner.pl
perl mysqltuner.pl

Performance Metricsの3行目には

-------- Performance Metrics -------------------------------------------------
[--] Up for: 8d 20h 46m 22s (8M q [10.711 qps], 129K conn, TX: 90B, RX: 19B)
[--] Reads / Writes: 4% / 96%
[--] Total buffers: 2.1G global + 5.4M per thread (2000 max threads)
[OK] Maximum possible memory usage: 12.6G (80% of installed RAM)

スレッドあたり5.4Mを参照してください。これはmax_connectionsで乗算されます。この例では、最大で約10.8GのRAMになります。したがって、max_connectionsを増やすたびに、mysqltuner.plを実行して、OSにメモリを押しすぎていないかどうかを確認する必要があります。

いずれの場合も、SUPER権限を持つユーザーを制限することで、そのようなユーザーにmysqldのDB接続によるフラッディングを軽減する機会が与えられます。


perl mysqltuner.plの試行中にこのエラーが発生する「debianメンテナンスアカウントからログイン認証情報を使用しようとしましたが、失敗しました。」
Shashank 2012

私は私のローカルubuntuサーバーでこれを試していますが、最大メモリ使用量を示していますが、私のvpsでは失敗を示し、phpmyadminにログインできませんが、mysql端末に正常にログインします
Shashank

このcmd wget mysqltuner.plはindex.htmlをダウンロードしましたが、これはperlファイルだったので、mysqltuner.plに名前を変更して次のcmdがperl mysqltuner.pl機能しました。
MotsManish

2
  1. グローバル変数max_connectionsは、MySQLへの同時接続の最大数を決定します。この変数の値が大きいことを確認してください。この値を300または400に増やし、この設定の後でMySQLを再起動してみてください。
  2. MySQL接続がごく短時間開いたままになるようにアプリケーションを設計します。
  3. また、クライアントコードが永続的な接続(mysql_pconnect()など)を不適切に使用していないことも確認する必要があります。

またFlush status;、MySQlサーバーでコマンドを実行して、この値を減らします。

これらの提案がお役に立てば幸いです。


0

ディスクがいっぱいかどうかを確認してください。これにより、同じエラーが発生する可能性があります。

df -h

各パーティションの残りのスペースが表示されます。おそらく、ルートパーティション/(または、これに追加のパーティションがある場合は/ var /)を確認する必要があります。

df -h /
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.