max_user_connections は、MySQL ユーザー接続数の最大設定です。ステートメント全体は、サーバーの MySQL の最大接続数パラメータが十分に設定されていないことを意味します。解決策: MySQL インストール ディレクトリの my.ini または my.cnf ファイルの max_user_connections パラメータの値を変更し、MySQL サーバーを再起動します。
ただし、通常は、MySQL のデフォルトの接続数 100 で十分です。手続き的な観点から考える必要があります。 MySQL のデフォルトの最大接続数は 100 (N) ですが、接続がいっぱいになったときに管理者が追い出されるのを防ぐために、一般ユーザーが実際に使用する接続は 1 つだけです。多くの Web サイトの実行中に接続が制限されるのは、10 回中 9 回、Web サイトへの実際のアクセス数が多すぎて接続数が標準を超えているためではなく、不合理な方法を使用しているためだと思います。 Web サイトのプログラムのデザイン アーキテクチャまたはデータ構造が原因。制限を超える異常な接続の考えられる理由は次のとおりです (Tianyuan のリアルタイム サマリーは完全ではない、またはエラーがない可能性があります。参照のみを目的としています):
人数、オンライン時間、およびビューの数は、メイン プログラム データベースと同じデータ領域に属します。
特にユーザーが閲覧するたびに複数のデータベースまたはテーブル操作が関与する場合、複雑な動的ページも表示されやすくなります。
また、プログラム設計に無理があったり(例えば、データベースとのやり取りの途中に複雑な処理や待機などの処理が入っているなど)、プログラムにリリースバグがある場合もあります。
コンピューターのハードウェア構成が低すぎますが、インストールされている MySQL のバージョンと構成が高すぎます。
キャッシュ技術は使用されていません。
データベースが最適化されていないか、テーブルの設計が非常に複雑です。
その他の理由により、データベースのデータ インタラクション時間が長くなったり、インタラクションの数が増加したりすることがあります。したがって、この種の問題が発生した場合は、まずプログラムに接続の解放に失敗するバグがあるかどうかを検討し、次にソフトウェアとハードウェアの最適化を検討する必要があります。もちろん、MySQL の接続数を変更することもソフトウェア最適化の手法の 1 つです。学習する姿勢で自分なりの理由を検討して、この問題を解決できることを願っています。本当に理由が見つからない場合は、まず接続数を変更し、本当の原因の特定を先延ばしにする必要があります。
PHP のデータベース永続接続 mysql_pconnect について
PHP プログラマは、MySQL データベースに接続するには、mysql_pconnect (永続接続) 関数を使用できることを知っているはずですが、データベース永続接続を使用すると効率が向上しますが、実際のアプリケーションではデータベース永続接続が使用されます。多くの場合、アクセス数が多い Web サイトでは、断続的にデータベースに接続できなくなり、再起動後に「接続が多すぎます」のようなエラー メッセージが表示されます。サーバーは正常に戻りますが、しばらくすると同じ問題が再び発生します。残念ながら、誰もがこれらの問題の原因を明確に説明できるわけではありませんが、PHP ドキュメントにはいくつかの関連情報が記載されていますが、ここでは恥ずかしがらずに簡単な説明と見解を述べようとしています。すべてが正しいかもしれません。皆さんのフィードバックを歓迎します。
まず、永続的なデータベース接続の定義を見てみましょう。永続的なデータベース接続とは、スクリプトの実行終了時に閉じられない接続を指します。常設接続要求を受信したとき。 PHP は、(以前に開かれた) 同一の永続接続が既に存在するかどうかを確認します。存在する場合は接続が直接使用され、存在しない場合は新しい接続が確立されます。いわゆる「同じ」接続とは、同じユーザー名とパスワードを使用した同じホストへの接続を指します。
PHP が永続接続を使用して MySQL を操作するには前提条件があります。PHP は、マルチスレッドまたはマルチプロセス Web サーバーのプラグインまたはモジュールとしてインストールする必要があります。最も一般的な形式は、PHP をマルチプロセス Apache サーバーのモジュールとして使用することです。マルチプロセス サーバーの典型的な特徴は、親プロセスと子プロセスのグループが連携して実行され、その中で実際に Web ページを生成するのは子プロセスであることです。クライアントが親プロセスにリクエストを行うと、そのリクエストは他のクライアント リクエストによって占有されていない子プロセスに渡されます。これは、同じクライアントがサーバーに対して 2 回目のリクエストを行うと、そのリクエストが別の子プロセスによって処理される可能性があることを意味します。永続的な接続を開いた後は、さまざまなサブプロセスから SQL サービスを要求する後続のすべてのページで、確立された SQL サーバー接続を再利用できます。これにより、各子プロセスは、ページが処理されるたびに SQL サーバーへの接続要求を行うのではなく、ライフサイクル中に接続操作を 1 つだけ実行できるようになります。各子プロセスは、サーバーへの独自の独立した永続的な接続を確立します。 PHP 自体にはデータベース接続プールの概念がありませんが、Apache にはプロセス プールの概念があり、Apache の子プロセスが終了すると、mysql_pconnect で開かれた mysql 接続リソースも許可されます。解放されないように、対応する Apache 子プロセスにアタッチされ、プロセス プールに保存されます。その後、次の接続リクエストで再利用できます。すべてが正常であるように見えますが、Apache に大量の同時アクセスがある場合、mysql_pconnect を使用すると、前の Apache 子プロセスによって占有されていた MySQL 接続が閉じられず、MySQL はすぐに最大接続数に達し、後続の接続が確立されません。要求は不可能です。
上記のテキストの一部は PHP ドキュメントからの抜粋です。少しおとなしく理解しにくいように思えるかもしれません。そのため、問題を分かりやすく説明するために別の例を示します。
接続の最大数が設定されていると仮定します。 Apache による接続の最大数は 1000、MySQL によって設定される接続の最大数は 1000 です。接続の最大数は 100 です。Apache サーバーが 200 の同時アクセスを受信すると、そのうち 100 はデータベース アクセスに関係し、残りの 100 はデータベース アクセスに関係しません。現時点では使用可能なデータベース接続がないため、データベース アクセスに関連する 100 個の同時実行により、同時に 100 個のデータベース永続接続が生成され、データベース接続の最大数に達すると、これらの操作が完了しないと、他の接続は生成されません。これらの操作が完了すると、対応する接続がプロセス プールに入れられます。この時点で、Apache のプロセス プールには 200 個のアイドル状態の子プロセスがあり、そのうちの 100 個は Apache 以降のデータベース接続を持っています。は、アクセス要求に対してアイドル状態の子プロセスをランダムに選択します。そのため、取得する子プロセスは、データベース接続を含まない 100 個の子プロセスのうちの 1 つである可能性が高く、データベース接続が最大値に達しているため、新しいデータベース接続を正常に確立できません。悲しいことに、ページが正常に閲覧できるように、運が良ければデータベース接続のある子プロセスに割り当てられる場合は、常に更新し続ける必要があります。アクセス数が多い Web サイトの場合、常に大量の同時実行が行われる可能性があるため、訪問者は常にデータベースに接続できないことに気づく可能性があります。
おそらく、Apache と MySQL の最大接続数を同じサイズに調整することはできないのではないかと思われるかもしれません。はい、最大接続数を適切に調整することでこの問題はある程度回避できますが、Apache と MySQL の負荷能力は異なります。Apache の負荷容量に応じて設定すると、MySQL の場合は最大接続数が異なります。これが大きすぎる場合、負荷に応じて設定すると、平時で数百万の軍隊をサポートするようなものになります。 MySQL の容量、Apache の場合、この最大接続数は少なすぎるため、過剰に感じられ、Apache の効率を最大限に引き出すことができません。
PHP マニュアルの紹介によると、データベース永続接続は同時アクセス数が少ない Web サイトでのみ使用するのが適しているとのことですが、同時アクセス数が少ない Web サイトの場合、データベース永続接続を使用することによってもたらされる効率の向上はないようです。つまり、この観点から見ると、PHP のデータベース永続接続は基本的に役に立たない役割であると考えられます。データベース接続プールの概念を使用する必要がある場合は、Apache 自体が提供する sqlrelay または mod_dbd を試すことができるでしょう。驚きです。
mysql_free_result と mysql_close について
mysql を使用するときは、mysql_store_result を呼び出してデータを取得した後、それを直接呼び出しました: