序文 MySQL を扱ったことがある人なら、テーブル メタデータ ロックの待機についてよく知っているはずです。通常、これは変更操作中にブロックされ、プロセス リストを表示すると、スレッド ステータスがメタデータ ロックを待機中であることがわかります。この記事では、MySQL テーブル構造の変更に対するメタデータ ロックについて詳しく説明します。 DDL 操作をオンラインで実行する場合、発生する可能性のあるシステム負荷と比較して、最も懸念されるのは、MDL によって発生する可能性のあるブロッキング問題です。 MDL を取得できないために DDL 操作がブロックされると、テーブルに対する後続のすべての操作がブロックされます。典型的な例は次のとおりです。ブロックがしばらく続くと、Threads_running の急増と CPU アラームが発生します。 mysql> プロセスリストを表示します。 +----+-----------------+------------+-----------+-------+---------------------------------+------------------------------------+ | ID | ユーザー | ホスト | db | コマンド | 時間 | 状態 | 情報 | +----+-----------------+------------+-----------+-------+---------------------------------+------------------------------------+ | 4 | event_scheduler | localhost | NULL | デーモン | 122 | 空のキューを待機中 | NULL | | 9 | ルート | ローカルホスト | NULL | スリープ | 57 | | NULL | | 12 | root | localhost | employees | クエリ | 40 | テーブル メタデータ ロックを待機中 | alter table slowtech.t1 add c1 int | | 13 | root | localhost | employees | クエリ | 35 | テーブル メタデータ ロックを待機中 | select * from slowtech.t1 | | 14 | root | localhost | employees | クエリ | 30 | テーブル メタデータ ロックを待機中 | select * from slowtech.t1 | | 15 | root | localhost | employees | クエリ | 19 | テーブル メタデータ ロックを待機中 | select * from slowtech.t1 | | 16 | root | localhost | employees | クエリ | 10 | テーブル メタデータ ロックを待機中 | select * from slowtech.t1 | | 17 | root | localhost | employees | クエリ | 0 | 開始 | プロセスリストを表示 | +----+-----------------+------------+-----------+-------+---------------------------------+------------------------------------+ セット内の行数 (0.00 秒) それがオンラインで起こった場合、間違いなくビジネスに影響が及ぶでしょう。したがって、一般的には、業務のオフピーク時に DDL 操作を実行することが推奨されます。実際には、次の 2 つの考慮事項があります。1. システム負荷に大きな影響を及ぼさないようにする。 2. DDL がブロックされる可能性を減らします。 MDL導入の背景 MDL は MySQL 5.5.3 で導入され、主に 2 つの問題を解決するために使用されます。 RRトランザクション分離レベルにおける非反復読み取りの問題 以下に示すように、デモ環境では MySQL 5.5.0 を使用します。 セッション1> 開始; クエリは正常、影響を受けた行は 0 行 (0.00 秒) セッション1> t1から*を選択します。 +------+------+ | ID | 名前 | +------+------+ | 1 | へ | | 2 | バ | +------+------+ セット内の行数 (0.00 秒) セッション2> テーブル t1 を変更し、c1 int を追加します。 クエリは正常、2 行が影響を受けました (0.02 秒) 記録: 2 重複: 0 警告: 0 セッション1> t1から*を選択します。 空のセット (0.00 秒) セッション1>コミット; クエリは正常、影響を受けた行は 0 行 (0.00 秒) セッション1> t1から*を選択します。 +------+------+------+ | ID | 名前 | c1 | +------+------+------+ | 1 | a | NULL | | 2 | b | NULL | +------+------+------+ セット内の行数 (0.00 秒) RR 分離レベルであるにもかかわらず、トランザクションがオンになっていると 2 番目のクエリには結果がないことがわかります。 マスタースレーブレプリケーションの問題 マスターとスレーブのデータ間の不整合、マスタースレーブレプリケーションの中断などが含まれます。 たとえば、マスターとスレーブのデータは以下のように矛盾しています。 セッション1> テーブル t1(id int,name varchar(10)) を作成します。エンジンは innodb です。 クエリは正常、影響を受けた行は 0 行 (0.00 秒) セッション1> 開始; クエリは正常、影響を受けた行は 0 行 (0.00 秒) session1> t1に値(1,'a')を挿入します。 クエリは正常、1 行が影響を受けました (0.00 秒) セッション2> テーブル t1 を切り捨てます。 クエリは正常、影響を受けた行は 0 行 (0.46 秒) セッション1>コミット; クエリは正常、影響を受けた行は 0 行 (0.35 秒) セッション1> t1から*を選択します。 空のセット (0.00 秒) ライブラリの結果を見てみましょう session1> slowtech.t1 から * を選択します。 +------+------+------+ | ID | 名前 | c1 | +------+------+------+ | 1 | a | NULL | +------+------+------+ セット内の行数 (0.00 秒) binlog の内容を見ると、切り捨て操作が最初に記録され、挿入操作が後で記録されていることがわかります。 # 7140 で #180714 19:32:14 サーバー ID 1 end_log_pos 7261 クエリ thread_id=31 exec_time=0 error_code=0 タイムスタンプを 1531567934/*!*/ に設定します。 テーブル t1(id int,name varchar(10)) を作成 engine=innodb //*!*/; # 7261 で #180714 19:32:30 サーバー ID 1 end_log_pos 7333 クエリ thread_id=32 exec_time=0 error_code=0 タイムスタンプを 1531567950/*!*/ に設定します。 始める //*!*/; # 7333で #180714 19:32:30 サーバー ID 1 end_log_pos 7417 クエリ thread_id=32 exec_time=0 error_code=0 タイムスタンプを 1531567950/*!*/ に設定します。 テーブルt1を切り捨てる //*!*/; # 7417 で #180714 19:32:30 サーバー ID 1 end_log_pos 7444 Xid = 422 専念 /*!*/; # 7444 で #180714 19:32:34 サーバー ID 1 end_log_pos 7516 クエリ thread_id=31 exec_time=0 error_code=0 タイムスタンプを 1531567954/*!*/ に設定します。 始める //*!*/; # 7516 で #180714 19:32:24 サーバー ID 1 end_log_pos 7611 クエリ thread_id=31 exec_time=0 error_code=0 タイムスタンプを 1531567944/*!*/ に設定します。 t1 に値(1,'a') を挿入する //*!*/; # 7611 で #180714 19:32:34 サーバー ID 1 end_log_pos 7638 Xid = 421 専念 /*!*/; セッション 2 がテーブル削除操作を実行すると、マスターとスレーブの関係が中断されます。 興味深いことに、セッション 2 がテーブル変更操作を実行すると、操作は依然としてブロックされ、ブロック時間は innodb_lock_wait_timeout パラメータによって制限されます。 mysql> プロセスリストを表示します。 +----+-------+-----------+----------+--------+-------+-------------------+----------------------------+ | ID | ユーザー | ホスト | db | コマンド | 時間 | 状態 | 情報 | +----+-------+-----------+----------+--------+-------+-------------------+----------------------------+ | 54 | root | localhost | NULL | クエリ | 0 | NULL | プロセスリストを表示 | | 58 | ルート | ローカルホスト | slowtech | スリープ | 1062 | | NULL | | 60 | root | localhost | slowtech | クエリ | 11 | tmp テーブルにコピー | alter table t1 add c1 int | +----+-------+-----------+----------+--------+-------+-------------------+----------------------------+ セット内の行数 (0.00 秒) MDLの基本概念 まずは公式声明を見てみましょう。
上記の説明から、 1. MDL の本来の目的は、トランザクション内のテーブルの構造が変更されないように保護することです。 2. ここで言及するトランザクションには、明示的なトランザクションと AC-NL-RO (自動コミット非ロック読み取り専用) トランザクションの 2 種類が含まれます。明示的なトランザクションには、1. AutoCommit がオフになっている操作と、2. begin または start transaction で開始された操作の 2 種類があります。 AC-NL-RO は、AutoCommit がオンになっている選択操作として理解できます。 3. MDL はトランザクション レベルであり、トランザクションが終了した後にのみ解放されます。これに先立って、実際に同様の保護メカニズムが存在しましたが、それはステートメント レベルのものでした。 MDL はテーブルだけでなく、次の表に示すように他のオブジェクトにも適用できることに注意してください。ここで、「待機状態」は「show processlist」の状態に対応します。 データベースの同時実行性を向上させるために、MDL は 11 種類に分かれています。
よく使用されるものは MDL_SHARED_READ、MDL_SHARED_WRITE、MDL_EXCLUSIVE で、それぞれ SELECT 操作、DML 操作、DDL 操作に使用されます。その他の対応する操作については、ソース コード sql/mdl.h を参照してください。 MDL_EXCLUSIVEの公式説明は、
つまり、MDL_EXCLUSIVE は排他ロックです。保持期間中は、SELECT や DML 操作など、他の種類の MDL を許可することはできません。 このため、DDL 操作がブロックされると、後続の他の操作もブロックされます。 MDLに関する補足情報 1. MDL の最大待機時間は lock_wait_timeout パラメータによって決定され、デフォルト値は 31536000 (365 日) です。ツールを使用して DDL 操作を実行する場合、この値は適切ではありません。実際、pt-online-schema-change と gh-ost は対応する調整を行っており、前者は 60 秒、後者は 3 秒かかります。 2. SQL 文が構文的に有効であっても、実行中に列名が存在しないなどのエラーが発生した場合は、MDL ロックも取得され、トランザクションが終了するまで解放されません。 要約する 上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に一定の参考学習価値を持つことを願っています。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM を応援していただきありがとうございます。 以下もご興味があるかもしれません:
|
<<: Vue における v-for のキーの一意性の詳細な説明
>>: Nginx http ヘルスチェック構成プロセス分析
それは何ですか? Spring Boot は、Spring オープンソース組織のサブプロジェクトであ...
1. ホストMacbookにHOSTをセットアップする前回のドキュメントでは仮想マシンの静的 IP ...
>1 データベースを起動するcmd コマンド ウィンドウで、「sqlplus」を直接入力して ...
Linux インストール JDK1.8 手順1. CentOS に独自の openJDK があるかど...
MySQLへの接続ここでは、リモート接続に navicat を使用します。MySQL に接続する前に...
目次序文シナリオシミュレーション要約する序文最近、sql_mode の話題については何度も話し合われ...
オリジナルリンクhttps://github.com/XboxYan/no…ボタンは、おそらく We...
従来のソフトウェアから Web ウェアへの段階的な移行の傾向の中で、デザイン パターンとテクノロジは...
序文: Vue プロジェクトで現在のマウスの座標を取得するにはどうすればよいでしょうか。ここで共有す...
目次序文オプション1:オプション2:オプション3:オプション4(最終的に採用されたオプション):要約...
本日は、色彩の応用に関する優れた事例を 30 件集めて、皆さんにご紹介したいと思います。これらの事例...
以前書いた内容が詳細さに欠けていたため、今回は修正・補足しました。ただし、以前の MySQL バージ...
失敗の原因今日、カルーセルを書いていたときに、overflow;hidden; が失敗する可能性があ...
この記事の例では、セカンダリメニュー効果を実現するためのJSの具体的なコードを参考までに共有していま...
この記事では、例を使用して MySQL インデックスの原理と使用方法を説明します。ご参考までに、詳細...