本文介紹了對冷資料進行DDL的操作方法以及最佳化方法。
前提條件
DDL執行演算法
PolarDB MySQL版冷資料支援以下2種DDL執行演算法:
INSTANT演算法: 使用INSTANT演算法執行DDL操作時,只需要修改資料字典中的中繼資料,不需要修改或複製存量資料,也不需要重建表。因此其不受表的大小影響,整個DDL過程可以秒級完成。
COPY演算法:當使用COPY演算法執行DDL操作時,需要將表中所有的資料複製到新表中。在資料複製期間,會持有原表的SNW(SHARED_NO_WRITE)鎖。因此,在執行DDL操作期間僅支援讀操作,不允許執行並發寫入操作,對業務影響較大。
為了使用指定演算法執行DDL語句,您可以指定ALGORITHM欄位,可選的值有DEFAULT、INSTANT和COPY。當DDL操作不支援該演算法時,會立即返回報錯。
通常來說,INSTANT演算法比COPY演算法代價更低,執行影響更小。當使用者不通過ALGORITHM手動指定DDL使用的演算法時,PolarDB MySQL版會自動優先選擇INSTANT演算法,其次才考慮使用COPY演算法。因此,本文詳細介紹INSTANT演算法。
INSTANT演算法使用說明
8.0.2.2.23版本支援了OSS冷資料表的中繼資料(OSS META)能力。只有當表開啟OSS META時,才可以支援INSTANT DDL,否則只能支援COPY DDL。 使用方法如下:
查看當前表是否開啟OSS META。
通過
show create table
命令,可以查看當前表是否開啟了OSS META。如果返回結果中有OSS META=1 ,則說明當前表開啟了OSS META。show create table t \G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` varchar(1000) DEFAULT NULL ) /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ 1 row in set (0.00 sec)
老化情境下增加OSS META。
無論是InnoDB單表老化為OSS外表,還是InnoDB分區表歸檔至OSS外表,或是InnoDB表歸檔至OSS分區,在建立新的OSS外表時,都是通過系統變數 use_oss_meta來控制當前建立的OSS外表(分區)是否使用OSS META管理中繼資料。
當系統變數use_oss_meta為ON時,例如:
show variables like "use_oss_meta"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | use_oss_meta | ON | +---------------+-------+ 1 row in set (0.03 sec)
此時,歸檔至OSS外表會帶有OSS META標記:
alter table t engine = csv storage oss; Query OK, 3 rows affected (2.13 sec) Records: 3 Duplicates: 0 Warnings: 0 show create table t \G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` varchar(1000) DEFAULT NULL ) /*!50100 */ /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ 1 row in set (0.00 sec)
alter table t1 change partition p0 engine = orc; Query OK, 0 rows affected (1.95 sec) Records: 0 Duplicates: 0 Warnings: 0 show create table t1 \G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `order_time` datetime DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020223 OSS META=1 */ CONNECTION='default_oss_server' /*!99990 800020205 PARTITION BY RANGE COLUMNS(id) (PARTITION p0 VALUES LESS THAN (10) ENGINE = ORC, PARTITION p1 VALUES LESS THAN (20) ENGINE = InnoDB, PARTITION p2 VALUES LESS THAN (30) ENGINE = InnoDB, PARTITION p3 VALUES LESS THAN (40) ENGINE = InnoDB, PARTITION p4 VALUES LESS THAN (50) ENGINE = InnoDB, PARTITION p5 VALUES LESS THAN (60) ENGINE = InnoDB, PARTITION p6 VALUES LESS THAN (70) ENGINE = InnoDB, PARTITION p7 VALUES LESS THAN (80) ENGINE = InnoDB, PARTITION p8 VALUES LESS THAN (90) ENGINE = InnoDB, PARTITION p9 VALUES LESS THAN (100) ENGINE = InnoDB, PARTITION p10 VALUES LESS THAN (110) ENGINE = InnoDB) */ 1 row in set (0.00 sec)
對沒有OSS META的表添加META。
可以通過
repair
命令對沒有META的表額外增加OSS META。repair table t; +--------+--------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------+--------+----------+----------+ | test.t | repair | status | OK | +--------+--------+----------+----------+ 1 row in set (0.84 sec) show create table t \G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` varchar(1000) DEFAULT NULL ) /*!50100 */ /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ 1 row in set (0.00 sec)
說明在repair期間會持有表的X鎖,當前表無法查詢和修改。repair實際時間與表的大小有關。
關閉當前表的OSS META功能。
可以通過
disable
命令關閉當前表的META。alter table t disable oss meta; Query OK, 0 rows affected (0.04 sec) Records: 0 Duplicates: 0 Warnings: 0 show create table t \G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` varchar(1000) DEFAULT NULL ) /*!50100 */ /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ 1 row in set (0.00 sec)
關閉後,表上不會顯示OSS META標記。
說明執行
disable
命令關閉META後,無需重啟,即可生效。
DDL行為特徵
COLUMN操作
操作 | 重建表 | 僅修改中繼資料 |
增加列 | 否1 | 是1 |
刪除列 | 是 | 否 |
重新命名列 | 否 | 是 |
重排序列 | 是 | 否 |
設定列的預設值 | 否 | 是 |
修改列注釋 | 否 | 是 |
修改列類型 | 是 | 否 |
擴充VARCHAR長度 | 否 | 是 |
將UTF8mb3字元集修改為UTF8mb4字元集 | 否2 | 是2 |
刪除列預設值 | 否 | 是 |
修改auto-increment值 | 否 | 是 |
變更某列為NULL | 是 | 否 |
變更某列為非NULL | 是 | 否 |
修改ENUM/SET列的定義 | 否 | 是3 |
秒級加欄位功能僅支援將列添加至表的末尾。同時,需要當前表開啟OSS META 。當表未指定主鍵時,需要將參數
implicit_primary_key
的值設定為OFF,以避免在執行秒級加欄位操作時因表的最末尾的隱式主鍵列導致加列操作失敗。如果叢集不支援使用秒級加欄位功能,增加欄位將使用COPY方式執行DDL。此時需要進行全表重建,重建期間允許並發讀操作。當滿足以下條件時,將列的字元集從UTF8mb3修改至UTF8mb4僅修改中繼資料,無需修改資料。否則,需要使用COPY演算法進行表重建,且重建期間全程鎖表,目標表只能讀,不能執行寫入操作。
列類型為CHAR、VARCHAR、ENUM以及TEXT類型。
修改的列上不存在任何索引。
字元集轉換前後,列的最大儲存長度均小於256或均大於255。
您可以通過指定ALGORITHM=INSTANT 來強制使用非重建表的方式執行DDL,如果需要使用COPY演算法才能執行時,會立刻返回報錯。樣本如下:
ALTER TABLE test modify column b char(1) CHARACTER SET utf8mb4 default null,algorithm = INSTANT; ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE.
僅當資料類型的儲存大小不發生改變,且向ENUM或SET的末尾追加元素時,才可以僅修改中繼資料,不重建整張表。否則需要使用COPY演算法進行表重建。
Table操作
操作 | 重建表 | 僅修改中繼資料 |
開啟META | 是 | 否 |
關閉META | 否 | 是 |
聲明Character Set | 否 | 是 |
轉換Character Set | 是 | 否 |
重新命名表 | 否 | 是1 |
修改表注釋 | 否 | 是 |
重新命名表不會全部重寫表的資料,但是會對該表對應的OSS資料檔案做RENAME操作,因此rename速度和表大小呈正相關,略慢於其他的INSTANT操作。