質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

4185閲覧

アクセス者がいないのにMySQLのDB接続数が上昇し続ける理由がわかりません

Webtuuuu

総合スコア30

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2022/01/12 20:58

前提・実現したいこと

会員制サイトを運用していたところ、突然下記のエラーが表示されページの閲覧ができなくなりました。
下記エラーの解消方法を教えてください。

発生している問題・エラーメッセージ

エラー!: SQLSTATE[HY000] [1040] Too many connections

試したこと

エラー表示されたメッセージ元に調べてみたところ、DBの接続数上限に達しているため表示されるエラーだということがわかりました。
そこでphpMyAdminにアクセスし、下記コマンドを実行し確認しました。

sql

1show global status like 'Threads_connected' 2show global variables like 'max_connections'

結果、上限値が500でした。

そして、現在接続されている数がアクセス者が0の状態でもどんどん上昇し500になって閲覧不能になります
数分するとサイトの閲覧が可能になるため再びコマンドを実行し現在の接続数を確認すると300くらいに下がっていて、
またそこからみるみるうちに上昇して再び500になります。

Googleアナリティクスを見ていても閲覧者は自分のみで、そのほかに閲覧をしている人はいません。
※たまに自分以外にいますが深夜に確認しているのもあって1人~2人たまにいるくらいです。

そして自分もサイトを閉じてしばらく放置してから確認してもこの現象は止まりません。

レンタルサーバーを利用しているため、レンタルサーバーの管理画面からみられるアクセス情報を見ると、1月10日からリクエストが急上昇しており、もともとのリクエスト量の平均が3000~5000だったところから1月12日には約19000にものぼっています。
これが何か関係があるのかどうかはわかりませんが、明らかに数値が異常なため念のため記述します。

サイト自体は1月1日あたりに公開したばかりで現在の会員登録者数は150人程度。
現時点での1日の平均PV数は1000~2000程度です。

DBの接続上限数を上げてみようと試みましたが、レンタルサーバーのためかphpMyAdminのコンソールからコマンドを実行しても下記エラーが表示されるだけで更新はできませんでした。

#1227 - アクセスは拒否されました。この操作には SUPER 権限が(複数の場合はどれか1つ)必要です。

また、PHPでDBへ接続したあと、接続を閉じる処理を行っていなかったため、それが原因かと思い、
インクルードで全てのページの最下部に下記の処理を追加し接続を閉じるように記述しました。

PHP

1$〇〇〇 = null; 2$△△△ = null; 3456$DBh->close();

しかし、やはりこれでも解決はせず、どこに原因があるのかすら突き止められずにいます。
この原因と対策がわかる方、ぜひご教示お願い致します。

補足情報(ツールのバージョンなど)

・PHP:71
・phpMyAdmin:4.8.0
・レンタルサーバー:coreserver ※利用しているのはCORE-Miniプランです。


ちなみに後から気づいたのですが、同じこのレンタルサーバー上で管理している別ドメイン・別DBのサイトも全く同じ症状が発生しておりました

別ドメインのもので、1つはデータベースに接続するサイトではなかったためエラーになっておらず、
また別のドメインのものはデータベースに接続しているためか同じエラーとなっておりました。

ドメインやDBを跨いで同様のエラー表示になっていたため、
てっきりレンタルサーバー側の障害かと思いましたが、確認してもエラー報告は特になく、おそらく私の管理しているサイトのみで発生しています。

おそらく、レンタルサーバーのためDB上限値は変更できません。
単純に今利用しているレンタルサーバーのプランの限界なのであれば上位のプランに切り替えるだけなのですが、もしそうでないのであればアップデートをしても同様の症状になるかと思います。

どうかこの原因がわかる方がいらっしゃいましたらご教示くださいませ。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

うーん、にわかには信じがたい症状ですね。
という訳で調べたら以下の記事がヒット、色々ヒントらしきものが拾えました。
https://gallu.hatenadiary.jp/entry/20150629/p1

この記事を読んでの私の印象としてはこんな感じ。

