スマートスタイル TECH BLOG

データベース&クラウド技術情報

GIPKs を利用したレプリケーションについて

はじめに

MySQL 8.0.30 から、Generated Invisible Primary Keys(GIPKs) という機能が追加されています。

この機能を有効にすることで、主キーの存在しないテーブルを作成した際に、自動で Invisible Columns の主キーを追加することができます。

MySQL 8.0.32 ではこの機能の拡張として、レプリケーションのレプリカで主キーのないテーブルを複製する場合にも対応できるようになりました。

Replication: It is now possible to cause a replica to add a generated invisible primary key to any InnoDB table that otherwise, as replicated, has no primary key.

引用 : Changes in MySQL 8.0.32 (2023-01-17, General Availability)

今回はこの新機能について、挙動や仕様について確認してみたいと思います。

Generated Invisible Primary Keys(GIPKs) について

まず GIPKs とは、明示的に主キーを指定せずに作成したテーブルに対して、非表示のカラムを追加する機能です。
具体的には、以下のような仕様となっています。

  • sql_generate_invisible_primary_key システム変数で動作を制御する
    デフォルトでは無効になっている sql_generate_invisible_primary_key を有効にすることで、GIPKs の機能が適用されるようになります。なお、動的かつグローバル・セッション単位で指定することが可能です。

    また、この値はレプリケーション時に伝播しないため、伝播させるには後述する CHANGE REPLICATION SOURCE TO 文のオプションとして指定する必要があります。

  • 作成される主キー名は my_row_id
    GIPKs は主キーのないテーブルを作成した際に、カラムの先頭に非表示の my_row_id 列を作成します。
    非表示カラム(Invisible Columns)として作成されるため、ユーザー側は特に意識することなく普段通りテーブルを使用することが可能です。

    また、GIPKs が有効になっていて主キーのないテーブルを作成する際には、my_row_id という名前のカラムは作成できないので注意してください。なお、主キーのあるテーブルでは my_row_id カラムを追加することが可能です。

この他、GIPKs が有効になっている場合、MySQL 8.0.32 時点では、新たに主キーを追加しないで主キーを削除する操作がエラーとなります。

ちなみにこの挙動は、テーブル作成時に主キーがない場合はエラーにする sql_require_primary_keyと被っているようです。似たシステム変数なので、今後統合されると嬉しいですね。

Generated Invisible Primary Keys(GIPKs) を利用したレプリケーションの仕様について

前述している通り、sql_generate_invisible_primary_key の値はレプリケーション時に伝播しないため、レプリケーションのレプリカで GIPKs を利用するためには CHANGE REPLICATION SOURCE TO 文で REQUIRE_TABLE_PRIMARY_KEY_CHECK = GENERATE を指定する必要があります。
したがって、レプリカサーバーで sql_generate_invisible_primary_key を有効にしていても、REQUIRE_TABLE_PRIMARY_KEY_CHECK = GENERATE を指定していなければレプリケーション SQL スレッドにおいて GIPKs は有効にならないので注意してください。

なお、グループレプリケーションにおいて REQUIRE_TABLE_PRIMARY_KEY_CHECK = GENERATE はサポートされていないため、ON/OFF あるいはデフォルト値の STREAM を指定する必要があります。

既存のレプリケーションに追加をおこなう場合は、以下のように一度レプリケーションを停止してから設定を追記すると、以降の DDL で GIPKs が有効になります。また設定については、performance_schema.replication_applier_configuration テーブルから確認可能です。

ここで、レプリケーションにおける GIPKs の挙動については以下のように、GIPKs をサポートしている(MySQL 8.0.30 以降の)ソースと MySQL 8.0.32 以降のレプリカにおける GIPKs に基づく相違はサポートされ、MySQL 8.0.29 以前のソースの場合はレプリケーションエラーが発生する可能性があるとの記載があります。

A divergence based on the presence of a generated invisible primary key solely on a source or replica table is supported by MySQL Replication as long as the source supports GIPKs (MySQL 8.0.30 and later) and the replica uses MySQL version 8.0.32 or later. If you use GIPKs on a replica and replicate from a source using a MySQL 8.0.29 or earlier, you should be aware that in this case such divergences in schema are not supported and may result in replication errors.

引用: 13.4.2.3 CHANGE REPLICATION SOURCE TO Statement – REQUIRE_TABLE_PRIMARY_KEY_CHECK

しかし、たとえば以下のように MySQL 8.0.32 の GIPKs が無効のソースサーバーで主キーの追加をおこなうと、GIPKs を有効にしているレプリカサーバーではレプリケーションエラーが発生してしまいます。

その他、ソースサーバーで my_row_id という名前のカラムを追加してもエラーになりますし、主キーが存在するテーブルから主キーを削除してもレプリカサーバーではエラーが発生してしまいます。

そのため、実質的にはソースあるいはレプリカサーバーでのみ GIPKs を有効にすることで、意図的にデータ不整合を発生させる可能性があることになるため、慎重に運用していく必要がありそうです。

まとめ

ここまで、GIPKs およびレプリケーションの挙動について確認してきました。
主キーのない環境からのレプリケーションでも自動で主キーが追加されるため、行ベースレプリケーション を使用している際に主キーがないテーブルへの UPDATE や DELETE が遅くなる問題が懸念される環境において、ソースサーバー側で操作をおこなわなずに対策ができるのは便利かと思います。

※既存のテーブルには有効でないため、あらかじめ GIPKs を有効にしてから論理バックアップを流すなどのひと手間が必要になる点にはご注意ください

ただし、実際はソースとレプリカ間でデータの不整合が発生しており、今回のように特定の DDL を実行したりフェイルオーバーを実施すると、思わぬ障害につながる可能性もあるため、実環境で使用する際には、問題がないかどうかを十分注意して利用する必要がありそうです。

Return Top