MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  ...  /  MySQL でのテーブルのオープンとクローズの方法

8.4.3.1 MySQL でのテーブルのオープンとクローズの方法

mysqladmin status コマンドを実行すると、次のように表示されるはずです。

Uptime: 426 Running threads: 1 Questions: 11082
Reloads: 1 Open tables: 12

12 未満のテーブルがある場合、Open tables 値の 12 はある程度パズルになる可能性があります。

MySQL はマルチスレッド化されているため、特定のテーブルに対するクエリーを同時に発行するクライアントが多数存在する場合があります。 同じテーブルに対して、複数のクライアントセッションが異なる状態を持つ問題を最小にするため、テーブルは各同時セッションに独立して開かれます。 これは追加メモリーを使用しますが、一般にパフォーマンスは向上します。 MyISAM テーブルでは、テーブルを開いているクライアントごとに、データファイルに 1 つの追加のファイルディスクリプタが必要になります。 (対照的に、インデックスファイルディスクリプタはすべてのセッションで共有されます。)

table_open_cache および max_connections システム変数は、サーバーが開いたままにするファイルの最大数に影響します。 これらの値のいずれかまたは両方を増やすと、オープンファイルディスクリプタのプロセスあたりの数に関して、オペレーティングシステムによって適用されている制限に達する可能性があります。 多くのオペレーティングシステムでは、オープンファイル制限を増やすことができますが、方法はシステムによって大きく異なります。 制限値を増やすことができるかどうか、およびその実行方法については、使用するオペレーティングシステムのドキュメントを参照してください。

table_open_cachemax_connections に関連します。 たとえば、200 の同時実行接続の場合、少なくとも 200 * N のテーブルキャッシュサイズを指定します。ここで N は実行するクエリーの結合あたりのテーブルの最大数です。 また、一時テーブルとファイル用のいくつかの追加のファイルディスクリプタを予約する必要もあります。

オペレーティングシステムで、table_open_cache の設定に示されたオープンファイルディスクリプタの数を処理できることを確認してください。 table_open_cache の設定が高すぎると、MySQL でファイル記述子が不足し、接続の拒否やクエリーの実行の失敗などの症状が発生する可能性があります。

また、MyISAM ストレージエンジンでは、一意のオープンテーブルごとに 2 つのファイル記述子が必要であることも考慮してください。 MySQL で使用可能なファイル記述子の数を増やすには、open_files_limit システム変数を設定します。 セクションB.3.2.16「ファイルが見つからず同様のエラーが発生しました」を参照してください。

オープンテーブルのキャッシュは、table_open_cache エントリのレベルで保持されます。 サーバーはスタートアップ時にキャッシュサイズを自動サイズ設定します。 サイズを明示的に設定するには、スタートアップ時に table_open_cache システム変数を設定します。 MySQL では、このセクションの後半で説明するように、クエリーを実行するために一時的にこれよりも多くのテーブルを開く場合があります。

次の状況では、MySQL は未使用のテーブルを閉じ、それをテーブルキャッシュから削除します。

  • キャッシュがいっぱいで、スレッドがキャッシュにないテーブルを開こうとした場合。

  • キャッシュに table_open_cache を超えるエントリがあり、キャッシュ内のテーブルがどのスレッドによっても使用されなくなった場合。

  • テーブルフラッシュ操作が発生した場合。 これは、だれかが FLUSH TABLES ステートメントを発行するか、または mysqladmin flush-tables または mysqladmin refresh コマンドを実行した場合に行われます。

テーブルキャッシュがいっぱいになると、サーバーは次の手順に従って使用するキャッシュエントリを見つけます。

  • 現在使用されていないテーブルは、最も最近使用されていないテーブルからリリースされます。

  • 新しいテーブルを開く必要があるが、キャッシュがいっぱいでテーブルを解放できない場合、キャッシュは必要に応じて一時的に拡張されます。 キャッシュが一時的に拡張された状況で、テーブルが使用中から未使用状態になったときは、そのテーブルが閉じられ、キャッシュから解放されます。

MyISAM テーブルは同時アクセスごとに開かれます。 つまり、2 つのスレッドで同じテーブルにアクセスする場合、または 1 つのスレッドが同一クエリーでテーブルに 2 回アクセスする場合 (テーブルをそれ自体に結合することによってなど) は、テーブルを 2 回開く必要があることを意味します。 同時オープンは、それぞれテーブルキャッシュにエントリが必要になります。 いずれかの MyISAM テーブルを最初に開くと、データファイルに 1 つとインデックスファイルに 1 つの 2 つのファイルディスクリプタが必要になります。 テーブルの追加の使用では、それぞれデータファイルに 1 つだけのファイルディスクリプタが必要です。 インデックスファイルディスクリプタはすべてのスレッドで共有されます。

HANDLER tbl_name OPEN ステートメントを使用してテーブルを開く場合、専用のテーブルオブジェクトがスレッドに割り当てられます。 このテーブルオブジェクトはほかのスレッドと共有されず、スレッドが HANDLER tbl_name CLOSE を呼び出すか、スレッドが終了するまでクローズされません。 これが発生すると、テーブルがテーブルキャッシュに戻されます (キャッシュがいっぱいでない場合)。 セクション13.2.4「HANDLER ステートメント」を参照してください。

テーブルキャッシュが小さすぎるかどうかを判断するには、サーバーの起動後のテーブルオープン操作の数を示す Opened_tables ステータス変数を確認します:

mysql> SHOW GLOBAL STATUS LIKE 'Opened_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_tables | 2741  |
+---------------+-------+

多数の FLUSH TABLES ステートメントを発行していない場合でも、値が非常に大きいか急速に増加する場合は、サーバーの起動時に table_open_cache 値を増やします。


関連キーワード:  テーブル, キャッシュ, インデックス, InnoDB, ステートメント, クエリー, 結合, 実行, 状態, open