数据库中很少被访问的历史数据长期占用PolarDB块存储,会持续产生存储成本。归档为IBD格式在不更换InnoDB存储引擎的前提下,把这部分冷数据转存到成本更低的对象存储 OSS,归档后的数据仍保留原有的InnoDB数据格式、索引结构和 DML 能力。MySQL 8.0.1和MySQL 8.0.2都支持该功能,但归档语法、支持的归档对象和归档后的可操作范围不同。
确认集群版本对应的归档方式
基础版和高级版都支持将冷数据归档为 IBD 格式,但底层实现不同:基础版在 InnoDB 侧封装 OSS 访问能力,高级版基于共享存储 PolarStore 提供 OSS 混合存储能力,两者的归档语法、支持的归档对象和归档后的可操作范围不同,语句不能混用。
对比项 | 基础版 | 高级版 |
实现逻辑 | 在 InnoDB 存储引擎侧封装 OSS 访问能力,数据直接从 InnoDB 读写 OSS | 基于共享存储 PolarStore 提供 OSS 混合存储能力,存储层统一管理冷热数据 |
支持版本 | MySQL 8.0.1且修订版本需为 8.0.1.1.51.2 或以上。 |
|
支持的归档对象 | 普通表 | 普通表和分区表,分区表可归档全部或指定分区 |
归档语法 |
|
|
归档后的 DDL 操作 | 不支持 | 支持增加列、创建索引、调整分区等常见 DDL 操作 |
查询归档数据 | 归档整表后直接查询 | 分区表默认跳过归档分区,可通过 |
导回块存储 | 整表导回 | 整表、指定分区或全部已归档分区导回 |
通用适用范围
已开启冷数据归档功能。
不支持全球数据库网络(GDN)中的集群归档为 IBD 格式。
操作指南
基础版
基础版是基于 InnoDB 存储引擎封装 OSS 访问能力,支持将普通表整体归档到 OSS 对象存储。该版本后续仅包含缺陷修复,不再进行功能迭代。如需分区级归档、归档后 DDL 等进阶能力,请使用高级版。
准备工作
MySQL 8.0.1且修订版本需为 8.0.1.1.51.2 或以上。
如需使用归档为 IBD 格式,请前往配额中心,根据配额 ID
polardb_innodb_oss_enable找到配额名称,在对应的操作列单击申请开通该功能。
注意事项
读写与事务限制(DML & DDL)
DML与事务支持:归档后的表支持正常的
INSERT、UPDATE、DELETE等 DML 操作,并支持事务。DDL 限制:不支持 DDL 操作。表一旦归档到 OSS,将无法修改表结构。
归档过程中的可用性
数据访问中断:在执行冷数据归档的过程中,默认无法访问正在归档中的表数据。
临时规避方案:如果需要在归档期间保持可读,须提前将参数
polar_oss_ddl_shared的值设置为ON。
备份与数据安全
不包含在标准数据备份中:自动备份和手动备份均不包含存储在 OSS 上的数据。
恢复限制:无法对 OSS 上的数据执行库表恢复或按时间点恢复操作。
性能影响与运维建议
归档期间资源消耗:归档冷数据会占用一定量的网络和存储 I/O 资源,建议在业务低峰期或非活跃集群上执行。
高延迟风险:对象存储(OSS)的 I/O 延迟比块存储高百倍以上,需评估因此导致的长 SQL 延迟影响。
大批量写操作避坑:对OSS表执行大量写入或删除前,建议先将表导回块存储,否则会引发以下严重后果:
缓存污染:消耗大量数据库 Buffer Pool(页缓存)资源,导致其他正常表的 SQL 因无法获取空闲页面而变慢。
阻塞 Checkpoint:大量 OSS 脏页持久化缓慢,会阻塞 Checkpoint 推进,从而拉长数据库崩溃恢复时间。
拖慢崩溃恢复:崩溃恢复过程中,对OSS表的日志回放会触发 OSS 读写,进一步拖慢崩溃恢复速度。
将表数据归档至 OSS
当表中的数据为冷数据且对延迟不敏感,或访问集中、可被缓存且对尾访问延迟不敏感时,通过以下语法将块存储表转换为 OSS 对象存储表:
ALTER TABLE table_name STORAGE_TYPE OSS;将数据导回块存储
ALTER TABLE table_name STORAGE_TYPE NULL;删除 OSS 上对应的文件
将 OSS 上的表删除或导回块存储后,OSS 上的文件不会同步删除。确定数据不再使用后,使用如下语法删除 OSS 上对应的文件:
CALL dbms_oss.delete_table_file('database_name', 'table_name');删除 OSS 上对应文件的操作异步执行,需要等待集群中的所有节点都不再依赖 OSS 文件后才可完全删除,且流量较大时存在一定延迟。如果上述命令执行失败并返回错误信息 OSS files are still in use,可等待一段时间后重新执行该命令。
示例
以下示例包含删除表、删除数据库和删除 OSS 上归档文件的操作,请在测试数据库中执行。
数据备份不包含 OSS 上的数据,删除后无法通过库表恢复或按时间点恢复找回。确认数据不再使用后,再删除 OSS 上对应的文件。
创建数据库。
CREATE DATABASE oss;使用数据库。
USE oss;创建表
toss1。CREATE TABLE `toss1`( `uid` int NOT NULL AUTO_INCREMENT, `text_data` text NOT NULL, `save_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY(`uid`) ) ENGINE = InnoDB;创建存储过程
populate。DELIMITER | CREATE PROCEDURE populate(IN `cnt` INT) BEGIN DECLARE i INT DEFAULT 1; WHILE (i <= cnt) DO INSERT INTO `toss1` (`text_data`) VALUES (REPEAT("#", 6333)); SET i = i + 1; END WHILE; END | DELIMITER ;调用存储过程,向表
toss1中插入数据。CALL populate(5000);将数据归档至 OSS。
ALTER TABLE `toss1` STORAGE_TYPE OSS;查询
toss1表中的数据。SELECT COUNT(*) FROM `toss1`;删除 OSS 上的
toss1表。DROP TABLE `toss1`;删除 OSS 数据库。
DROP DATABASE oss;确认数据不再使用后,删除 OSS 上对应的文件。
CALL dbms_oss.delete_table_file('oss', 'toss1');
冷数据归档耗时
执行冷数据归档操作的并发线程数量由参数 innodb_oss_copy_worker 控制,其参数值与集群规格绑定。不同线程数量和数据量下的冷数据归档耗时如下:
单张表的数据量 | 归档耗时(4 个线程) | 归档耗时(8 个线程) |
100 GB | 约 18 分钟 | 约 10 分钟 |
1 TB | 约 2.5 小时 | 约 1.3 小时 |
10 TB | 约 24 小时 | 约 13 小时 |
高级版
高级版是基于共享存储 PolarStore 提供 OSS 混合存储能力,支持普通表和分区表的归档,并可按分区粒度操作。归档后仍支持常见 DDL 操作,是功能更完整的归档方案。
准备工作
MySQL 8.0.2且修订版本需为8.0.2.2.37或以上,且存储类型需为PSL4或PSL5,不支持ESSD云盘。
在控制台中,开启
loose_polar_oss_enable参数。目标表使用独立表空间,且存储引擎为 InnoDB。分区表的所有分区均须使用 InnoDB 引擎。不支持压缩表和通用表空间。
在主节点(主地址)上执行归档、查询和导回操作,且当前账号具备目标表的操作权限。
注意事项
读写与分区行为(DML)
DML 与事务支持:归档后的表和分区仍可修改,支持
INSERT、UPDATE、DELETE操作及事务。分区表特有行为:
查询:默认会自动跳过已归档的分区。
更新与删除:
UPDATE和DELETE操作不会跳过归档分区。执行前请务必确认操作的影响范围,避免误修改或因 OSS 延迟导致请求堆积。
结构变更支持(DDL 规则)
DDL 能力提升:支持增加列、创建索引、调整分区等常见 DDL 操作(须满足 InnoDB 自身限制)。
归档状态继承:归档状态会随表结构变更自动保留或调整。但在分区重组(Reorganize Partition)后,建议重新手动确认各分区的归档状态。
语法限制(不准合并):
归档和导回操作必须单独执行,不能与其他表结构变更(如加列、改类型)合并在同一条
ALTER TABLE语句中。执行归档和导回时,不能显式指定
ALGORITHM=COPY或ALGORITHM=INSTANT(此限制仅针对归档动作本身,不影响已归档表执行普通的 COPY DDL)。
表压缩与表空间限制
执行以下操作前,需要先将相关表或分区的数据从 OSS 导回块存储。导回操作不改变表的 InnoDB 存储引擎。
启用表压缩:归档状态下不支持
ROW_FORMAT=COMPRESSED和页压缩,启用前需先导回数据。迁入通用表空间:通用表空间允许多张表共享同一个数据文件。OSS 归档要求每张表或每个分区使用独立的
.ibd文件,因此不支持归档通用表空间中的表。已归档的表迁入通用表空间前,需先导回数据。导入或丢弃表空间:执行
IMPORT TABLESPACE(导入表空间文件)或DISCARD TABLESPACE(丢弃表当前使用的表空间)前,需先导回数据。DISCARD TABLESPACE不是导回操作,不能用于将数据迁回块存储。
透明数据加密(TDE)
完全支持 TDE。归档和导回操作不会改变表已有的加密属性。
若需修改加密属性,请使用默认算法或显式指定
ALGORITHM=COPY,不支持ALGORITHM=INPLACE。
备份、安全与运维建议
归档不等于备份:
DROP和TRUNCATE操作仍会物理删除或清空 OSS 上的数据,严禁将其作为备份替代方案。并发阻塞与资源占用:归档和导回操作会锁定目标表,可能阻塞并发读写,且占用网络与存储 I/O。建议在业务低峰期执行。
大批量修改建议:由于 OSS 访问延迟高于块存储,在需要对归档数据进行大批量修改前,仍建议先将数据导回块存储执行。
将表数据归档至 OSS
归档适用于访问频率较低、对延迟不敏感的数据。在 CREATE TABLE 语句中指定 STORAGE_TYPE 不会使新建的表自动归档,需先创建表,再执行归档操作:
ALTER TABLE table_name STORAGE_TYPE HYBRID_OSS;该语法同样适用于分区表,执行后会归档表中的所有分区。
将指定分区归档至 OSS
-- 归档一个分区。
ALTER TABLE table_name MODIFY PARTITION p0 STORAGE_TYPE HYBRID_OSS;
-- 归档多个分区。
ALTER TABLE table_name MODIFY PARTITION p0, p1 STORAGE_TYPE HYBRID_OSS;整表数据均为冷数据时归档整表,仅部分分区为冷数据时归档指定分区,不要对同一分区重复执行归档。若表包含子分区,可以填写子分区名,填写父分区名时,会归档该父分区下的所有子分区。
查询归档数据
已归档的普通表可以直接查询,用法与归档前一致。分区表默认只查询未归档的分区,需要同时查询归档分区时,可在语句中添加 WITH ARCHIVED,或关闭当前会话的归档分区过滤。
单次查询:在表名后添加
WITH ARCHIVED,只对添加该子句的语句生效,适合单次查询归档数据:-- 查询未归档分区。 SELECT * FROM table_name; -- 查询数据时包含归档分区。 SELECT * FROM table_name WITH ARCHIVED;当前会话生效:关闭当前会话的归档分区过滤后,普通查询即可包含归档分区。该方式对整个当前会话生效,适合需要持续查询归档数据的场景:
SET SESSION prune_archived_oss_partitions=OFF;参数
prune_archived_oss_partitions的默认值为 ON。设置为 OFF 后,查询仍会按WHERE条件和正常的分区规则筛选数据。如需恢复默认行为,将该参数的值设置为 ON。
查看归档状态
SHOW CREATE TABLE table_name;返回结果中,表或对应分区带有 STORAGE_TYPE HYBRID_OSS 时,表示该对象已归档。
将数据导回块存储
导回操作会保留业务数据,并取消相应表或分区的归档状态。
-- 导回普通表;用于分区表时,导回所有已归档分区。
ALTER TABLE table_name STORAGE_TYPE NULL;
-- 仅导回指定分区。
ALTER TABLE table_name MODIFY PARTITION p0 STORAGE_TYPE NULL;
-- 导回所有已归档分区。
ALTER TABLE table_name MODIFY PARTITION ALL STORAGE_TYPE NULL;需要恢复整表或分区表的全部已归档分区时使用第一条语句,只需恢复个别分区时使用 MODIFY PARTITION 指定分区。指定的分区必须处于归档状态。使用 ALL 时,会选择当前已归档的分区。
示例
以下示例分别演示普通表和分区表的操作,请在测试数据库中执行。示例使用少量数据展示操作方法,实际节省的存储空间与表的大小有关。
普通表
创建表并写入数据。
CREATE TABLE archive_orders ( id INT NOT NULL PRIMARY KEY, amount INT NOT NULL ) ENGINE=InnoDB; INSERT INTO archive_orders VALUES (1,100), (2,200), (3,300);归档后查询,仍可读取全部 3 条记录。
ALTER TABLE archive_orders STORAGE_TYPE HYBRID_OSS; SELECT COUNT(*) FROM archive_orders; SHOW CREATE TABLE archive_orders;将数据导回块存储。
ALTER TABLE archive_orders STORAGE_TYPE NULL;
分区表
创建分区表,每个分区写入一条记录。
CREATE TABLE archive_orders_part ( id INT NOT NULL PRIMARY KEY, amount INT NOT NULL ) ENGINE=InnoDB PARTITION BY RANGE(id) ( PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20), PARTITION pmax VALUES LESS THAN MAXVALUE ); INSERT INTO archive_orders_part VALUES (1,100), (11,200), (21,300);仅归档分区
p0,其他分区保持不变。ALTER TABLE archive_orders_part MODIFY PARTITION p0 STORAGE_TYPE HYBRID_OSS;对比普通查询和包含归档数据的查询。
SET SESSION prune_archived_oss_partitions=ON; -- 返回 2;归档分区被跳过时可能伴随警告。 SELECT COUNT(*) FROM archive_orders_part; -- 返回 3,包含归档分区中的记录。 SELECT COUNT(*) FROM archive_orders_part WITH ARCHIVED;导回分区
p0后,普通查询即可读取全部 3 条记录。ALTER TABLE archive_orders_part MODIFY PARTITION p0 STORAGE_TYPE NULL; SELECT COUNT(*) FROM archive_orders_part;