MySQL アーキテクチャと内部モジュール

MySQL アーキテクチャと内部モジュール
デモ環境:
MySQL 5.7
ストレージ エンジン: InnoDB

1. クエリ SQL はどのように実行されますか?

ここに画像の説明を挿入

プログラムまたはツールがデータベースを操作する場合、最初のステップはデータベースとの接続を確立することです。

1. 通信プロトコル

まず、MySQL はデフォルト ポート (3306) でリッスンするサービスを実行する必要があります。
通信プロトコル
MySQL はさまざまな通信プロトコルをサポートしています。
1 つ目は TCP/IP プロトコルで、プログラミング言語の接続モジュールは、mysqlconnector-java-xxxx.jar など、TCP プロトコルを使用して MySQL サーバーに接続します。
ここに画像の説明を挿入

2 つ目は Unix ソケットです。たとえば、Linux サーバーはネットワーク プロトコルを経由せずに MySQL サーバーに接続できますが、サーバー上の物理ファイル (mysql.sock) を使用する必要があります。

mysql -uroot -p123456
show variables like 'socket';

名前付きパイプ (Named Pipes) やメモリ共有 (Share Memory) もあります。

通信方法
2つ目は通信方法です。
ここに画像の説明を挿入

MySQL は半二重通信を使用します。
半二重とは、クライアントがサーバーにデータを送信するか、サーバーがクライアントにデータを送信することを意味し、これら 2 つのアクションは
同時に実行できません。したがって、クライアントが SQL ステートメントをサーバーに送信するとき、 SQL ステートメントが
どれほど大きくても、(1 回の接続内で) データを小さな部分に分割して送信することはできず、一度に送信されます。サーバーに送信されるデータ パケットが大きすぎる場合は、MySQL サーバー設定の max_allowed_pa​​cket パラメータの値を調整する必要があります(デフォルトは 4M)。



ここに画像の説明を挿入

一方、サーバーの場合は、すべてのデータが一度に送信されるため、目的のデータを取得したからといって操作を中断することはできません。
したがって、プログラム上ではこのような操作を際限なく避ける必要があります。
接続方法
3つ目はこの部分を接続する方法です。
MySQL は短い接続と長い接続の両方をサポートします。短い接続とは、操作が完了したらすぐに接続を閉じることです。長い接続は開いたままにしておくことができ、後でプログラムがアクセスするときにもこの接続を使用できます。
接続が長期間非アクティブな場合、MySQL サーバーは切断されます。
ここに画像の説明を挿入

デフォルトは 28800 秒、8 時間です。
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_interactive_timeout

MySQL のデフォルトの最大接続数は 151 (バージョン 5.7) で、最大接続数は 16384 (2^14) です。

show variables like 'max_connections';

ここに画像の説明を挿入

ポート 3306 の現在の接続数を表示します。

netstat-an|grep3306|wc-l

SHOW FULL PROCESSLIST; を使用して、クエリの実行ステータスを表示します。
ここに画像の説明を挿入

いくつかの一般的な状態:
ここに画像の説明を挿入

2. クエリキャッシュ

MySQL には内部的にキャッシュ モジュールが付属しています。デフォルトはオフです。主な理由は、MySQL の組み込みキャッシュのアプリケーション シナリオが制限されていることです。1 つ目は、SQL ステートメントがまったく同じである必要があることです。2 つ目は、テーブル内のデータが変更されると、このテーブル内のすべてのキャッシュが無効になることです。

MySQL 5.8 では、クエリ キャッシュが削除されました。

3. 解析と前処理 (パーサー & プリプロセッサ)

次は何をしましょうか?
ランダムな文字列 fkdljasklf を実行すると、サーバーは 1064 エラーを報告します。

[Err] 1064 - SQL 構文にエラーがあります。1 行目の「fkdljasklf」付近で使用する正しい構文については、MySQL サーバーのバージョンに対応するマニュアルを確認してください。

サーバーは私が入力した内容が間違っていることをどうやって知るのでしょうか?
あるいは、完全に正しい構文で SQL を入力したが、テーブル名が存在しなかった場合、どうやってそれを見つけたのでしょうか?
これは、MySQL の Parser パーサーおよび Preprocessor 前処理モジュールです。
このステップで行う主な作業は、SQL ステートメントに対して字句解析、文法解析、および意味解析を実行することです。

字句分析
字句分析は、完全な SQL ステートメントを個々の単語に分割することです。
たとえば、単純な SQL ステートメントは次のとおりです。

select name from user where id = 1;

