MySQL デッドロックのトラブルシューティングの分析例
問題が発生します
# ある日の午後、突然システムが警告を発し、例外をスローしました: よく見るとトランザクションのロールバック例外のようでした。デッドロックのためロールバックされたと書かれていました。デッドロックの問題であることが判明しました。Mysql のロックについてはまだある程度理解しているので、この問題を積極的に調査し始めました。 。 まず、データベースで Innodb Status を検索します。最後のデッドロック情報が Innodb Status に記録されます。次のコマンドを入力します: エンジンの INNODB ステータスを表示 デッドロック情報は次のとおりです。SQL 情報は単純に処理されています: ------------------------------------ 最後に検出されたデッドロック ------------------------------------ 2019-02-22 15:10:56 0x7eec2f468700 *** (1) トランザクション: トランザクション 2660206487、アクティブ 0 秒開始インデックス read mysql テーブルは使用中 1、ロックされています 1 ロック待機 2 つのロック構造体、ヒープ サイズ 1136、1 行のロック# MySQL スレッド ID 31261312、OS スレッド ハンドル 139554322093824、クエリ ID 11624975750 10.23.134.92 erp_crm__6f73 更新中
/*id:3637ba36*/UPDATE tenant_config SET
オープンカードポイント = 0
ここで、テナント ID = 123
*** (1) このロックが許可されるのを待っています:
RECORD LOCKS スペース ID 1322 ページ番号 534 n ビット 960 テーブルのインデックス uidx_tenant ——erp_crm_member_plan——. ——tenant_config—— trx id 2660206487 lock_mode X は、rec をロックしますが、ギャップ待機はしません
*** (2) トランザクション:
トランザクション 2660206486、アクティブ 0 秒開始インデックス read
mysql テーブルは使用中 1、ロックされています 1
3 つのロック構造体、ヒープ サイズ 1136、2 つの行ロック
# MySQL スレッド ID 31261311、OS スレッド ハンドル 139552870532864、クエリ ID 11624975758 10.23.134.92 erp_crm__6f73 更新中 /*id:3637ba36*/UPDATE tenant_config SET オープンカードポイント = 0 ここで、テナント ID = 123 *** (2) ロックを保持します (S): RECORD LOCKS スペース ID 1322 ページ番号 534 n ビット 960 テーブルのインデックス uidx_tenant ——erp_crm_member_plan——. ——tenant_config—— trx id 2660206486 ロック モード S *** (2) このロックが許可されるのを待っています: RECORD LOCKS スペース ID 1322 ページ番号 534 n ビット 960 テーブルのインデックス uidx_tenant ——erp_crm_member_plan——. ——tenant_config—— trx id 2660206486 lock_mode X は、rec をロックしますが、ギャップ待機はしません *** トランザクションをロールバックします (1) ---------------- このデッドロック ログを簡単に分析して説明します。トランザクション 1 が Update ステートメントを実行するとき、uidx_tenant インデックスを取得し、次に where 条件で X ロック (行ロック) を取得する必要があります。トランザクション 2 は同じ Update ステートメントを実行し、次のことも考えます。 uidx_tenant. X ロック (行ロック) を取得するためにデッドロックが発生し、トランザクション 1 がロールバックされました。当時私は非常に混乱していましたが、デッドロックが発生するための必要条件を思い出しました: 相互に排他的です。 条件をリクエストして保留します。 条件の剥奪はありません。 待機サイクル。ログを見ると、トランザクション 1 とトランザクション 2 が同じ行の行ロックを競合していることがわかります。これは、以前の周期的なロックの競合とは少し異なります。どう見ても満たすことができません。循環待機状態。同僚から注意を受けましたが、デッドロックログは調査できないため、業務コードと業務ログから問題を調査するしかありません。このコードのロジックは次のとおりです: public int saveTenantConfig(PoiContext poiContext, TenantConfigDO tenantConfig) { 試す {###### return tenantConfigMapper.saveTenantConfig(poiContext.getTenantId(), poiContext.getPoiId(), tenantConfig); } catch (DuplicateKeyException e) { LOGGER.warn("[saveTenantConfig] 主キーの競合。レコードを更新します。context:{}, config:{}", poiContext, tenantConfig); return tenantConfigMapper.updateTenantConfig(poiContext.getTenantId(), tenantConfig); } } このコードの意味は、構成ファイルを保存することです。一意のインデックスの競合が発生した場合、ファイルは更新されます。もちろん、ここでの記述はあまり標準化されていない可能性があります。実際には、 を使用できます。 … に挿入 重複キー更新時 同様の効果が得られますが、これを使用しても実際にはデッドロックが発生します。コードを読んだ後、同僚が当時の業務ログ を送ってくれました。 同時に発生した 3 つのログがあることがわかります。これは、一意のインデックスの競合が発生して更新されたステートメントを入力し、その後デッドロックが発生したことを示しています。この時点で、ようやく答えが少し明確になったように思えます。 この時点で、テーブル構造を次のように見てみましょう (簡略化): テーブルの作成 ——tenant_config—— (——id—— bigint(21) NOT NULL AUTO_INCREMENT,
——tenant_id—— int(11) NOT NULL,
——open_card_point—— int(11) デフォルト NULL,
主キー (——id——)、
一意のキー ——uidx_tenant—— (——tenant_id——)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT
tenant_id は一意のインデックスとして使用され、挿入と更新の where 条件はすべて一意のインデックスに基づいています。
tenant_config SET
を更新します オープンカードポイント = 0
ここで、テナント ID = 123
この時点では挿入時のユニークインデックスのロックが関係しているような気がしますので、次のステップで詳しく分析してみましょう。
詳細な分析
上では 3 つのトランザクションが更新ステートメントに入ると言われましたが、説明を簡単にするため、同時に更新ステートメントに入るには 2 つのトランザクションだけが必要です。次の表は、発生プロセス全体を示しています:
ヒント: S ロックは共有ロック、X ロックは相互排他ロックです。一般に、X ロック、S ロック、および X ロックは相互排他的ですが、S ロックと S ロックは相互排他的ではありません。
上記のプロセスから、このデッドロックの鍵は S ロックの取得であることがわかりますが、なぜ再挿入時に S ロックを取得する必要があるのでしょうか?一意のインデックスを検出する必要があるためですか? RR 分離レベルでは、読み取りたい場合は現在の読み取りとなるため、実際には S ロックを追加する必要があります。ここで、ユニークキーが既に存在していることが分かり、このとき、2つのトランザクションのSロックにより更新の実行がブロックされ、上記のループ待ち状態が形成される。
ヒント: MVCC では、現在の読み取りとスナップショットの読み取りの違い: 最新のデータを取得するには、現在の読み取りは毎回ロックする必要があります (共有ロックまたはミューテックス ロックを使用できます)。一方、スナップショットの読み取りはこのトランザクションの開始を読み取ります。スナップショットは元に戻すログを通じて実装されました。
これがデッドロック全体の原因です。この種のデッドロックが発生するもう 1 つの状況は、同時に 3 つの挿入操作がある場合です。最初に挿入されたトランザクションが最後にロールバックされると、これは他の 2 つの操作でも発生します。トランザクションのデッドロック。
解決###### ここでの中心的な問題は、S ロックを取り除くことです。参考までに 3 つの解決策を示します:
RR 分離レベルを RC 分離レベルまで下げます。ここでは、RC 分離レベルはスナップショット読み取りを使用するため、S ロックは追加されません。
再度挿入する場合は、select * for updateを使用してXロックを追加すると、Sロックが追加されなくなります。
分散ロックは事前に追加することも、Redis や ZK などを使用することもできます。分散ロックについては、私のこの記事を参照してください。分散ロックについて話しましょう
最初の方法は、分離レベルを簡単に変更できないため、あまり現実的ではありません。 3 番目の方法はさらに面倒です。そこで最終的に落ち着いたのが 2 番目の方法です。
以上がMySQL デッドロックのトラブルシューティングの分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









