建立及管理唯讀副本索引

本文說明如何在 Cloud SQL 唯讀副本上建立、維護及監控次要索引。

如要瞭解代管副本索引的運作方式,請參閱「唯讀副本索引總覽」。

代管副本索引

下表摘要說明建立、設定及監控代管副本索引的工作流程:

步驟 預存程序或資料庫旗標 執行步驟的位置
建立索引定義 CALL mysql.cloudsql_replica_idx_defn_create('INDEX_DEFINITION_NAME', 'CREATE_INDEX_STATEMENT');

這個預存程序會傳回索引定義 INDEX_DEFINITION_ID 的專屬整數 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 陳述式,完成目前工作階段中的變更。因此,使用這些預存程序執行的 data manipulation language (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 (定義的專屬整數 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) 陳述式。如果某個索引失敗,不會阻礙佇列中後續索引的執行。Cloud SQL 則會在約五分鐘後,挑選下一批。

如果索引建立失敗,Cloud SQL 會將狀態標示為 FAILED,並在一小時後自動重試。

mysql.cloudsql_replica_idx_status 資料表包含所有索引作業狀態項目,並包含下列資料欄:

  • idx_id:索引定義的專屬整數 ID。
  • create_stmt:CREATE INDEX SQL 陳述式。
  • action:正在執行的作業 (CREATE 或 DROP)。
  • thread_id:執行作業的 MySQL 執行緒 ID。
  • start_time:作業開始的時間戳記。
  • end_time:作業完成時的時間戳記。
  • retry_count:作業的重試次數。Cloud SQL 會在一小時後重試失敗的索引建立作業。
  • err_msg:上次失敗作業的錯誤訊息。
  • comment_tag:加在索引註解前的 [SIC_X_Y] 標記。這個標記僅用於內部管理,不具任何功能。
  • status:作業的目前狀態:
    • PENDING:索引作業已加入佇列。
    • RUNNING:索引作業已開始執行。
    • DONE:索引作業已成功完成。
    • FAILED:索引作業失敗。Cloud SQL 會在一小時後重試失敗的索引建立作業。

捨棄代管副本索引

如要從副本群組中移除索引,或完全刪除索引定義,請在主要執行個體上呼叫對應的預存程序:

  • 從副本群組中移除索引定義:

    在主要執行個體上呼叫 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)。副本一次只能指派給一個副本群組。副本會建構對應至這個副本群組名稱的所有索引。

自行管理的副本索引

Cloud SQL 在 mysql 結構定義中包含兩個儲存程序,可用於在 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 資料欄上建立名為 t1_license_id 的不重複索引,並加上「unique 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', '')

不當使用

下列嘗試在 first_name 和 last_name 資料欄上建立索引,但因 idxDefinition 參數中的外部括號而失敗:

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 (定義的專屬整數 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', '');

      在下一個背景維護週期 (約每五分鐘一次),Cloud SQL 會自動重新建立並追蹤代管副本索引。

疑難排解副本索引問題

如要排解副本索引問題,請確認下列事項:

  • 確認副本執行個體已啟用代管副本索引:

    如果您使用代管副本索引,請確認唯讀副本的 cloudsql_index_recreate_enable 資料庫旗標設為 on。

    如要進一步瞭解如何設定資料庫旗標,請參閱「設定資料庫旗標」。

  • 查看作業狀態和錯誤:

    連線至唯讀副本並查詢 mysql.cloudsql_replica_idx_status,或執行 CALL mysql.cloudsql_replica_idx_show_errors();,即可查看失敗作業的錯誤訊息。如果某個索引失敗,不會影響佇列中後續索引的執行。

後續步驟