StackCareersEventRECRUITMySQL(innodb)のインデックスとDeadLock2022年12月2日こんにちは。今回は、人気のデータペースMySQL(innodb)のインデックスとDeadLockについてお話しできればと思います。そもそもデータベースのロックとは、並列処理によってデータの不整合が発生しないよう、同じデータを同時に更新・参照することを防ぐ仕組みです。MySQLのロックはインデックスと直接関係していて、インデックスを利用した検索・更新によってDeadLockが発生してしまう場合があります。今回は上記のようなことについて、1つの例を題材に簡単に解説します。以下のテーブルを作成します。Y以下のインデックスを作成します。BTREETransaction例えば、以下のような業務ロジックがあるとします。update;上記のようなTransactionAとTransactionBが同時に実行された場合、TransactionBの抽出結果が0行だったとしても、DeadLockが発生する可能性は高いです。原因はお分かりでしょうか。DeadLock解説DeadLock発生を解説する前に、まず、MySQL(innodb)のロックはどういう仕組みかを簡単に説明します。MySQLのロック対象は抽出した行ではなく、該当のインデックスを含む行です。(よく「抽出の行のみロックする」だと勘違いされる)このことを頭に入れた上で、先ほどの例でどのようなことが起きていたのか整理してみましょう。TransactionAの場合idはプライマリーインデックスのため、プライマリーインデックスにて以下のように順番にロックをかけます。id=1のプライマリーインデックスにロックをかけます。id=2のプライマリーインデックスにロックをかけます。TransactionBの場合usernameはセカンダリインデックスのため、以下のような順番でロックをかけます。セカンダリインデックスusername_indexにて、test3のものにロックをかけます。test3がid=2のため、さらに、id=2のプライマリーインデックスにロックをかけます。セカンダリインデックスusername_indexにて、test4のものにロックをかけます。test4がid=1のため、さらに、id=1プライマリーインデックスにロックをかけます。※statusにインデックスを張っていないため、YとNを無視して全部ロックをかけます。id=1がAによってロックされているため、ロック待ち状態になるとなり、DeadLockが発生してしまいます。終わりに今回はMySQLのインデックスとDeadLockについて簡単にご紹介しました。MySQLをシステム運用する上で、インデックス+非インデックスを条件にレコードを更新することもあると思います。検索条件に使用する非インデックスのカラムにインデックスを張る業務ロジックやTransaction中で実行するSQLを工夫するなどの対策・検討が必要かもしれません。DeadLock発生時の原因分析にこの記事が参考となれば幸いです。ココネでは一緒に働く仲間を募集中です。ご興味のある方は、ぜひこちらの採用特設サイトをご覧ください。22Category技術TagcoconeDeadLockMySQL一緒に働くエンジニアを募集していますココネのエンジニア採用はこちら感性をカタチに。株式会社%d人のブロガーが「いいね」をつけました。