MySQLデータベースでは、ユーザーとデータベースの関係は、アクセス許可と表によって定義されます。ユーザーには、データベースにアクセスするためのユーザー名とパスワードがあります。許可は助成金コマンドを通じて付与され、テーブルはCreate Tableコマンドによって作成されます。ユーザーとデータベースの関係を確立するには、データベースを作成し、ユーザーを作成してから許可を付与する必要があります。

データ統合の簡素化:AmazonrdsmysqlとRedshiftのゼロETL統合効率的なデータ統合は、データ駆動型組織の中心にあります。従来のETL(抽出、変換、負荷)プロセスは、特にデータベース(AmazonrdsmysQlなど)をデータウェアハウス(Redshiftなど)と統合する場合、複雑で時間がかかります。ただし、AWSは、この状況を完全に変えたゼロETL統合ソリューションを提供し、RDSMYSQLからRedshiftへのデータ移行のための簡略化されたほぼリアルタイムソリューションを提供します。この記事では、RDSMysQl Zero ETLのRedshiftとの統合に飛び込み、それがどのように機能するか、それがデータエンジニアと開発者にもたらす利点を説明します。

MySQLには、無料のコミュニティバージョンと有料エンタープライズバージョンがあります。コミュニティバージョンは無料で使用および変更できますが、サポートは制限されており、安定性要件が低く、技術的な能力が強いアプリケーションに適しています。 Enterprise Editionは、安定した信頼性の高い高性能データベースを必要とするアプリケーションに対する包括的な商業サポートを提供し、サポートの支払いを喜んでいます。バージョンを選択する際に考慮される要因には、アプリケーションの重要性、予算編成、技術スキルが含まれます。完璧なオプションはなく、最も適切なオプションのみであり、特定の状況に応じて慎重に選択する必要があります。

