MySQL でテーブル メタデータ ロックを待機する理由と方法

MySQL でテーブル メタデータ ロックを待機する理由と方法

MySQL が alter table などの DDL 操作を実行すると、テーブル メタデータ ロックの待機シナリオが発生する可能性があります。さらに、TableA のテーブル変更操作がテーブル メタデータ ロックの待機状態で停止すると、TableA に対する後続の操作 (読み取りを含む) も、テーブルを開く段階でテーブル メタデータ ロックの待機のロック待機キューに入るため、実行できなくなります。このようなロック待機キューが本番環境のコア テーブルに出現すると、悲惨な結果を招くことになります。

alter table が Waiting for table metadata lock を生成する理由は、実は非常に単純で、通常は次のような単純なシナリオによるものです。

シナリオ 1: 長いトランザクションの実行により DDL がブロックされ、同じテーブルに対する後続のすべての操作がブロックされる

show processlist を通じて、TableA で進行中の操作 (読み取りを含む) があることがわかります。この時点で、alter table ステートメントはメタデータ排他ロックを取得できず、待機します。

これは最も基本的な状況であり、MySQL 5.6 のオンライン DDL と競合しません。一般的なテーブル変更操作中(下図参照)は、作成後のステップで排他メタデータ ロックが取得されます。テーブル変更プロセス(通常最も時間のかかるステップ)が実行されると、テーブルへの読み取りと書き込みは正常に続行されます。これはオンライン DDL のパフォーマンスであり、以前のようにテーブル変更プロセス全体で書き込みがブロックされることはありません。 (もちろん、すべての種類の変更操作がオンラインで実行できるわけではありません。詳細については、公式マニュアルを参照してください: http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html)
解決策: DDL が配置されているセッションを終了します。

シナリオ 2: トランザクションが送信されず、DDL がブロックされ、同じテーブルに対する後続のすべての操作がブロックされる

show processlist では TableA の操作を確認できませんが、実際にはコミットされていないトランザクションがあり、information_schema.innodb_trx で確認できます。トランザクションが完了するまで、TableA のロックは解除されず、alter table はメタデータの排他ロックを取得しません。

解決策: select * from information_schema.innodb_trx\G を使用して、コミットされていないトランザクションの sid を見つけ、それを強制終了してロールバックします。

シナリオ3:

show processlist を通じて TableA に対して操作は行われず、information_schema.innodb_trx には進行中のトランザクションはありません。これは、明示的なトランザクションで、TableA に対して失敗した操作が実行された (たとえば、存在しないフィールドが照会された) ためであると考えられます。この時点では、トランザクションは開始されていませんが、失敗したステートメントによって取得されたロックは依然として有効であり、解放されていません。失敗したステートメントは、performance_schema.events_statements_current テーブルから見つけることができます。

公式マニュアルには次のように記載されています。

サーバーが、構文的には有効だが実行中に失敗したステートメントのメタデータ ロックを取得した場合、ロックは早期に解放されません。失敗したステートメントはバイナリ ログに書き込まれ、ロックによってログの一貫性が保護されるため、ロックの解放はトランザクションの終了まで延期されます。

つまり、構文エラーを除いて、他のエラーのあるステートメントによって取得されたロックは、トランザクションがコミットまたはロールバックされるまで解放されません。しかし、この動作の理由は理解しにくいです。失敗したステートメントはバイナリ ログに書き込まれ、失敗したステートメントはバイナリ ログにまったく記録されないため、ロックによってログの一貫性が保護されるからです。

解決策: performance_schema.events_statements_current から sid を見つけて、セッションを強制終了します。DDL が配置されているセッションを強制終了することもできます。

つまり、alter table ステートメントは非常に危険です (実際には、その危険性はコミットされていないトランザクションや長いトランザクションによって引き起こされます)。操作の前に、操作対象のテーブルで進行中の操作がないこと、コミットされていないトランザクションがないこと、明示的なトランザクションにエラー ステートメントがないことを確認することをお勧めします。監視なしで実行されるテーブル変更メンテナンス タスクがある場合は、メタデータ ロックの長時間待機を回避するために、lock_wait_timeout を介してタイムアウトを設定するのが最適です。

以下もご興味があるかもしれません:
  • MySQLのテーブル構造を変更する際に知っておきたいメタデータロックの詳しい解説
  • MYSQL メタデータ ロック (MDL ロック) MDL ロックの問題分析
  • MySQLスレーブは列の外部キーチェックと自動増分ロックを遅延します
  • MySQLのネクストキーロックのロック範囲についての簡単な説明
  • MySQL ロック制御同時実行方法
  • PHP+MySQL の高同時ロックトランザクション処理問題の解決方法
  • MYSQL メタデータ ロック (MDL ロック) の理論とロック タイプ テスト

<<:  webpackでHMRを手動で実装するいくつかの方法

>>:  VMwareがwin10ホームバージョンに64ビットオペレーティングシステムをインストールできない問題を解決します

推薦する

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

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

MySQL 5.7.21 解凍版のインストールと設定方法のグラフィックチュートリアル

私は頻繁にシステムをインストールするので、インストールのたびにいくつかのソフトウェアを再インストール...

Docker で Portainer ビジュアル インターフェースを構築するための詳細な手順

前回述べた問題を解決するために、オンラインで検索したところ、非常に優れたビジュアル インターフェース...

Linux に Python 3.8.1 をインストールするための詳細なチュートリアル

この例では、Linux への Python 3.8 のインストールを例に挙げます。 1. 依存パッケ...

Linux での MongoDB のインストールと設定のチュートリアル

MongoDBインストールYumを使用してインストールすることを選択する1. repoファイルを作成...

GET POSTの違い

1. Get はサーバーからデータを取得するために使用され、Post はサーバーにデータを渡すために...

Centos6 で 20TB を超えるディスクをパーティション分割してフォーマットするためのサンプル コード

1. サーバー環境の構成: 1. ディスクパーティションを確認します。最近、あるプロジェクト内のサー...

MySQL8インストーラーバージョングラフィックチュートリアル

インストール必要な書類は下部に記載されていますステップ1 mysql-installer-web-c...

さまざまな種類のMySQLインデックス

インデックスとは何ですか?インデックスは、データベース ストレージ エンジンが指定されたデータをすば...

Ubuntu 18.04にMySQL 5.7をインストールする

この記事は MySQL 公式サイトを参考にしてまとめたものであり、遭遇したいくつかの問題も記録されて...

ドメイン名を nginx サービスにバインドする方法

nginx.conf で複数のサーバーを設定します。 http リクエストを処理する際、nginx ...

Docker で TLS と CA 認証を有効にする方法

目次1. 証明書を生成する2. リモートを有効にする3. リモート接続3.1 Jenkins接続3....

404エラーページを作成する際に注意すべき問題の簡単な分析

ウェブサイトを最適化するときは、エラー ページの使い方を学ぶ必要があります。たとえば、ウェブサイトに...

CSSのline-heightとheightの詳細な説明

最近、CSS インターフェースに取り組んでいるときに、line-height と height とい...

Nginx 正規表現関連のパラメータとルールの紹介

序文最近、私はクライアントのサーバー構成を支援しており、Nginx 構成ファイルを頻繁に変更していま...