MySQL道普請便り

第277回MySQL 9.6と9.7の新機能について

MySQL 9.6が2026年1月、MySQL 9.7が2026年4月にリリースされました。以前の記事の 第260回 MySQL 9.4と9.5の新機能について と同じように、今回もMySQL 9.6と9.7の中からMySQL Community Editionで利用できる新機能や変更点を、いくつかピックアップして簡単に紹介したいと思います。

なお、9.6までがInnovation Releaseだったのに対し、MySQL 9.7は8.4に続くLTS(Long-Term Support)リリースです。5年間のPremier Supportと3年間のExtended Supportが提供され、8.4.x LTSからのアップグレードがサポートされます。また、9.7は従来の連番バージョニングを使用する最後のリリースで、以降はYY.M形式のカレンダーバージョニングに変更されます。たとえばMySQL 26.7は2026年7月のリリースを表します。

MySQL 9.6の新機能

最初に、MySQL 9.6の新機能と変更点について紹介します。

外部キー制約の処理がSQLレイヤーへ移行

MySQL 9.6では、外部キー制約の検査とカスケード操作の処理が、InnoDBストレージエンジンからSQLレイヤーへ移されました。

これまでON DELETE CASCADEなどによる子テーブルの変更はInnoDBの内部で処理されていたため、バイナリログには親テーブルへの操作しか記録されませんでした。レプリカ側でもInnoDBが同じカスケードを実行するため整合はしていましたが、バイナリログを読み取るCDCツールや監査の用途では、カスケードによる変更が見えないという問題がありました。

実際に、ON DELETE CASCADEを張った親子テーブルで親の行を削除し、バイナリログを確認してみます。SQLレイヤーで処理される場合は、子テーブルの削除も記録されます。

### DELETE FROM `test`.`child`
### WHERE
###   @1=10 /* INT meta=0 nullable=0 is_null=0 */
###   @2=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM `test`.`parent`
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */

一方、後述のinnodb_native_foreign_keysを有効にして従来どおりInnoDBで処理させると、親テーブルの削除しか記録されません。

### DELETE FROM `test`.`parent`
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */

従来の挙動に戻したい場合は、起動時にinnodb_native_foreign_keysを有効にします。ただし、この変数は将来のリリースで削除される予定とされているため、移行時の検証用と考えておくのがよいでしょう。

JSON duality viewのDMLタグ付け

第260回で紹介したJSON duality viewに、テーブル単位でDML操作を制御するタグが追加されました。INSERTUPDATEDELETEのうち許可する操作を指定するか、NO INSERTNO UPDATENO DELETEで禁止する操作を指定します。実行時に、DML操作がタグと突き合わせて検証されます。

MD5()とSHA1()のコンポーネント化

MD5()SHA1()が、classic_hashingという別のコンポーネントに移されました。すでに安全とは言えないハッシュアルゴリズムの利用を、コンポーネントのロード有無で制御できるようになります。

その他、コンテナのリソース制限を認識するcontainer_aware起動オプションの追加や、監査ログのコンポーネント化なども行われています。

MySQL 9.7の新機能

続いて、MySQL 9.7の新機能と変更点を紹介します。

外部キーのカスケードによるトリガーの実行

MySQLでは長らく、カスケードされた外部キーアクションではトリガーが起動しないという制限がありました。9.6でカスケード処理がSQLレイヤーへ移ったことを受けて、9.7では子テーブルのトリガーを実行できるようになっています。

制御にはenable_cascade_triggersを使用します。デフォルト値はOFFです。innodb_native_foreign_keysのデフォルト値もOFF、つまり9.6以降はSQLレイヤーでの処理がデフォルトになっています。

mysql> SELECT @@innodb_native_foreign_keys, @@enable_cascade_triggers;
+------------------------------+---------------------------+
| @@innodb_native_foreign_keys | @@enable_cascade_triggers |
+------------------------------+---------------------------+
|                            0 |                         0 |
+------------------------------+---------------------------+
1 row in set (0.00 sec)

ON DELETE CASCADEを張った親子テーブルを用意し、子テーブルにAFTER DELETEトリガーを作成して動作を確認してみます。まずはデフォルトのOFFのまま親の行を削除します。子テーブルの行はカスケードで削除されますが、トリガーは実行されません。

