リードレプリカ インデックスを作成して管理する

このドキュメントでは、Cloud SQL リードレプリカでセカンダリ インデックスを作成、維持、モニタリングする方法について説明します。

マネージド レプリカ インデックスの仕組みに関するコンセプトについては、リードレプリカ インデックスの概要をご覧ください。

マネージド レプリカ インデックス

次の表に、マネージド レプリカ インデックスの作成、構成、モニタリングのワークフローをまとめます。

ステップ ストアド プロシージャまたはデータベース フラグ ステップを実施する場所
インデックス定義を作成する CALL mysql.cloudsql_replica_idx_defn_create('INDEX_DEFINITION_NAME', 'CREATE_INDEX_STATEMENT');

このストアド プロシージャは、インデックス定義 INDEX_DEFINITION_ID の一意の整数識別子を返します。

プライマリ インスタンス
マップ定義をグループ化する CALL mysql.cloudsql_replica_idx_group_add(INDEX_DEFINITION_ID, 'GROUP_NAME');

GROUP_NAME は、選択可能なカスタム名です。そのグループが存在しない場合、Cloud SQL は新しいグループを作成します。

プライマリ インスタンス
レプリカにグループを割り当てる データベース フラグ: cloudsql_index_recreate_replica_group = GROUP_NAME 読み取りレプリカ インスタンス
ステータスを確認 CALL mysql.cloudsql_replica_idx_show_status(); 読み取りレプリカ インスタンス
監査エラー CALL mysql.cloudsql_replica_idx_show_errors(); 読み取りレプリカ インスタンス

各ストアド プロシージャ呼び出しは、現在のセッションの変更を確定する COMMIT ステートメントを実行します。そのため、これらのストアド プロシージャを使用して実行されたデータ操作言語(DML)ステートメントは、トランザクション内でロールバックできません。

Cloud SQL は、既存のインデックス メタデータの更新または変更をサポートしていません。マネージド レプリカ インデックスを変更するには、既存のインデックス定義を削除(またはレプリカ グループから削除)し、新しいインデックス定義を作成する必要があります。詳細については、マネージド レプリカ インデックスを変更するをご覧ください。

必要なロールと権限

マネージド レプリカ インデックスのストアド プロシージャを実行するには、cloudsqlsuperuser ロールが割り当てられているデータベース ユーザー アカウントを使用する必要があります。

マネージド レプリカ インデックスを作成する

リードレプリカでマネージド レプリカ インデックスを作成して維持する手順は次のとおりです。

  1. プライマリ インスタンスにインデックス定義を作成します。

    データベースのプライマリ インスタンスで mysql.cloudsql_replica_idx_defn_create ストアド プロシージャを呼び出します。

    CALL mysql.cloudsql_replica_idx_defn_create
    ('INDEX_DEFINITION_NAME', 'CREATE_INDEX_STATEMENT');

    次のように置き換えます。

    • INDEX_DEFINITION_NAME: インデックス定義の名前。
    • CREATE_INDEX_STATEMENT: セカンダリ インデックスを作成する SQL ステートメント(CREATE INDEX idx_age ON university.students (age) など)。このステートメントには、スキーマ接頭辞を付ける必要があります。

    プロシージャの出力から返された idx_id(定義の一意の整数識別子)をメモします。Cloud SQL はこのデータを mysql.cloudsql_replica_idx_defn に保存します。このテーブルをクエリすることで、後で idx_id を取得できます。

  2. インデックス定義をレプリカ グループに追加します。

    プライマリ インスタンスで mysql.cloudsql_replica_idx_group_add を呼び出して、インデックス定義を指定されたレプリカ グループ名にマッピングします。

    CALL mysql.cloudsql_replica_idx_group_add
    (INDEX_DEFINITION_ID, 'GROUP_NAME');

    次のように置き換えます。

    • INDEX_DEFINITION_ID: mysql.cloudsql_replica_idx_defn_create ストアド プロシージャを実行してセカンダリ インデックスを作成したときに返された一意の整数 ID。
    • GROUP_NAME: レプリカ グループ マッピングの名前(例: reporting_group)。GROUP_NAME は、選択可能なカスタム名です。そのグループが存在しない場合、Cloud SQL は新しいグループを作成します。

    Cloud SQL はこのデータを mysql.cloudsql_replica_idx_group_map に保存します。このテーブルをクエリすることで、後でグループ マッピングを取得できます。

  3. グループをレプリカ インスタンスに割り当てます。

    データベース フラグ cloudsql_index_recreate_replica_group をグループ名(reporting_group など)に設定して、リードレプリカで指定されたグループを有効にします。

  4. 復元の進行状況を確認します。

    リードレプリカ インスタンスに接続し、インデックスの作成の進行状況とステータスを確認します。

    • 進行中のインデックス作成の進行状況を確認します。

      CALL mysql.cloudsql_replica_idx_show_status();
      
    • 失敗した試行とエラー メッセージを確認します。

      CALL mysql.cloudsql_replica_idx_show_errors();
      
    • すべてのマネージド インデックスのステータス、再試行の詳細、期間を一覧表示します。

      CALL mysql.cloudsql_replica_idx_show_all();
      