max_connectionsは500程度あればよし

なるほど、500は既に実践的な数値になっているようです。
これでコネクションを食いつぶしているのはPHPコード側の問題と認識しても良さそうです。


「1プログラム内で3回呼んだら」1プログラムで3接続使います。

本命はこれでしょうね。
まず1個のPHPプロセスが1個のコネクションだけで
1アクセスをちゃんと捌いているか確認してみてください。

PDOのコンストラクタで第四引数に「array(PDO::ATTR_PERSISTENT => true)」をいれると、1プログラムでn回callしても、接続は1つでした。

PDOの場合はこういう対処方が入っていると安心ですね。
デザインパターンのシングルトンケース等も検討してみてください。


次に割とあるのが「えらいこと重たいSQLが流れていて、DB connectionがつかまれっぱなし」なケース。

対抗はこれ

ちょっとアクセス数が増えた程度で裁けなくなるんだから、
MySQLのテーブルのインデックス貼り忘れでゴミみたいな速度のクエリが混ざってると考えられます。

PVが増えたとのことなので、SNS等で特定ページがバズったのでしょうね。
そのページを突き止め、開いた際に発行されるであろうSQLがどの程度の速度になるのか確認してみてください。

ベンチマークツール使えば再現出来るかもしれないですね。
https://www.10nin.com/hey/benchmark/2020/07/29/hey.html


最後に質問文をみて引っかかった箇所です。
確認してみてください。

$DB->close();

Apache等はPHPプロセスを複数立ち上げてリクエストに備えますが、
動的HTML等を生成し終わってメモリを洗浄して使いまわす際、DBとのコネクションを解除するようになって居ませんでしたっけ(ここうろ覚え)
なので、基本的にはその対策は無駄……とまでは言いませんが大した効果は得られないでしょう。

んで、PHPは基本的にHTTPリクエストを受け付けてからコネクションを張り始めるわけですが、
コネクションプールという仕組みを利用して
どっかの領域にコネクションを張りっぱなしのまま保持して
コネクションを確立するための手間を減らすテクニックが存在します。

もしかするとこれやってるのに更に新しくコネクション張り直すという
おバカな事やってる可能性があるので一応紹介しておきます。
https://www.php.net/manual/ja/features.persistent-connections.php

投稿2022/01/12 22:00

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Webtuuuu

2022/01/12 23:45

コメントありがとうございます。 頂いたコメントで、お?と思う場所がいくつか思い浮かんだので諸々試してみました。 結論から申し上げますと、何度も同じ接続を繰り返していたことが原因でした。 (初歩すぎてすみません…) 1つのページでAというテーブルを2回も3回も接続しなおして同じ値を取りに行ってました。 こんな具合に、AテーブルもBテーブルもCテーブルも同じように記述していたので、たった1度のアクセスで5回も10回も同じデータを取りに行っていたみたいです。 ひとまずデータを取りに行く回数をできるだけ最小限に記述しなおして、 その間に.htaccessでメンテナンス画面にリダイレクトされるように設定してすべてのアクセス者がDBにアクセスしないようにしました。 そのおかげでいったんDB接続数は一桁まで落ちたので修正したファイルをアップしなおして検証したところ基本的に4~15で落ち着いています。 ありがとうございます。ひとまず解決いたしましたのでベストアンサーとさせていただきます。 (ただ、アクセス者がいないのに増幅し続けた理由が本当にこれなんでしょうか…?なんだかまだ不安がぬぐえないです…)
Webtuuuu

2022/01/13 10:40

何度もすみません…解決しておりませんでした… 受付中に戻したいのでいったんベストアンサーを外させていただきます申し訳ございません…。
Webtuuuu

2022/01/13 11:01

右往左往してしまって申し訳ないです…。 直っていないと思ったのですが、 今改めて起きているエラーに関してはレンタルサーバー側の障害のようで、レンタルサーバー側のお知らせに障害報告があがってましたので今回の問題は解決したものとします。 もしまた問題が発生した場合は新規で質問を立ち上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問