1.正しいインデックスを使用して、データの量を削減してデータ検索をスピードアップしました。テーブルの列を複数回検索する場合は、その列のインデックスを作成します。あなたまたはあなたのアプリが基準に従って複数の列からのデータが必要な場合、複合インデックス2を作成します2。選択した列のみを避けます。必要な列のすべてを選択すると、より多くのサーバーメモリを使用する場合にのみサーバーが遅くなり、たとえばテーブルにはcreated_atやupdated_atやupdated_atなどの列が含まれます。

MySQLのユーザー名とパスワードを入力するには:1。ユーザー名とパスワードを決定します。 2。データベースに接続します。 3.ユーザー名とパスワードを使用して、クエリとコマンドを実行します。

MySQLデータベースパフォーマンス最適化ガイドリソース集約型アプリケーションでは、MySQLデータベースが重要な役割を果たし、大規模なトランザクションの管理を担当しています。ただし、アプリケーションのスケールが拡大すると、データベースパフォーマンスのボトルネックが制約になることがよくあります。この記事では、一連の効果的なMySQLパフォーマンス最適化戦略を検討して、アプリケーションが高負荷の下で効率的で応答性の高いままであることを保証します。実際のケースを組み合わせて、インデックス作成、クエリ最適化、データベース設計、キャッシュなどの詳細な主要なテクノロジーを説明します。 1.データベースアーキテクチャの設計と最適化されたデータベースアーキテクチャは、MySQLパフォーマンスの最適化の基礎です。いくつかのコア原則は次のとおりです。適切なデータ型を選択し、ニーズを満たす最小のデータ型を選択すると、ストレージスペースを節約するだけでなく、データ処理速度を向上させることもできます。

MySQLのコピーと貼り付けには、次の手順が含まれています。データを選択し、Ctrl C(Windows)またはCMD C(MAC)でコピーします。ターゲットの場所を右クリックして、貼り付けまたはCTRL V(Windows)またはCMD V(MAC)を使用します。コピーされたデータは、ターゲットの場所に挿入されるか、既存のデータを置き換えます(データが既にターゲットの場所に存在するかどうかに応じて)。

データベース酸属性の詳細な説明酸属性は、データベーストランザクションの信頼性と一貫性を確保するための一連のルールです。データベースシステムがトランザクションを処理する方法を定義し、システムのクラッシュ、停電、または複数のユーザーの同時アクセスの場合でも、データの整合性と精度を確保します。酸属性の概要原子性:トランザクションは不可分な単位と見なされます。どの部分も失敗し、トランザクション全体がロールバックされ、データベースは変更を保持しません。たとえば、銀行の譲渡が1つのアカウントから控除されているが別のアカウントに増加しない場合、操作全体が取り消されます。 TRANSACTION; updateaccountssetbalance = balance-100wh