マネージド レプリカ インデックスのステータスを確認する

インデックス オペレーションのステータスを確認するには、リードレプリカ インスタンスに接続して mysql.cloudsql_replica_idx_status テーブルをクエリします。

SELECT * FROM mysql.cloudsql_replica_idx_status;

出力は次のようになります。

+--------+----------------------------------------------------+--------+-----------+---------------------+---------------------+-------------+---------+--------------------+---------+
| idx_id | create_stmt                                        | action | thread_id | start_time          | end_time            | retry_count | err_msg | comment_tag        | status  |
+--------+----------------------------------------------------+--------+-----------+---------------------+---------------------+-------------+---------+--------------------+---------+
|      2 | CREATE INDEX t1_fname ON sampletest.t1(first_name) | CREATE |      8140 | 2026-08-26 10:52:13 | NULL                |           0 | NULL    | [SIC_4_1787741231] | RUNNING |
|      4 | CREATE INDEX t2_lname ON sampletest.t2(last_name)  | DROP   |      NULL | 2026-08-26 10:52:13 | 2026-08-26 10:53:15 |           0 | NULL    | [SIC_4_1787741533] | DONE    |
|      5 | CREATE INDEX t1_lname ON sampletest.t1(last_name)  | CREATE |      8142 | 2026-08-26 10:53:14 | NULL                |           0 | NULL    | [SIC_5_1787741594] | RUNNING |
+--------+----------------------------------------------------+--------+-----------+---------------------+---------------------+-------------+---------+--------------------+---------+

Cloud SQL は、マネージド レプリカのインデックス メンテナンスをバッチで実行します。Cloud SQL が CREATE または DROP アクションのグループを取得すると、各インデックスに PENDING ステータス エントリを作成し、各データ定義言語(DDL)ステートメントを順番に実行します。1 つのインデックスで障害が発生しても、キュー内の後続のインデックスの実行はブロックされません。Cloud SQL は、約 5 分後に次のバッチを取得します。

インデックスの作成に失敗すると、Cloud SQL はステータスを FAILED としてマークし、1 時間後にオペレーションを自動的に再試行します。

mysql.cloudsql_replica_idx_status テーブルには、すべてのインデックス オペレーション ステータス エントリが含まれ、次の列が含まれます。

  • idx_id: インデックス定義の一意の整数識別子。
  • create_stmt: CREATE INDEX SQL ステートメント。
  • action: 実行されるオペレーション(CREATE または DROP)。
  • thread_id: オペレーションを実行している MySQL スレッド ID。
  • start_time: オペレーションの開始時のタイムスタンプ。
  • end_time: オペレーションが完了したときのタイムスタンプ。
  • retry_count: オペレーションの再試行回数。Cloud SQL は、失敗したインデックスの作成を 1 時間後に再試行します。
  • err_msg: 最後に失敗したオペレーションのエラー メッセージ。
  • comment_tag: インデックス コメントの先頭に付加される [SIC_X_Y] タグ。このタグは内部管理専用であり、機能はありません。
  • status: オペレーションの現在のステータス。
    • PENDING: インデックス オペレーションがキューに追加されました。
    • RUNNING: インデックス オペレーションの実行が開始されました。
    • DONE: インデックス オペレーションが正常に完了しました。
    • FAILED: インデックス オペレーションが失敗しました。Cloud SQL は、失敗したインデックスの作成を 1 時間後に再試行します。

マネージド レプリカ インデックスを削除する