これは 8 つのシンボルに分割され、各シンボルがどのようなタイプであるか、どこで始まり、どこで終わるかを記録します。

文法解析
2 番目のステップは文法解析で、単一引用符が閉じられているかどうかなど SQL の構文をチェックし、MySQL で定義された文法規則に従って SQL ステートメントに応じたデータ構造を生成します。このデータ構造を解析ツリーと呼びます。
ここに画像の説明を挿入

プリプロセッサ (Preprocessor) の
テーブル名が正しくない場合、プリプロセッサの処理中にエラーが報告されます。
結果として得られる解析ツリーを調べて、パーサーが解決できないセマンティクスを解決します。たとえば、テーブル名と列名の存在をチェックし、名前とエイリアスをチェックして曖昧さがないことを確認します。

4. クエリ オプティマイザーとクエリ実行プラン

どのようなオプティマイザーですか?
質問: SQL ステートメントを実行する方法は 1 つだけですか? それとも、データベースが最終的に実行する SQL は、送信した SQL と同じですか?

これに対する答えはノーです。SQL ステートメントはさまざまな方法で実行できます。しかし、実行方法が非常にたくさんある場合、これらの実行方法はどのようにして取得されるのでしょうか? 結局どれを選ぶの?どのような基準で選べばよいのでしょうか?

これは、MySQL クエリ オプティマイザー モジュール (Optimizer) です。

クエリ オプティマイザーの目的は、解析ツリーに基づいてさまざまな実行プランを生成し、最適な実行プランを選択することです。MySQL はコストベースのオプティマイザーを使用します。コストが最も低い実行プランが使用されます。

クエリのコストを表示するには、次のコマンドを使用します。

show status like 'Last_query_cost';

– これは、ルックアップを完了するには、いくつかの 4K データ ページをランダムに読み取る必要があることを意味します。

オプティマイザーがどのように機能するかを知りたい場合、オプティマイザーは複数の実行プランを生成します。各実行プランのコストはいくらで、何をすべきでしょうか?

オプティマイザはどのようにして実行計画を取得するのでしょうか?
https://dev.mysql.com/doc/internals/en/optimizer-tracing.html

まず、オプティマイザー トレースを有効にする必要があります (デフォルトではオフになっています)。

SHOW VARIABLES LIKE 'optimizer_trace';
set optimizer_trace="enabled=on";

なお、このスイッチをオンにすると、最適化解析の結果をテーブルに書き込む必要があるためパフォーマンスを消費しますので、安易にオンにしたり、確認後にオフにする(オフに変更する)ことは避けてください。

次に SQL ステートメントを実行すると、オプティマイザーが実行プランを生成します。

selectt.tcidfromteachert,teacher_contacttcwheret.tcid=tc.tcid;

現時点では、オプティマイザーの分析プロセスがシステム テーブルに記録されており、次のクエリを実行できます。

select*frominformation_schema.optimizer_trace\G

ここに画像の説明を挿入

Expanded_query は最適化された SQL ステートメントです。
すべての実行プランは、conned_execution_plans にリストされます。
忘れずにオフにしてください。

setoptimizer_trace="enabled=off";
SHOWVARIABLESLIKE'optimizer_trace';

オプティマイザーは何ができるのでしょうか?
MySQL のオプティマイザーはどのような種類の最適化を処理できますか?
例:
1. 複数のテーブルに対して関連付けられたクエリを実行する場合、どのテーブルのデータが参照テーブルとして使用されます。
2. a=1、b=2、c=3 のユーザーから * を選択します。c=3 の結果が 100 件、b=2 の結果が 200 件、a=1 の結果が 300 件ある場合、あなたはどう思いますか
?最初に実行するフィルタ?
3. 条件に恒等式や不等式がある場合、それらを削除できますか?
4. データをクエリし、インデックスから値を直接取得できるかどうかを確認します。
5. count()、min()、max() など、インデックスから値を直接取得できるかどうか。
6. その他。

オプティマイザーによって取得される結果
オプティマイザーは、最終的に解析ツリーをデータ構造であるクエリ実行プランに変換します。
もちろん、この実行計画は必ずしも最適な実行計画であるでしょうか? MySQL はすべての実行プランをカバーしていない可能性があるため、必ずしもそうとは限りません。
MySQL は、計画を実行するためのツールを提供します。SQL ステートメントの前に EXPLAIN を追加すると、実行計画の情報を確認できます。

EXPLAINselectnamefromuserwhereid=1;

5. ストレージエンジン

データはどこに保存されますか? 実行計画はどこで実行されますか? 誰がそれを実行するのでしょうか?