mysql> DELETE FROM parent WHERE id = 1;
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM trigger_log;
Empty set (0.00 sec)

続いてenable_cascade_triggersを有効にしてから、別の親の行を削除します。

mysql> SET SESSION enable_cascade_triggers = ON;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> DELETE FROM parent WHERE id = 2;
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM trigger_log;
+----+---------------------+
| id | ev                  |
+----+---------------------+
|  1 | child id=20 deleted |
+----+---------------------+
1 row in set (0.00 sec)

今度は子テーブルのトリガーが実行されていることがわかります。ON UPDATE CASCADEでも同様に、AFTER UPDATEトリガーが実行されます。なお、トリガーの実行が失敗した場合は、ステートメント全体が失敗し、カスケードによる変更もすべてロールバックされます。

ここでSETの実行時に警告が1件出ている点に注意してください。enable_cascade_triggersは追加と同時に非推奨とされており、次の警告が出力されます。

mysql> SHOW WARNINGS;
+---------+------+----------------------------------------------------------------------------------+
| Level   | Code | Message                                                                          |
+---------+------+----------------------------------------------------------------------------------+
| Warning | 1681 | 'enable_cascade_triggers' is deprecated and will be removed in a future release. |
+---------+------+----------------------------------------------------------------------------------+
1 row in set (0.00 sec)

また、innodb_native_foreign_keysONの環境ではenable_cascade_triggersは効果がなく、ONに設定すると次の警告が出力されます。

| Warning | 4166 | 'enable_cascade_triggers' is deprecated and will be removed in a future release. Enabling trigger execution on child table is supported only with SQL Foreign Key handling (i.e with innodb_native_foreign_keys = OFF). |

将来的には、SQLレイヤーでの外部キー処理とカスケード時のトリガー実行が標準の挙動になり、これらの変数自体がなくなっていくものと思われます。

Hypergraph OptimizerがCommunity Editionで利用可能に

optimizer_switchhypergraph_optimizerフラグ自体は以前から存在していましたが、Community Editionのビルドには組み込まれておらず、有効にしようとしても失敗するか無視される状態でした。MySQL 9.7では、Community Editionのビルドにも組み込まれ、実際に利用できるようになりました。

デフォルトはoffのままなので、利用する場合は明示的に有効にします。セッション単位、グローバル、PERSIST、起動オプション、オプティマイザヒントのいずれでも指定できます。

mysql> SET optimizer_switch='hypergraph_optimizer=on';
Query OK, 0 rows affected (0.00 sec)

結合順序の探索に新しいアルゴリズムを採用したオプティマイザで、特に多数のテーブルを結合するクエリで効果が期待できます。実行計画が変わる可能性があるため、有効にする前に主要なクエリのEXPLAINを取得して比較しておくとよいでしょう。

JSON duality viewのDML操作のサポート

第260回では、JSON duality viewの更新系の機能はEnterprise Edition専用のため割愛しました。MySQL 9.7では、MySQL Community ServerでもJSON duality viewに対するINSERTUPDATEDELETEが実行できるようになりました。あわせて、DML操作でのAUTO_INCREMENT列もサポートされています。

9.7.1と9.7.2での変更

9.7.1はCritical Security Patch Updateのみのリリースです。9.7.2では、group_replication_communication_stackgroup_replication_ip_allowlistが非推奨になり、thread_pool_max_unused_threadsのデフォルト値が2から32に変更されました。

まとめ

今回はMySQL 9.6と9.7の新機能や変更点について紹介しました。外部キー制約の処理がSQLレイヤーへ移り、9.7ではカスケードによるトリガーの実行までサポートされた点が、2つのバージョンを通した大きな変更です。

MySQL 9.7は8.4に続くLTSリリースであり、8.4を利用している環境にとっては次の移行先となるバージョンです。外部キーまわりは挙動が変わる部分なので、アップグレード前に確認しておくとよいでしょう。

以下ドキュメントを参考にしました。詳しく知りたい方はご参照ください。

おすすめ記事

記事・ニュース一覧