レプリカ グループからインデックスを削除するか、インデックス定義を完全に削除するには、プライマリ インスタンスで対応するストアド プロシージャを呼び出します。

  • レプリカ グループからインデックス定義を削除します。

    プライマリ インスタンスで mysql.cloudsql_replica_idx_group_drop を呼び出します。

    CALL mysql.cloudsql_replica_idx_group_drop
    (INDEX_DEFINITION_ID, 'GROUP_NAME');

    次のように置き換えます。

    • INDEX_DEFINITION_ID: セカンダリ インデックス定義の作成時に返された一意の整数 ID。
    • GROUP_NAME: レプリカ グループ マッピングの名前(例: reporting_group)。
  • インデックス定義を削除する:

    プライマリ インスタンスで mysql.cloudsql_replica_idx_defn_drop を呼び出します。

    CALL mysql.cloudsql_replica_idx_defn_drop
    (INDEX_DEFINITION_ID);

    次のように置き換えます。

    • INDEX_DEFINITION_ID: 削除するインデックス定義の一意の整数 ID。

ストアド プロシージャの詳細については、マネージド レプリカ インデックスのストアド プロシージャをご覧ください。

マネージド レプリカ インデックスを変更する

Cloud SQL は、既存のインデックス メタデータの更新または変更をサポートしていません。既存のインデックス定義またはその SQL ステートメントを直接変更することはできません。

マネージド レプリカ インデックスを変更する(インデックス付きの列やインデックス オプションを変更するなど)には、既存のインデックス定義を削除してから、新しいインデックス定義を作成する必要があります。

マネージド レプリカ インデックスを変更する手順は次のとおりです。

  1. プライマリ インスタンスの既存のインデックス定義を削除します。

    • レプリカ グループからインデックス定義を削除するには、mysql.cloudsql_replica_idx_group_drop を呼び出します。

      CALL mysql.cloudsql_replica_idx_group_drop
      (INDEX_DEFINITION_ID, 'GROUP_NAME');
    • インデックス定義を完全に削除するには、mysql.cloudsql_replica_idx_defn_drop を呼び出します。

      CALL mysql.cloudsql_replica_idx_defn_drop
      (INDEX_DEFINITION_ID);

    次のように置き換えます。

    • INDEX_DEFINITION_ID: 削除するインデックス定義の一意の整数 ID。
    • GROUP_NAME: レプリカ グループ マッピングの名前(例: reporting_group)。
  2. プライマリ インスタンスに新しいインデックス定義を作成します。

    更新されたインデックス ステートメントを指定して mysql.cloudsql_replica_idx_defn_create を呼び出します。

    CALL mysql.cloudsql_replica_idx_defn_create
    ('INDEX_DEFINITION_NAME', 'CREATE_INDEX_STATEMENT');

    次のように置き換えます。

    • INDEX_DEFINITION_NAME: 新しいインデックス定義の名前。
    • CREATE_INDEX_STATEMENT: セカンダリ インデックスを作成する更新された SQL ステートメント(例: CREATE INDEX idx_age ON university.students (age, name))。

    ストアド プロシージャの出力で返された新しい idx_id をメモしておきます。

  3. 新しいインデックス定義をレプリカ グループにマッピングします。

    プライマリ インスタンスで mysql.cloudsql_replica_idx_group_add を呼び出します。

    CALL mysql.cloudsql_replica_idx_group_add
    (INDEX_DEFINITION_ID, 'GROUP_NAME');

    次のように置き換えます。

    • INDEX_DEFINITION_ID: 手順 2 で返された新しい一意の整数 ID。
    • GROUP_NAME: レプリカ グループ マッピングの名前(例: reporting_group)。

新しいインデックス定義をレプリカ グループにマッピングすると、バックグラウンド メンテナンス プロセスによって、リードレプリカから既存のインデックスが削除され、更新された定義を使用してレプリカに新しいインデックスが作成されます。

マネージド レプリカ インデックスのデータベース構成フラグ

次のグローバル データベース フラグを使用して、マネージド レプリカ インデックスの動作を動的にカスタマイズできます。

  • cloudsql_index_recreate_enable: 再作成プロセスを有効または無効にします。デフォルトでは、このフラグは on に設定されています。このフラグを off に設定すると、進行中のインデックス メンテナンス オペレーションが直ちに終了します。

  • cloudsql_index_recreate_replica_group: レプリカに指定されたレプリカ グループ名(デフォルトは NULL)。レプリカは、一度に 1 つのレプリカ グループにのみ割り当てることができます。レプリカは、このレプリカ グループ名にマッピングされたすべてのインデックスを構築します。