ストレージ エンジンの基本概要
リレーショナル データベースでは、データはテーブルに配置されます。このテーブルは Excel スプレッドシートとして理解できます。したがって、テーブルにデータが保存される一方で、データのストレージ構造も整理する必要があります。このストレージ構造はストレージ エンジンによって決定されるため、ストレージ エンジンをテーブル タイプと呼ぶこともできます。

MySQL では複数のストレージ エンジンがサポートされており、置き換えることができるため、プラグイン ストレージ エンジンと呼ばれます。なぜこれほど多くのストレージ エンジンを利用するのでしょうか? 1 つでは十分ではありませんか? これは、ビジネス シナリオごとにデータ操作に対する要件が異なるためであり、これらのさまざまなストレージ エンジンは、さまざまなストレージ メカニズム、インデックス付け方法、ロック レベル、その他の機能を提供することでビジネス ニーズを満たします。

ストレージ エンジンの表示
データベース テーブルのストレージ エンジンを表示します。

show table status from `training`;

ここに画像の説明を挿入

MySQL では、作成するテーブルごとにストレージ エンジンを指定することができ、1 つのストレージ エンジンしか使用できないデータベースではありません。また、テーブルの作成後にストレージ エンジンを変更することもできます。

データベースにデータを保存するパス:

show variables like 'datadir';

各データベースには独自のフォルダーがあります。例としてトレーニング データベースを取り上げます。
どのストレージ エンジンにも、テーブル構造定義ファイルである frm ファイルがあります。

ここに画像の説明を挿入

異なるストレージ エンジンを使用して、データベースに 3 つのテーブルを構築しました。
ストレージ エンジンが異なれば、データは異なる方法で保存され、異なるファイルが生成されます。
ストレージ エンジンの比較
一般的なストレージ エンジン

MySQL 5.5 より前では、デフォルトのストレージ エンジンは MySQL に付属する MyISAM でした。バージョン 5.5 以降、デフォルトのストレージ エンジンは、MySQL 用にサードパーティ企業によって開発された InnoDB に変更されました。なぜ変更するのでしょうか? 主な理由は、InnoDB がトランザクションと行レベルのロックをサポートしており、ビジネスの一貫性要件が高いシナリオにより適しているためです。

データベースでサポートされているストレージ エンジン
次のコマンドを使用して、データベースのストレージ エンジンのサポートを確認できます。

SHOWENGINES;

ストレージ エンジンと、トランザクション、XA プロトコル、セーブポイントのサポートについて説明します。
ここに画像の説明を挿入

公式 Web サイトのストレージ エンジンの概要:
https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html

MyISAM(3 文件)
これらのテーブルの占有面積は小さいです。テーブル レベルのロックは、読み取り/書き込みワークロードのパフォーマンスを制限するため、Web およびデータ ウェアハウジング構成の読み取り専用またはほとんど読み取り専用のワークロードでよく使用されます。

適用範囲は比較的狭いです。テーブル レベルのロックは読み取り/書き込みパフォーマンスを制限するため、Web およびデータ ウェアハウス構成での読み取り専用またはほとんど読み取り専用の作業によく使用されます。

特徴:
1 テーブルレベルのロックをサポートします (挿入と更新によりテーブルがロックされます)。トランザクションはサポートされていません。
2 は、挿入 (挿入) およびクエリ (選択) の速度が高速です。
3 はテーブル内の行数を保存します (カウントが高速になります)。
4 読み取り専用などのデータ分析に適したプロジェクト。

InnoDB(2 件の文書)
MySQL 5.7 のデフォルトのストレージ エンジン。InnoDB は、ユーザー データを保護するためのコミット、ロールバック、およびクラッシュ リカバリ機能を備えた MySQL 用のトランザクション セーフ (ACID 準拠) ストレージ エンジンです。InnoDB の行レベルのロック (粒度の粗いロックへのエスカレーションなし) と Oracle スタイルの一貫した非ロック読み取りにより、マルチユーザーの同時実行性とパフォーマンスが向上します。InnoDB はユーザー データをクラスター化インデックスに保存し、主キーに基づく一般的なクエリの I/O を削減します。データの整合性を維持するために、InnoDB は FOREIGN KEY 参照整合性制約もサポートします。

