MySQL5.7とそれ以前のMySQL(従来のMySQL)では、ディクショナリーデータはメタデータを保持したファイルや、MyISAMのようなトランザクションに未対応のストレージエンジンのテーブルなどで管理されていました。MySQL8.0からは、データディクショナリーはトランザクションをサポートしたInnoDBストレージエンジンで管理されるようになりました。これによって、さまざまな形で管理されていたものが統一され中央管理となり、運用において多くの利点があります。
今回はMySQL8.0からのデータディクショナリーについて紹介したいと思います。
トランザクショナルなデータディクショナリー
従来のMySQLの方式と比較して、以下のような変更点があります。
- ディクショナリーデータの中央管理
- ファイルベースのメタデータ管理の削除
- クラッシュセーフなデータディクショナリー
- アトミックなDDL操作
- 統一されたキャッシュシステム
- INFORMATION_SCHEMAの改良
ディクショナリーデータの中央管理
基本的にデータディクショナリーのテーブルは、mysql.ibd
という1つのテーブルスペースに格納されるようになりました。データディクショナリーのテーブルは保護されているため、直接アクセスすることはできません(DEBUGオプションでコンパイルすることでアクセスは可能です)。INFORMATION_SCHEMA
テーブルやSHOW
ステートメントを通してデータディクショナリテーブルに格納されたデータへのアクセスすることで、データを確認することが可能です。
また、従来のメタデータ情報を持ったsdi(Serialized Dictionary Information)ファイルも作成されます。InnoDBのテーブルであれば各テーブルのibdファイルに内包されており、InnoDB以外のストレージエンジンのテーブルはsdiファイルが作成されます。これを利用して、InnoDBであればトランスポータブル表領域で、MyISAMであれば13.2.5 IMPORT TABLE Syntaxでテーブルを移行したり可能です。また、障害時の復旧のために用いることができます。
ファイルベースのメタデータ管理の削除
以下のファイルが無くなり、データディクショナリーテーブルに取り込まれました。
- frmファイル:テーブル定義ファイル。
- parファイル:パーティション定義ファイル
- TRNファイル:トリガー ネームスペースファイル
- TRGファイル:トリガー パラメータファイル
- islファイル:データディレクトリの外側に作成されたテーブルの場所を含むシンボリックリンクファイル
- db.opt:データベース構成ファイル
クラッシュセーフなデータディクショナリー
ディクショナリーデータをトランザクションをサポートしたテーブル(InnoDB)に格納します。よって、ディクショナリーデータはInnoDBで作成した通常のテーブルと同様に、ロールフォワード、ロールバック機能を備えたクラッシュリカバリーが可能になりました。注意として、BEGIN; .. ROLLBACK;
という明示的なロールバックではなく、あくまでクラッシュ時にデータ不整合を防ぐためのロールフォワード、ロールバックが内部で実行されます。
アトミックなDDL操作
MySQL8.0での大きな新機能として、このアトミックDDLと呼ばれる操作があります。
従来のMySQLでは、DDLの途中で中断した場合はデータディクショナリー、ストレージエンジンとバイナリログ間で不整合や中途半端にファイルが残ったりする可能性がありました。
そのようなことが起こらないように、アトミックDDLは、データディクショナリの更新、ストレージエンジンの操作とDDL操作に関連するバイナリログの書き込みを1つのトランザクションにまとめます。
そしてトランザクションは、適用可能な変更がデータディクショナリー、ストレージエンジンとバイナリログに更新された状態でコミットされるか、またはサーバーが操作中にクラッシュして不完全の状態であればロールバックされるようになるので、DDLがアトミックな処理となります。
注意として、以下のような操作はアトミックDDLとなりません。
- InnoDBストレージエンジン以外のDDL
- INSTALL/UNINSTALL PLUGIN ステートメント
- INSTALL/UNINSTALL COMPONENT ステートメント
- CREATE/ALTER/DROP SERVER ステートメント
また、Create/Drop UserやGrant/Revokeステートメントといったユーザ管理ステートメントについても、アトミックな処理となりました。
アトミックDDLの処理
アトミックDDLは4つのフェーズで処理されます。
- Prepare:DDLログに記録。ロールフォワード、ロールバック手順を定義。
- Perform:DDLの実行。
- Commit:データディクショナリ更新して、データディクショナリートランザクションをコミット。
- Post-DDL:DDLログの削除。データファイルの削除や名前変更などのファイル操作を実行。
DDLの途中でクラッシュした際は、復旧後にCommitフェーズでredoログとバイナリーログに書き込みがあった場合のみロールフォワードされ、それ以外はロールバックされます。
「DDLログに記録」はmysql.ibd
の中のmysql
.innodb_ddl_log
テーブルに書き込むことを意味します。これはデータディクショナリーテーブルであるため、前述のように直接アクセスすることはできません。DDLログを確認するためには、パラメータinnodb_print_ddl_logs
を有効にします。ONにすると、エラーログに出力されるようになります。
統一されたキャッシュシステム
ディクショナリーオブジェクトキャッシュは、以前にアクセスされたデータディクショナリーオブジェクトをメモリに格納して、オブジェクトの再利用を可能にします。ディスクI/Oを最小限に抑える共有グローバルキャッシュです。格納されるデータとしては、表の定義、表領域の定義やスキーマの定義などをキャッシュします。
system変数によりキャッシュされるサイズは異なりますので、詳しくは14.4 Dictionary Object Cacheを参照してください。
INFORMATION_SCHEMAの改良
さまざまなINFORMATION_SCHEMAテーブルが、データディクショナリーテーブルのビューとして実装されるようになりました。従来のMySQLではfrmファイルなどのファイルから取得していた情報が、データディクショナリーテーブルへのアクセスのみで完結するようになったため、効率的になりました。また、STATISTICS
やTABLES
テーブルに含まれるテーブル統計の情報は、前述のキャッシュが利用できたり、それ以外でもインデックスを使用したアクセスが可能となったため、パフォーマンスの改善にも期待できます。
まとめ
MySQL8.0の大きな変更点であるデータディクショナリーについて紹介しました。この機能により、安全にテーブル定義変更や削除が可能になります。
もっと詳しく情報を確認したい方は、マニュアルのChapter 14 MySQL Data Dictionaryを参照してください。