セルフマネージド レプリカ インデックス

Cloud SQL には、mysql スキーマに 2 つのストアド プロシージャが含まれています。これにより、MySQL リードレプリカにセカンダリ インデックスの追加またはドロップを行うことができます。これらのストアド プロシージャはプライマリ ソース インスタンスで実行できますが、リードレプリカ用に設計されています。

レプリカが再作成されると、これらのインデックスは保持されません。

mysql.addSecondaryIdxOnReplica
データベースにセカンダリ インデックスを追加します。このストアド プロシージャは、CREATE INDEX DDL ステートメントのラッパーです。

パラメータ:

  • idxType: 作成するインデックスのタイプ。たとえば、一意のインデックスを作成するには UNIQUE を渡します。
  • idxName: インデックスの名前。
  • tableName: テーブルの名前(schema.name の形式)。
  • idxDefinition: インデックスの定義。外側の括弧は含めないでください。
  • idxOption: インデックスの作成時に渡す追加のオプション。たとえば、MySQL 8.0 では、非表示インデックスに INVISIBLE オプションを渡すことができます。

構文:

mysql.addSecondaryIdxOnReplica(idxType, idxName, tableName, idxDefinition, idxOption)
     
mysql.dropSecondaryIdxOnReplica
データベースのセカンダリ インデックスを削除します。このストアド プロシージャは、DROP INDEX DDL ステートメントのラッパーです。

パラメータ:

  • idxName: インデックスの名前。
  • tableName: テーブルの名前(schema.name の形式)。
  • idxOption: インデックスを削除するときに渡す追加のオプション。たとえば、INPLACE などのアルゴリズム オプションです。

構文:

mysql.dropSecondaryIdxOnReplica(idxName, tableName, idxOption)
      

idxType パラメータと idxOption パラメータについては、Cloud SQL インスタンスで実行される MySQL のメジャー バージョンのドキュメントをご覧ください。

例

このセクションでは、セルフマネージド レプリカ インデックスを正しく追加または削除する方法と、誤って追加または削除する方法の例を示します。

正しい使用方法

プロシージャの呼び出し例を次に示します。次の定義を持つテーブルがあるとします。