mysql 5.7 のデフォルトのストレージ エンジン。InnoDB は、ユーザー データを保護するためのコミット、ロールバック、クラッシュ回復機能を備えたトランザクション セーフ (ACID 準拠) MySQL ストレージ エンジンです。InnoDB の行レベルのロック (粒度の粗いロックにはアップグレードされていません) と Oracle スタイルの一貫した非ロック読み取りにより、マルチユーザーの同時実行性とパフォーマンスが向上します。InnoDB はユーザー データをクラスター化インデックスに保存し、主キーに基づく一般的なクエリの I/O を削減します。データの整合性を維持するために、InnoDB は外部キーの参照整合性制約もサポートしています。

特徴:
1. トランザクションと外部キーをサポートしているため、データの完全性と一貫性がより高くなります。
2 行レベルのロックとテーブルレベルのロックをサポートします。
3 同時読み取りと書き込みをサポートします。書き込みは読み取りをブロックしません。
4 特別なインデックス保存方法により IO が削減され、クエリ効率が向上します。
5 頻繁に更新されるテーブルに適しており、同時読み書きやトランザクション処理を行う業務システムもあります。

メモリ (1 ファイル)
重要でないデータの素早い検索が必要な環境での高速アクセスのために、すべてのデータを RAM に保存します。このエンジンは、以前は HEAP エンジンとして知られていました。その使用例は減少しています。バッファ プール メモリ領域を備えた InnoDB は、 NDBCLUSTER は、ほとんどまたはすべてのデータをメモリ内に保持するための汎用かつ耐久性のある方法であり、NDBCLUSTER は、巨大な分散データ セットに対する高速なキーと値のルックアップを提供します。重要でないデータ アクセスの高速ルックアップが必要な環境での高速ルックアップのために、すべてのデータを RAM に保存します
このエンジンは、以前はヒープ エンジンと呼ばれていました。その使用例は減少しており、InnoDB とそのバッファ プール メモリ領域は、ほとんどまたはすべてのデータをメモリ内に保持するための汎用で耐久性のある方法を提供する一方、ndbcluster は大規模な分散データセットに対する高速なキーと値のルックアップを提供します。

特徴:
データをメモリに置くと、読み取りと書き込みの速度が非常に速くなりますが、データベースが再起動またはクラッシュすると、すべてのデータが消えます。一時テーブルにのみ適しています。デフォルトではハッシュインデックスが使用されます。テーブル内のデータをメモリに保存します。

CSV(3个文件)
そのテーブルは実際にはカンマ区切りの値を持つテキスト ファイルです。CSV テーブルを使用すると、CSV 形式でデータをインポートまたはダンプし、同じ形式で読み書きするスクリプトやアプリケーションとデータを交換できます。CSV テーブルにはインデックスが作成されないため、通常は通常の操作中はデータを InnoDB テーブルに保持し、インポートまたはエクスポートの段階でのみ CSV テーブルを使用します。

そのテーブルは実際には、カンマ区切りの値を含むテキスト ファイルです。csv テーブルを使用すると、同じ形式で読み書きするスクリプトやアプリケーションとデータを交換するために、データを csv 形式でインポートまたはダンプできます。CSV テーブルにはインデックスがないため、通常の操作中はデータを innodb テーブルに保持し、インポートまたはエクスポート フェーズ中にのみ CSV テーブルを使用するのが一般的です。

特徴:
空白行は使用できず、インデックスはサポートされていません。この形式は共通であり、直接編集できるため、異なるデータベース間でのインポートおよびエクスポートに適しています。

アーカイブ (2 ファイル)これらのコンパクトなインデックスのないテーブル
は、めったに参照されない大量の履歴情報、アーカイブ情報、またはセキュリティ監査情報を保存および取得することを目的としています

特徴:
インデックスをサポートせず、更新削除をサポートしません。

6. クエリ実行エンジン、結果を返す

実行エンジン。ストレージ エンジンを使用して、ストレージ エンジンの操作を完了するための対応する API を提供します。最後に、結果がない場合でもデータをクライアントに返します。

2. MySQL アーキテクチャの概要

階層化されたアーキテクチャ
全体として、MySQL は 3 つの階層に分けることができます。
ここに画像の説明を挿入

モジュールの詳しい説明
ここに画像の説明を挿入

1.コネクタ: PHP、Python、Java JDBCなど、さまざまな言語とSQLの間の対話をサポートするために使用されます。 2.管理
サービスとユーティリティ: バックアップとリカバリ、MySQLレプリケーション、クラスタリングなどのシステム管理および制御ツール。
3.接続プール: 接続プール。ユーザーのパスワード許可スレッドなどを含む、バッファリングする必要があるリソースを管理します。
4.SQL インターフェース: ユーザーの SQL コマンドを受信し、ユーザーが必要とするクエリ結果を返すために使用されます
。 5. パーサー: SQL ステートメントの解析に使用されます。 6.
オプティマイザー: クエリ オプティマイザー
7. キャッシュとバッファ: クエリ キャッシュ。行レコードのキャッシュに加えて、テーブル キャッシュ、キー キャッシュ、権限キャッシュなどもあります。
8.プラグ可能ストレージ エンジン: プラグ可能ストレージ エンジン。サービス層が特定のファイルを処理するための API を提供します。

