MySQL 接続で認証失敗エラーが発生する場合の分析と解決方法

MySQL 接続で認証失敗エラーが発生する場合の分析と解決方法

[問題の説明]

アプリケーション側では、次のエラーが時々表示されます。

メソッド 'mysql_native_password' を使用してユーザー 'yyyy' のホスト 'xxxx' への認証に失敗し、次のメッセージが表示されました: ストリームからの読み取りに失敗しました。

パフォーマンス特性:

1. この問題は Connector/NET を使用する場合にのみ発生します。JDBC ドライバーを使用する場合は同様の問題は発生しません。

2. アプリケーション サーバーは複数ありますが、このエラーを報告するのは 1 つだけなので、サーバー側の問題は除外できます。

3. この問題は非常にランダムに発生するため、サーバー/IIS を再起動すると一時的に問題が解決する場合があります。

4. シナリオによっては、アプリケーション サーバーの CPU がそれほど高くなく、このエラーが時々発生することがあります。

クライアントは Windows マシン、ドライバーは MySQL Connector ADO.NET Driver for MySQL (Connector/NET)、使用するバージョンは比較的新しい 6.9.9 です。

詳しい分析と解決策を見てみましょう。

【問題分析】

アプリケーション サーバー側とデータベース側でパケットをキャプチャします。両側でキャプチャされたパケットは一貫しています。ネットワークの問題は除外できます。キャプチャされたパケットと時間ポイントは次のとおりです。

シリアルナンバー絶対時間相対時間(秒)ソース目的ネットワークパケットの内容
1 12:58:47 9.07アプリケーションサーバーデータベースサーバー......S.
2 12:58:47 9.07データベースサーバーアプリケーションサーバー…として。
3 12:58:47 9:07アプリケーションサーバーデータベースサーバー…あ…。
4 12:58:47 9:07データベースサーバーアプリケーションサーバー…AP通信…
5 12:58:47 9.27アプリケーションサーバーデータベースサーバー…あ…。
6 12:58:57 19.12データベースサーバーアプリケーションサーバー…あ…ふ
7 12:58:57 19.12アプリケーションサーバーデータベースサーバー…あ…。
8 12:59:10 32.00アプリケーションサーバーデータベースサーバー…AP通信…
9 12:59:10 32.00データベースサーバーアプリケーションサーバー…..R..

上記のネットワーク パケットの相互作用から判断すると、最初の 3 つのパケットは TCP の 3 ウェイ ハンドシェイク プロトコルです。問題は 6 番目のパケットにあります。データベース サーバーは、データベース接続を終了するために、アプリケーション サーバーに Finish パケットを送信します。データベースは接続がタイムアウトしたことを検出するため、Finish パケットを送信します。 これは、サーバー側の Connect_timeout 変数によって制御されます。その理由は、アプリケーションが 10 秒以上ネットワーク パケットをデータベース サーバーに送信していないためです。ネットワーク パケットの相互作用から判断すると、5 番目と 6 番目のパケット間の時間間隔はちょうど 10 秒です。

上記の正常なデータベース接続と異常なデータベース接続を比較します。 アプリケーション サーバーは、5 番目のパケットをデータベースに送信した後、すぐに次のネットワーク パケットをデータベースに送信する必要があります。このパッケージは主に、アカウント番号、ドライバーのバージョン、オペレーティング システムの情報などをデータベース サーバーに送信します。 [以下は通常のネットワーク パケットのスクリーンショットです]異常なエラーが発生した場合、クライアントはパケットの送信を遅延します。フレーム8で送信されます。この時点で、接続は完了しています。フレーム 9 では、データベースがアプリケーション サーバーにリセット パケットを送信し、接続を完全に終了します。

次に、クライアントがアカウント、ドライバーのバージョン、オペレーティング システムの情報をデータベースに送信するのになぜ時間がかかるのかを詳しく分析してみましょう。この部分のコードは、Connector/NET MySQLAuthenticationPlugin.cs ファイルにあります。 コードのこの部分を変更し、時間追跡を実行して問題をさらに特定します。以下は、時点別に印刷される追跡情報です。

トレースによれば、約30秒の操作遅延があります。 MySQLDefs::OSDetails が返される場合。コードのこの部分は次のとおりです。

[表示名("_os_details")]

パブリック文字列 OSDetails

{

得る

{

文字列 os = 文字列.Empty;

試す

{

var searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");

var コレクション = searcher.Get();

foreach (コレクション内の変数 mgtObj)

{

os = mgtObj.GetPropertyValue("キャプション").ToString();

壊す;

}

}

例外 ex をキャッチします { System.Diagnostics.Debug.WriteLine(ex.ToString()); }

os を返します。

}

}

このコードは、WMI クエリを通じてキャプション情報を取得します。つまり、オペレーティングシステムのバージョン情報です。これは WMI 呼び出しなので、多くの依存関係があります。

【問題検証】

このコードを抽出してみましょう。以下に短い再現コードを示します。

静的void Main(文字列[] 引数)

{

ストップウォッチ watch = new Stopwatch();

(真)

{

ウォッチを再起動します。

var searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");

var コレクション = searcher.Get();

foreach (コレクション内の変数 mgtObj)

{

文字列 os = mgtObj.GetPropertyValue("キャプション").ToString();

}

ウォッチを停止します。

Console.WriteLine(watch.ElapsedMilliseconds);

(watch.ElapsedMilliseconds >= 1000)の場合

{

Console.WriteLine("--------------");

File.AppendAllText("abc.txt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") +","+ watch.ElapsedMilliseconds + "\r\n");

}

}

}