CREATE TABLE sampletest.t1(
   id int(10) unsigned NOT NULL AUTO_INCREMENT,
   first_name varchar(64) NOT NULL,
   last_name varchar(64) NOT NULL,
   license_id int NOT NULL,
   PRIMARY KEY (id),
   KEY idx_fname (first_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

first_name 列と last_name 列に t1_fname_lname という名前の通常のインデックスを作成する場合は、次のステートメントを実行します。

CALL mysql.addSecondaryIdxOnReplica('', 't1_fname_lname', 'sampletest.t1', 'first_name, last_name', '')

license_id 列に「unique license ID」というコメントを含む t1_license_id という名前の一意のインデックスも作成する場合は、次のステートメントを実行します。

CALL mysql.addSecondaryIdxOnReplica('unique', 't1_license_id', 'sampletest.t1', 'license_id', 'comment "unique license ID"')

t1_fname_lname インデックスを削除するには、次のステートメントを実行します。

CALL mysql.dropSecondaryIdxOnReplica('t1_fname_lname', 'sampletest.t1', '')

不適切な使用

次の例では、idxDefinition パラメータの外側の括弧が原因で、first_name 列と last_name 列にインデックスを作成しようとして失敗します。

CALL mysql.addSecondaryIdxOnReplica('', 't1_extra_parenthesis', 'sampletest.t1', '(first_name, last_name)', '')

インデックスを追加できるのは、お客様が作成したテーブルのみです。次の例では、mysql.servers テーブルの host 列にインデックスを作成しようとして失敗します。

CALL mysql.addSecondaryIdxOnReplica('', 'idx_invalid', 'mysql.servers', 'host', '')

dropSecondaryIdxOnReplica プロシージャを使用できるのは、以前に addSecondaryIdxOnReplica プロシージャを使用して作成したインデックスをドロップする場合のみです。たとえば、既存の idx_fname インデックスを削除する次の呼び出しは失敗します。

CALL mysql.dropSecondaryIdxOnReplica('idx_fname', 'sampletest.t1', '')

これらのプロシージャ呼び出しでの SQL インジェクションは失敗します。たとえば、コメント シーケンスを含む次の SQL インジェクションは失敗します。

CALL mysql.addSecondaryIdxOnReplica("user 'a'@'%' --", 'idx_fname', 'sampletest.t1', 'first_name', '')

同様に、区切り文字を使用した SQL インジェクションの試行は失敗します。

CALL mysql.addSecondaryIdxOnReplica('', 'idx_fname', 'sampletest.t1', 'first_name', ';flush status')

セルフマネージド レプリカ インデックスからマネージド レプリカ インデックスに移行する

マネージド レプリカ インデックスとセルフマネージド レプリカ インデックスは同じインスタンスに共存できますが、マネージド レプリカ インデックスに移行できます。

セルフマネージド レプリカ インデックスからマネージド レプリカ インデックスに移行する手順は次のとおりです。

  1. プライマリ インスタンスにインデックス定義を登録します。

    セカンダリ インデックスごとに、プライマリ インスタンスで mysql.cloudsql_replica_idx_defn_create を呼び出します。

    CALL mysql.cloudsql_replica_idx_defn_create
    ('INDEX_DEFINITION_NAME',
    'CREATE INDEX INDEX_NAME ON DATABASE.TABLE (COLUMNS)');

    プロシージャの出力から返された idx_id(定義の一意の整数識別子)をメモします。

  2. インデックス定義をレプリカ グループに追加します。

    プライマリ インスタンスで mysql.cloudsql_replica_idx_group_add を呼び出して、インデックス定義を指定されたレプリカ グループ名にマッピングします。

    CALL mysql.cloudsql_replica_idx_group_add
    (INDEX_DEFINITION_ID, 'REPLICA_GROUP');
  3. リードレプリカでレプリカ グループ フラグを構成します。

    リードレプリカ インスタンスの cloudsql_index_recreate_replica_group データベース フラグを、グループ名をターゲットに設定します。

    gcloud sql instances patch REPLICA_INSTANCE_NAME \
    --database-flags=EXISTING_FLAGS,cloudsql_index_recreate_replica_group=REPLICA_GROUP

    cloudsql_index_recreate_replica_group データベース フラグで指定されたグループ名が、mysql.cloudsql_replica_idx_group_add で指定されたグループ名と完全に一致していることを確認します。

  4. 既存のインデックスを確認または移行する:

    インデックスはリードレプリカにすでに存在するため、バックグラウンド プロセスがインデックスを作成しようとすると、mysql.cloudsql_replica_idx_status に FAILED ステータスのエラーが表示されることがあります。次のいずれかの方法を選択できます。

    • レプリカの再作成を待つ: ステータス テーブルの FAILED ステータスは無視してかまいません。Cloud SQL は、レプリカの再作成イベント後に、マネージド レプリカ インデックス メソッドを使用してセカンダリ インデックスを自動的に再作成します。
    • すぐに移行する: レプリカの再作成を待たずに Cloud SQL でインデックスをすぐに管理する場合は、リードレプリカに接続し、mysql.dropSecondaryIdxOnReplica ストアド プロシージャを使用してセルフマネージド インデックスを削除します。

      CALL mysql.dropSecondaryIdxOnReplica('INDEX_NAME', 'DATABASE.TABLE', '');

      次のバックグラウンド メンテナンス サイクル(約 5 分ごと)で、Cloud SQL はマネージド レプリカ インデックスを自動的に再作成して追跡します。

レプリカ インデックスのトラブルシューティング

レプリカ インデックスのトラブルシューティングを行うには、次の点を確認します。

  • レプリカ インスタンスでマネージド レプリカ インデックスが有効になっていることを確認します。

    マネージド レプリカ インデックスを使用している場合は、リードレプリカで cloudsql_index_recreate_enable データベース フラグが on に設定されていることを確認します。

    データベース フラグの構成の詳細については、データベース フラグを構成するをご覧ください。

  • オペレーションのステータスとエラーを確認する:

    リードレプリカに接続して mysql.cloudsql_replica_idx_status をクエリするか、CALL mysql.cloudsql_replica_idx_show_errors(); を実行して、失敗したオペレーションのエラー メッセージを表示します。1 つのインデックスで障害が発生しても、キュー内の後続のインデックスの実行はブロックされません。

次のステップ