特別なMysqlデッドロックのシナリオを覚えておいてください
余談
mysqlのバージョンは5.7.27で、分離レベルはRRです。
1.故障現象
Mysqlのスレーブノード、データは同期されず、SQLスレッドが中断されたことがチェックで検出され、次の情報がerror.logで検出されました。
| master_prdxxx001 | 1 | NULL | OFF | xxxxdab9-49ed-11e8-b5ee-005056axxx:122598975 | 1213 | Worker 1 failed executing transaction 'e3bedab9-49ed-11e8-b5ee-005056a1a8ba:122598975' at master log mysql-bin.000405, end_log_pos 185432301; Deadlock found when trying to get lock; try restarting transaction | 2020-06-14 01:38:49 |
デッドロックが発生しているのがわかりますが、スレーブノードがサービスを書いていないのはおかしいです。
問題が発生したため、SQLステートメントを取得するスクリプトを作成し、不審な挿入および更新ステートメントを見つけました
。a_tmpは一時的に使用するテーブルで、aはマスターノードのデータを同期する必要があるテーブルです。
insert into a_tmp select * from a;
update a_tmp set xx=.... where ...;
上記のような文章が原因と思われるため、シミュレーションテストを実施しました。
1.同じテーブルtb01とtb02を作成し、2つのデータをtb01に挿入します。
2. updateステートメントとinsertステートメントをシミュレートして、
セッション1をロックします。
セッション2:
セッション1に戻り
ます。この時点でロック待機が発生し、tb01 id = 2のレコードが他のトランザクションによってロックされていることを示します。
セッション2に戻る:
デッドロックが発生したため、デッドロックの原因と判断できる
2.トラブルシューティング
innodbエンジンを使用して、通常の状況では、読み取りと書き込みはお互いをブロックしませんが、ここでの特別なケースは次のとおり
です:1.単純なxxxからxxxを選択する ;しかし、xxxに挿入xxxからxxxを選択する ;
2.分離レベルRR;
このmysqlインスタンスはエッジシステムであるため、関連する担当者と通信した後、データがノードから直接取得されるシナリオがあり、これがこの状況の原因であることがわかりました。
解決策:宝くじに関連するセッションをRCレベルに変更し、デッドロックを解消します。
セッショントランザクション分離レベルをREAD COMMITTEDに設定します。
三、まとめ
今回は特別なシナリオのみに遭遇しましたが、対応するロックの細分性が分離レベルごとに異なることも思い出しました。
ああ、悪くない!------間違いを指摘し、より良い方法を追加することを歓迎します