問題のあるアプリケーション サーバーで上記のコードを実行すると、WMI クエリがタイムアウトしたことがわかります。次のポイントは、30 秒以上をキャプチャしたポイントです。

2017-11-21 17:19:30.208, 33638

2017-11-21 17:20:09.193, 33199

2017-11-21 17:20:53.086, 33201

2017-11-21 17:27:05.114, 32976

2017-11-21 17:28:19.178, 33635

2017-11-21 17:30:07.130, 65977

2017-11-21 17:30:49.051, 40478

2017-11-21 17:31:15.126, 26072

2017-11-21 17:38:16.048, 66671

2017-11-21 17:38:49.204, 33152

2017-11-21 17:39:53.161, 33828

2017-11-21 17:40:38.121, 33549

2017-11-21 17:47:09.179, 33775

2017-11-21 17:47:57.174, 33164

【解決】

WMI クエリが遅くなる理由はいくつか考えられます。たとえば、オペレーティング システムの CPU 使用率が高い場合や、クエリ自体がデッドロックしている場合などです。この問題はさらなる分析が必要です。しかし、コードを見ると、この WMI クエリはオペレーティング システムに関する情報を取得するためだけのものであることがわかります。この情報はキャッシュできます。接続するたびに WMI クエリを実行する必要はありません。

エラーの根本的な原因は、MySQL C# コネクタでオペレーティング システム情報を取得するのに時間がかかりすぎるため、トリガー サーバーへの接続がタイムアウトになることです。この部分(長時間の操作を引き起こす可能性があります)をコメントアウトし、さらに検証を実行します。タイムアウト エラーは発生しません。

パブリック文字列 OSDetails
{
得る
{
dbglog.dolog("MysqlDefs::OSDetails1");
文字列 os = 文字列.Empty;
/*試す
{
var searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
var コレクション = searcher.Get();
foreach (コレクション内の変数 mgtObj)
{
os = mgtObj.GetPropertyValue("キャプション").ToString();
dbglog.dolog(String.Format("MysqlDefs::OSDetails::foreach{0}", os.ToString()));
壊す;
}
}
catch (例外 ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }*/
dbglog.dolog("MysqlDefs::OSDetails2");
os を返します。
}
}

要約する

上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に一定の参考学習価値を持つことを願っています。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM を応援していただきありがとうございます。

以下もご興味があるかもしれません:
  • mysql_connect(): 古い (4.1.1 より前の) 認証プロトコルを使用した接続が拒否されました
  • MYSQL の「クライアントは認証をサポートしていません」の解決策
  • MySQL バージョン 4.1 以降に接続するときに発生する「クライアントが認証プロトコルをサポートしていません」という問題の解決方法

<<:  nohup /dev/null 2>&1 の使い方の詳しい説明

>>:  Centos7.6にTomcat-8.5.39をインストールする方法

推薦する

CSSはフロートをシミュレートして、画像の左右を囲む中央テキストの効果を実現します。

画像の周囲にテキストを折り返すとは何ですか?これは次の図の効果です。 エフェクトのCSSコードはここ...

DevUI で独自の Angular コンポーネント ライブラリを構築する方法

目次序文コンポーネントライブラリの作成主要な構成の変更ディレクトリレイアウトの調整ライブラリ構築のた...

HTMLセマンティクスと関連するフロントエンドフレームワークの詳細な分析

セマンティクスについて意味論は、記号やシンボルとそれらが表す意味との関係を研究する学問です。言語学で...

preタグを自動的に折り返すためのサンプルコード

pre 要素は、フォーマット済みのテキストを定義します。 pre 要素で囲まれたテキストでは、通常、...

IIS7 IIS8 http は自動的に HTTPS にジャンプします (ポート 80 はポート 443 にジャンプします)

IIS7 では、「URL REWRITE2」疑似静的モジュールがインストールされているかどうかを確...

Reactでカスタムフックを作成する方法を教えます

1. カスタムフックとは何かロジックの再利用簡単に言えば、カスタム フックを使用すると、特定のコンポ...

Linux での NVIDIA GPU 使用状況の監視の詳細な説明

TensorFlow をディープラーニングに使うとビデオメモリ不足がよく起こるので、GPU 使用状況...

MySql 5.6.36 64 ビット グリーン バージョンのインストール グラフィック チュートリアル

MySQL のインストールについてはインターネット上に多くの記事がありますが、今日ノート PC にイ...

CentOS 7 での mysql 5.7 のインストール チュートリアル

1. 公式MySQL Yumリポジトリをダウンロードしてインストールする 実行ファイル: mysql...

ハイパーリンクを開くターゲットのテスト

リンクのターゲット属性は、リンクが開く場所を決定します。その値は通常、_blank、_self、_p...

Nginx キャッシュ設定例

Web アプリケーションの開発とデバッグを行う際には、テストのためにブラウザのキャッシュをクリアした...

Windows 上で Zookeeper サーバーを構築するチュートリアル

インストールと設定Apacheの公式ウェブサイトには多くのミラーダウンロードアドレスが用意されており...

Node.js http モジュールの使用

目次序文ウェブHTTP サーバーファイルサーバー練習する序文Node.js 開発の目的は、JavaS...

vscodeカスタムvueテンプレートの実装

vscode エディタを使用して vue テンプレートを作成すると、新しい vue ファイルを作成す...

Nodejs での WeChat アプレット メッセージ プッシュの実装

サブスクリプションメッセージテンプレートを選択または作成するWeChat アプレットにログインし、「...