3. 更新 SQL はどのように実行されますか?

データベースでは、ここで説明している更新操作には、実際には更新、挿入、削除が含まれます。更新プロセスとクエリプロセスの違いは何ですか?
基本的なプロセスも同じです。つまり、パーサーとオプティマイザーによって処理され、最終的にエグゼキューターに渡されます。
違いは、修飾されたデータを取得した後の操作にあります。
まず、InnoDBにはメモリバッファプール(バッファプール)があります。IO コストが高すぎるため、データ更新を毎回
ディスクに直接書き込むことはしません。そのため、最初にデータ更新をバッファ プールに書き込みます。メモリ内のデータ ページがディスク データと一致しない場合、それをダーティ ページと呼びます。
InnoDB には、バッファ プール データをディスクに書き込み、時々複数の変更を一度にディスクに書き込む特別なスレッドがあります。これはダーティと呼ばれます。
ここに画像の説明を挿入

ここで問題が発生し、ダーティ ページがディスクに書き込まれる前にサーバーに障害が発生すると、メモリ内のデータが失われます。あるいは、ブラッシングの途中でデータファイルが破壊されてしまうこともあります。したがって、永続的なメカニズムが必要です。

REDO ログ
InnoDB では、REDO ログ (REDO ログ) と呼ばれるログ ファイルが導入されています。メモリ データに対するすべての変更操作はログ ファイルに書き込まれます。サーバーに問題がある場合は、ログ ファイルからデータを読み取り、データを復元します。これはトランザクションの永続性を実現するためです。

REDOログの特徴は何ですか?
1. 物理ログに属する変更された値を記録します
2. REDO ログのサイズは固定されており、以前の内容は上書きされるため、データのロールバック/データの回復には使用できません。
3. REDO ログは InnoDB ストレージ エンジンによって実装されますが、すべてのストレージ エンジンに実装されているわけではありません。

binlog
MySQL サーバー層には、すべてのストレージ エンジンで使用できる binlog と呼ばれるログ ファイルもあります。
Binlog は、すべての DDL および DML ステートメントをイベントの形式で記録し (論理ログに属するデータ値ではなく操作を記録するため)、マスター/スレーブ レプリケーションとデータ リカバリに使用できます。

マスター/スレーブ レプリケーション
ここに画像の説明を挿入

データ復旧
ここに画像の説明を挿入

REDO ログとは異なり、そのファイルの内容は追加でき、固定サイズの制限はありません。
これら 2 つのログを使用して、更新ステートメントがどのように実行されるかを見てみましょう。
ここに画像の説明を挿入

たとえば、ステートメントは次のとおりです。 update Teacher set name='jim' where name ='666'
1. まずこのデータをクエリします。キャッシュがある場合は、そのキャッシュも使用します。
2. 名前を jim に変更し、エンジンの API インターフェイスを呼び出し、このデータ行をメモリに書き込み、同時に REDO ログを記録します。この時点で、REDO ログは準備状態に入り、実行が完了し、いつでも送信できることを実行者に伝えます。
3. エグゼキュータは通知を受信した後、binlog を記録し、ストレージ エンジン インターフェイスを呼び出して REDO ログをコミット状態に設定します。
4. アップデートが完了しました。

質問: 2 フェーズ コミット (XA) を使用するのはなぜですか?
例:
名前を jim に変更すると、REDO ログが書き込まれ、bin ログが書き込まれなければ、MySQL が再起動します。
REDO ログはデータを復元できるため、ディスクに書き込むのは jim です。ただし、論理ログは bin ログに記録されないため、このとき binlog を使用してデータを復元したり、スレーブ データベースと同期したりすると、データの不整合が発生します。
したがって、2 つのログを書き込む場合、binlog はトランザクション コーディネーターとして機能します。InnoDB に準備、コミット、またはロールバックを実行するように通知します。
簡単に言うと、分散トランザクションと同様にログ書き込み操作が 2 つあり、2 フェーズ コミットがなければ、両方が成功するか失敗するかという保証はありません。

おすすめ

転載: blog.csdn.net/lx9876lx/article/details/129128706