テーブルのロックとテーブルのロック解除
TiDBでは、クライアントセッションがテーブルロックを取得して、他のセッションと連携してテーブルにアクセスしたり、他のセッションによるテーブルの変更を防止したりできます。セッションは、自身のロックのみを取得または解放できます。あるセッションが別のセッションのロックを取得したり、別のセッションが保持しているロックを解放したりすることはできません。
LOCK TABLES 、現在のクライアントセッションのテーブルロックを取得します。ロック対象となる各オブジェクトに対してLOCK TABLESおよびSELECT権限を持っている場合は、共通テーブルのテーブルロックを取得できます。
UNLOCK TABLES 、現在のセッションによって保持されているすべてのテーブル ロックを明示的に解放します。2 LOCK TABLES 、新しいロックを取得する前に、現在のセッションによって保持されているすべてのテーブル ロックを暗黙的に解放します。
テーブルロックは、他のセッションによる読み取りや書き込みから保護します。1 ロックを保持しているセッションは、 WRITEやTRUNCATE TABLE DROP TABLEのテーブルレベルの操作を実行できます。
注記:
テーブル ロック機能はデフォルトで無効になっています。
- TiDB Self-Managed の場合、テーブル ロック機能を有効にするには、すべての TiDB インスタンスの構成ファイルで
enable-table-lock~true設定する必要があります。- TiDB Cloud Dedicated の場合、テーブル ロック機能を有効にするには、 TiDB Cloudサポート連絡して
enable-table-lockをtrueに設定する必要があります。- TiDB CloudスターターおよびTiDB Cloudエッセンシャル場合、
enable-table-lockからtrue設定はサポートされていません。
概要
- 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ロックを取得できません。
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では、セッションBの書き込み要求はセッションAがテーブルロックを解放するまでブロックされ、他のセッションからのテーブルロック要求は現在のセッションが
WRITEロックを解放するまでブロックされます。 - TiDBでは、
LOCK TABLES文に必要なロックが別のセッションによって保持されている場合、LOCK TABLESの文は待機する必要があり、この文の実行時にエラーが返されます。MySQLでは、この文はロックが取得されるまでブロックされます。 - TiDBでは、
LOCK TABLES文はクラスタ全体で有効です。MySQLでは、この文は現在のMySQLサーバーでのみ有効であり、NDBクラスタとは互換性がありません。
テーブルロックの解除
TiDB セッションでトランザクションが明示的に開始されると (たとえば、 BEGINステートメントを使用)、TiDB はセッションによって保持されているテーブル ロックを暗黙的に解放しませんが、MySQL は解放します。