MySQLでロックのエスカレーションは発生するのか気になったので調べてみました。
ロック・エスカレーションとは
下記はMySQLマニュアル:ロックエスカレーションの引用です。
-
一部のデータベースシステムで使用される操作で、多数の行ロックを単一のテーブルロックに変換し、メモリー領域を節約しますが、テーブルへの同時アクセスを削減します。 InnoDB では、行ロックに領域効率の高い表現が使用されるため、lock エスカレーションは必要ありません。
つまり、ロック・エスカレーションが発生すると行ロックがテーブルロックに変換される代わりにメモリ領域が節約されます。
行ロックが大量に発生するとメモリの消費量も高くなるので、その対策としてロック・エスカレーションという仕組みが一部のDBで用意されているようです。
MySQLのロックエスカレーション
MySQLでは、ロック・エスカレーションが発生しないそうです。
下記はMySQL8.0マニュアルの引用。
-
InnoDB は、行レベルでロックを実行し、Oracle のスタイルでクエリーを非ロック consistent reads としてデフォルトで実行します。 InnoDB のロック情報は領域効率に優れて格納されるため、ロックのエスカレーションは必要ありません。 通常、いくつかのユーザーは、InnoDB メモリーを使い果たさずに、InnoDB テーブルのすべての行または行のランダムなサブセットをロックできます。
次はMysql4.1 マニュアルの引用。
-
InnoDB トランザクションモデルの目標は、マルチバージョニングのデータベースの優れた特性を、従来の 2 相ロックと組み合わせることでした。 InnoDB は、行レベルでロックを行い、デフォルトではクエリを Oracle 式の非ロックの一貫性読み取りとして実行します。 InnoDB のロックテーブルはスペース効率の高い方法で格納されるため、ロックエスカレーションは不要です。一般には、複数のユーザがデータベースのあらゆるレコードまたはレコードのランダムなサブセットをロックすることができ、InnoDB でメモリ不足が発生することもありません。
参考:Mysql4.1 マニュアル
thinkitさんの記事にもMySQLはロック・エスカレーションを行わないという記載があります。
-
なお、PostgreSQLもMySQLも行レベルのロック量が増えることによって、自動的にテーブルロックに変更されるロックのエスカレーションは発生しません。
参考:徹底比較!! PostgreSQL vs MySQL(ロックレベル)
下記はMySQLのInnoDBのロック挙動調査をされた方の調査結果引用
-
テーブルロックと効果が等しい
実際は全ての行に対してロックをかけているだけであり、InnoDBはロックエスカレーションしない
ロック・エスカレーションのあるDB、ないDB
ロック・エスカレーションのある機能があるDB、ないDBをまとめてみました。
ロック・エスカレーションのないDB
MySQL
PostgreSQL
OracleDB
参考:Mysqlマニュアル
参考:徹底比較!! PostgreSQL vs MySQL(ロックレベル)
参考:やっぱりOracleが好き
ロック・エスカレーションのあるDB
DB2
SQL Server
参考:https://www.ibm.com/docs/ja/db2/11.5?topic=management-lock-escalation
参考:https://learn.microsoft.com/ja-jp/troubleshoot/sql/database-engine/performance/resolve-blocking-problems-caused-lock-escalation