テーブルのロックとテーブルのロック解除
TiDB を使用すると、クライアント セッションは、他のセッションと連携してテーブルにアクセスしたり、他のセッションがテーブルを変更できないようにする目的で、テーブル ロックを取得できます。セッションは、それ自体に対してのみロックを取得または解放できます。あるセッションが別のセッションのロックを取得したり、別のセッションが保持しているロックを解放したりすることはできません。
LOCK TABLES現在のクライアント セッションのテーブル ロックを取得します。ロックするオブジェクトごとにLOCK TABLESおよびSELECT権限を持っている場合は、共通テーブルのテーブル ロックを取得できます。
UNLOCK TABLES現在のセッションで保持されているすべてのテーブル ロックを明示的に解放します。 LOCK TABLES新しいロックを取得する前に、現在のセッションで保持されているすべてのテーブル ロックを暗黙的に解放します。
テーブル ロックは、他のセッションによる読み取りまたは書き込みから保護します。 WRITEロックを保持するセッションは、 DROP TABLEやTRUNCATE TABLEなどのテーブルレベルの操作を実行できます。
あらすじ
- LockTablesDef
- UnlockTablesDef
- LockType
LockTablesDef
::= 'LOCK' ( 'TABLES' | 'TABLE' ) TableName LockType ( ',' TableName LockType)*
UnlockTablesDef
::= 'UNLOCK' 'TABLES'
LockType
::= 'READ' ('LOCAL')?
| 'WRITE' ('LOCAL')?
テーブル ロックの取得
LOCK TABLESステートメントを使用して、現在のセッション内でテーブル ロックを取得できます。次のロック タイプを使用できます。
READロック:
- このロックを保持しているセッションは、テーブルを読み取ることはできますが、書き込むことはできません。
- 複数のセッションが、同じテーブルから同時に
READロックを取得できます。 - 他のセッションは、明示的に
READロックを取得しなくてもテーブルを読み取ることができます。
READ LOCALロックは、MySQL との構文互換性のためだけのものであり、サポートされていません。
WRITEロック:
- このロックを保持しているセッションは、テーブルを読み書きできます。
- このロックを保持しているセッションのみがテーブルにアクセスできます。ロックが解除されるまで、他のセッションはアクセスできません。
WRITE LOCALロック:
- このロックを保持しているセッションは、テーブルを読み書きできます。
- このロックを保持しているセッションのみがテーブルにアクセスできます。他のセッションはテーブルを読み取ることはできますが、書き込むことはできません。
LOCK TABLESステートメントが必要とするロックが別のセッションによって保持されている場合、 LOCK TABLESステートメントは待機する必要があり、このステートメントの実行時にエラーが返されます。次に例を示します。
> LOCK TABLES t1 READ;
ERROR 8020 (HY000): Table 't1' was locked in WRITE by server: f4799bcb-cad7-4285-8a6d-23d3555173f1_session: 2199023255959
上記のエラー メッセージは、TiDB f4799bcb-cad7-4285-8a6d-23d3555173f1の ID 2199023255959のセッションがテーブルt1に対してWRITEロックを既に保持していることを示しています。したがって、現在のセッションはテーブルt1でREADロックを取得できません。
1 つのLOCK TABLESステートメントで同じテーブル ロックを複数回取得することはできません。
> LOCK TABLES t WRITE, t READ;
ERROR 1066 (42000): Not unique table/alias: 't'
テーブル ロックの解放
セッションによって保持されているテーブル ロックが解放されると、それらはすべて同時に解放されます。セッションは、そのロックを明示的または暗黙的に解放できます。
- セッションは
UNLOCK TABLESで明示的にロックを解除できます。 - すでにロックを保持しているときに、セッションが
LOCK TABLESステートメントを発行してロックを取得すると、新しいロックが取得される前に、既存のロックが暗黙的に解放されます。
クライアント セッションの接続が終了すると、正常または異常にかかわらず、TiDB はセッションによって保持されているすべてのテーブル ロックを暗黙的に解放します。クライアントが再接続すると、ロックは無効になります。このため、クライアントで自動再接続を有効にすることはお勧めしません。自動再接続を有効にすると、再接続が発生したときにクライアントに通知されず、すべてのテーブル ロックまたは現在のトランザクションが失われます。対照的に、自動再接続が無効になっている場合、接続が切断されると、次のステートメントが発行されたときにエラーが発生します。クライアントはエラーを検出し、ロックの再取得やトランザクションのやり直しなどの適切なアクションを実行できます。
テーブルロックの制限と条件
KILLを使用して、テーブル ロックを保持しているセッションを安全に終了できます。
次のデータベースのテーブルでは、テーブル ロックを取得できません。
INFORMATION_SCHEMAPERFORMANCE_SCHEMAMETRICS_SCHEMAmysql
MySQL の互換性
テーブルロックの取得
- TiDB では、セッション A がすでにテーブル ロックを保持している場合、セッション B がテーブルに書き込もうとするとエラーが返されます。 MySQL では、セッション A がテーブル ロックを解放するまでセッション B の書き込み要求はブロックされ、現在のセッションが
WRITEのロックを解放するまで、他のセッションからのテーブル ロック要求はブロックされます。 - TiDB では、
LOCK TABLESステートメントが必要とするロックが別のセッションによって保持されている場合、LOCK TABLESステートメントは待機する必要があり、このステートメントの実行時にエラーが返されます。 MySQL では、このステートメントはロックが取得されるまでブロックされます。 - TiDB では、
LOCK TABLESステートメントはクラスター全体で有効です。 MySQL では、このステートメントは現在の MySQLサーバーでのみ有効であり、NDB クラスターとは互換性がありません。
テーブルロック解除
TiDB セッションで (たとえば、 BEGINステートメントを使用して) トランザクションが明示的に開始された場合、TiDB はセッションによって保持されているテーブル ロックを暗黙的に解放しません。しかしMySQLはそうします。