如何正確處理DDL異常
更新時間:
Copy as MD
本文介紹處理DDL異常的常用方法。
概述
作為一款分散式資料庫,PolarDB-X中的一條DDL語句背後隱藏著複雜的資料處理流程。例如建立一張拆分表時,實際上會在多個資料節點上建立很多張物理MySQL表。PolarDB-X的DDL處理架構擁有一定的容錯能力,會保證DDL的正確性和一致性。但在特殊情況下,需要手動處理DDL異常。
處理步驟
下面以建立全域唯一二級索引為例,介紹處理DDL異常的步驟。建立全域唯一二級索引時,會校正列中資料的全域唯一性,如果發現列中資料不唯一,則會導致DDL的執行失敗。此時DDL的狀態可能變為“PAUSED”或“ROLLBACK_PAUSED”。
- 查看DDL的執行狀態
執行
SHOW DDL語句,查看DDL的執行狀態。只有當DDL狀態為“PAUSED”或“ROLLBACK_PAUSED”時,才需要手動處理。SHOW DDL\G; *************************** 1. row *************************** JOB_ID: 1359992239576580096 OBJECT_SCHEMA: d1 OBJECT_NAME: t1 ENGINE: DAG DDL_TYPE: ALTER_TABLE STATE: PAUSED BACKFILL_PROGRESS: 0% PHY_DDL_PROGRESS: 100% PROGRESS: 80% START_TIME: 2021-08-05 13:57:57.852 END_TIME: 2021-08-05 13:58:30.804 ELAPSED_TIME(MS): 32952 PHY_PROCESS: CANCELABLE: true 1 row in set (0.03 sec) - 判斷錯誤原因
通常DDL異常發生時,會直接返回錯誤資訊。有時DDL的錯誤資訊可能難以擷取(例如DDL是非同步執行的),可以通過
SHOW DDL RESULT語句查看近期執行過的DDL。在本樣本中,從返回的錯誤資訊中看到出現了UNIQUE KEY的衝突。ALTER TABLE t1 ADD unique global INDEX `idx_c2`(`c2`) DBPARTITION BY HASH(`c2`) tbpartition by hash(c2) tbpartitions 3; ERROR 3009 (HY000): [12dfa9bc5c800000][30.39.226.95:8527][d1]Failed to execute the DDL task. Caused by: ERR-CODE: [TDDL-5321][ERR_GLOBAL_SECONDARY_INDEX_BACKFILL_DUPLICATE_ENTRY] Duplicated entry '100018' for key 'PRIMARY' SHOW ddl result\G; *************************** 1. row *************************** JOB_ID: 1359992239576580096 SCHEMA_NAME: d1 OBJECT_NAME: t1 DDL_TYPE: ALTER_TABLE RESULT_TYPE: ERROR RESULT_CONTENT: Failed to execute the DDL task. Caused by: ERR-CODE: [TDDL-5321][ERR_GLOBAL_SECONDARY_INDEX_BACKFILL_DUPLICATE_ENTRY] Duplicated entry '100018' for key 'PRIMARY' - 恢複或取消DDL
大多數情況下,DDL出錯時都能夠自動回復或取消。特殊情況需要手動處理DDL異常。各個DDL的容錯策略可能不同,例如
CREATE TABLE語句的容錯策略是:自動嘗試恢複,多次失敗則自動取消。可以手動恢複或取消DDL任務。- 手動恢複:使用
CONTINUE DDL語句可以恢複DDL任務。 - 手動取消:使用
CANCEL DDL語句可以取消DDL任務。有些DDL任務可能是無法取消的,可以通過SHOW DDL語句返回的“CANCELABLE”欄位查看是否可以取消。
-- 處理完UNIQUE KEY的資料衝突後,可以使用continue ddl語句繼續執行 CONTINUE ddl 1359992239576580096; Query OK, 1 row affected (1.63 sec) -- 如果不想再繼續添加這個全域唯一二級索引,則可以直接取消任務 CANCEL ddl 1359992239576580096; Query OK, 1 row affected (0.03 sec) - 手動恢複:使用
- 檢查表一致性和正確性
DDL執行成功後,建議使用以下語句檢查表的一致性和表結構的正確性:
- 使用
CHECK TABLE語句檢查表的一致性:如果返回結果為OK,說明表已經處於一致性狀態,可以正常使用;如果返回報錯資訊,提示表處於不一致狀態,請聯絡阿里雲支援人員。 - 使用
SHOW CHECK TABLE語句查看錶結構的正確性。
CHECK TABLE t1; +-------+-------+----------+----------+ | TABLE | OP | MSG_TYPE | MSG_TEXT | +-------+-------+----------+----------+ | d1.t1 | check | status | OK | +-------+-------+----------+----------+ 1 row in set (0.05 sec) SHOW CHECK TABLE t1\G; *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `c1` bigint(20) NOT NULL AUTO_INCREMENT BY GROUP, `c2` bigint(20) DEFAULT NULL, `c3` bigint(20) DEFAULT NULL, PRIMARY KEY USING BTREE (`c1`), UNIQUE GLOBAL KEY `idx_c2` (`c2`) COVERING (`c1`) DBPARTITION BY HASH(`c2`) TBPARTITION BY HASH(`c2`) TBPARTITIONS 3 ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 dbpartition by hash(`c1`) tbpartition by hash(`c1`) tbpartitions 3 1 row in set (0.02 sec) - 使用
该文章对您有帮助吗?