
TDSQL-B即TDSQL Boundless是腾讯云新推出的产品。有幸被邀请内测他们的冷热数据分离的特性。

这里的COS = Cloud Object Storage,即腾讯云对象存储。
类似 AWS 的 S3、阿里云的 OSS,是腾讯云提供的海量、低成本、高可靠的云端对象存储服务。归档到 COS 的数据不在本地 SSD/云盘上,而是存在远程的对象存储集群中,所以访问延迟会比本地高一些(首访 ~80ms vs 本地 ~45ms),但存储成本大幅降低。
从设计上看是解决当前数据和历史数据的问题。例如随着业务持续运营,订单、流水、日志、审计等历史数据规模不断增长,但访问频率随时间显著降低。这类冷数据长期占用本地高性能存储,使存储成本居高不下,仅靠扩容本地存储难以经济地承载长期保留需求。
TDSQL Boundless 提供的冷数据归档功能,可将冷数据从本地高性能存储下沉到对象存储(COS),让不同访问特征的数据匹配最合适的存储介质,兼顾性能与成本。本次实验的目标:
• 在真实 TDSQL Boundless 实例上开启并验证冷数据归档功能;
• 通过标准 SQL 显式控制整表/分区的冷热属性,验证冷热分离的可操作性;
• 实测冷数据落地 COS 后的读写性能,量化冷热访问差异;
• 梳理冷数据从写入、CacheDB 缓冲到 DurableDB(COS)归档的完整数据流,给出可落地的生产建议。
冷数据归档在原有热数据存储基础上,新增两层冷存储:
存储层 | 定位 | 承载介质 | 说明 |
|---|---|---|---|
DataDB(热) | 热数据存储 | 本地 SSD / 高性能云盘 | 未转冷数据,读写性能与未启用归档时一致 |
CacheDB(冷缓冲) | 冷数据本地缓冲 | 节点内本地存储 | 承接冷表近期写入与正在上传 COS 的数据 |
DurableDB(冷归档) | 冷数据最终归档 | 对象存储 COS | 以复制组(RG)为单位持久化,多 AZ 容灾 |
• 写入(先本地、后远端):冷表写入先进入 CacheDB 落盘形成 SST 文件,再异步攒批上传到 DurableDB(COS),对应用呈现为同步写入;上传成功后 CacheDB 中的 SST 被异步清除。
• 读取(先本地、再远端):按 CacheDB + DurableDB 合并视图返回结果;最近写入优先在 CacheDB 命中,历史全量由 DurableDB 承载;读取 DurableDB 的 SST 时先拉取到本地 COS file cache,加速下次访问。
特殊场景比如归档数据,可以通过 ALTER TABLE ... STORAGE_TIER = OBJECT_STORAGE 触发,系统后台自动完成转冷。
具体内部阶段由系统自行处理,不影响使用。
申请了云环境。通过一些配置,终于能在自己笔记本上能链接了。
实例连接:mysql -udbaadmin -p'****' -h 106.55.69.143,内核版本 8.0.26.0.0-sqlengine-21.6.3.0,满足冷数据归档要求的 V21.6.3.0 及以上版本。
功能开启:冷数据归档默认关闭,需通过控制台实例详情页「数据归档」开关开启。这一点开始以为是自动的,怎么测试都不行。而且还以为是手工改参数就可以。实际上不行。需要通过WEB页面的控制开关去操作。
开启后状态变量校验:

前提条件(与官方一致):节点规格 4C 以上、全功能型多副本/多可用区、增强型 SSD 云硬盘、预置资源实例;不支持 TDE、Binlog 服务、只读分析引擎、单副本、本地盘、Serverless 等。
开始不知道怎么做,看了文档才知道是建表时候指定。例如:
CREATE TABLE recent_orders
(
order_id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
product_name VARCHAR(200),
amount DECIMAL(10,2) NOT NULL,
order_time DATETIME NOT NULL,
status VARCHAR(20) DEFAULT 'pending', I
NDEX idx_user (user_id), I
NDEX idx_time (order_time))
STORAGE_TIER = LOCAL_STORAGE;
所以关键看STORAGE_TIER的值。如果是OBJECT_STORAGE,那么就是直接把表放到里对象存储上。
方式 | SQL 语法 | 特点 | 适用场景 |
|---|---|---|---|
整表冷表 | CREATE TABLE ... STORAGE_TIER = OBJECT_STORAGE | 整张表都是冷数据,写入先落 CacheDB 再异步上传 COS | 日志表、审计记录表、历史归档表 |
整表热表 | CREATE TABLE ... STORAGE_TIER = LOCAL_STORAGE | 整张表都是热数据,性能与未启用归档一致 | 订单表、用户表、配置表等高频访问表 |
分区表冷热混合 | PARTITION BY ... (PARTITION ... STORAGE_TIER = ...) | 不同分区可独立指定冷热属性 | 有明显时间特征的表(订单、流水) |
• 意义:同一张表内实现「近期分区为热、历史分区为冷」,无需拆表即可分层,热分区保性能、冷分区降成本。
• 推荐:有明确时间特征的业务表(如订单按月/天分区)优先采用「分区表冷热混合」,并配合滚动转冷策略(历史分区逐步转冷)。
• 注意事项:当前版本不支持冷数据转热(回暖);冷分区不支持分裂/合并/迁移;写入直接落冷表的数据需 CacheDB 单节点 L2 层攒批超阈值才自动上传 COS(见第五节)。
• 热变冷的干预方式(手动):整表 ALTER TABLE t STORAGE_TIER = OBJECT_STORAGE;分区 ALTER TABLE t MODIFY PARTITION (p_x) STORAGE_TIER = OBJECT_STORAGE。
本次实验创建三类表,覆盖上述三种定义方式。具体建表就不在这里赘述了。
包括自己造数据写入大量数据,这些都是让agent去完成。因为真的要写大量数据,少量数据触发不出数据热转冷。下面详细说一下。
为什么要导入大量数据、并设计两条路径?因为冷数据归档存在两种不同的数据落盘链路,必须分别验证:(这里我自定义的表不重要,重要的是产品实现的两种方式,一种是自动,一种是手动)
• 路径一(建表即冷表,如 orders_cold):写入数据先存 CacheDB,需 CacheDB 单节点 L2 层攒批超过 2.5GB 才触发上传 COS。为观察这条自动攒批链路,向 orders_cold 灌入约 5050 万条(2.7GB)。
• 路径二(热表 ALTER 转冷,如 trigger_demo):先建热表写入少量数据,再执行 ALTER TABLE 转冷,转冷流程直接把数据从热存上传 COS,不依赖 2.5GB 阈值。这条路径能快速、确定地验证数据真正落地 COS。
表 | 冷热属性 | 数据量级 | 说明 |
|---|---|---|---|
orders_hot | 热(LOCAL_STORAGE) | 50 万条 | 热表基准 |
orders_cold | 冷(建表即 OBJECT_STORAGE) | 约 5050 万条 / 2.7GB | 验证自动攒批上传链路 |
trigger_demo | 热→冷(ALTER 转冷) | 50 万条 | 验证数据落地 COS |
执行 ALTER TABLE trigger_demo STORAGE_TIER = OBJECT_STORAGE 后,系统后台异步推进转冷。通过转冷任务进度视图监控,调度成功:
rep_group_id | stage | uploaded_file_num | total_file_num | progress_pct |
|---|---|---|---|---|
15861249 | Done | 3 | 3 | 100.000000 |
转冷任务已调度成功,数据已上传至 COS(DurableDB)。通过 SHOW CREATE TABLE 确认归档结果:

orders_cold 建表即冷表,写入约 2.7GB 数据。按官方机制,CacheDB 单节点 L2 层攒批超 2.5GB 才触发 uploader 上传 COS。当前各节点 L2 数据量:
节点 | CacheDB L2 层数据量 | 是否超 2.5GB 阈值 |
|---|---|---|
node-001 | 1.35 GB | 否 |
node-002 | 1.37 GB | 否 |
node-003 | 1.24 GB | 否 |
单节点均未超阈值,uploader 尚未触发,符合「自动攒批、达到阈值才上传」的设计预期。为快速、确定地验证 COS 落地效果,本实验采用 6.1 的「热表转冷」路径已成功实现数据到 COS;orders_cold 在持续写入使单节点 L2 超阈值后将自动触发上传。
为保证对比公平,性能测试采用同等数据量原则:热表 orders_hot 与冷表 COS trigger_demo 均为 50 万条(约 16MB),排除数据量差异对结果的干扰。orders_cold(5050 万条 / 2.7GB)仅作为大数据量冷存参考,不参与公平对比。
每个查询执行 5 次:第 1 次为首访(可能触发 COS 拉取或 RocksDB 首次加载),第 2~5 次为缓存命中后的稳定值。
表 / 场景 | 首访耗时 | 缓存命中均值 |
|---|---|---|
热表 orders_hot(本地热存,50 万条) | 32 ms | 29 ms |
冷表 COS trigger_demo(COS,50 万条) | 33 ms | 28 ms |
冷表 COS trigger_demo(首次访问,未预热) | 83 ms | 28 ms |
冷表 CacheDB orders_cold(2.7GB 大表) | 38 ms | 33 ms |
看上去数据这两者耗时没有明显差异,这个问题上纠结了很久。最后还是从后台日志中看到主键查询内核执行时间 < 1ms,即数据库执行实际耗时不足1ms,其他时间开销为网络延迟。

两张表均建有 idx_user 索引,查询返回 3~5 行:
表 / 场景 | 首访耗时 | 缓存命中均值 |
|---|---|---|
热表 orders_hot(本地热存,50 万条) | 35 ms | 32 ms |
冷表 COS trigger_demo(COS,50 万条) | 32 ms | 32 ms |
冷表 CacheDB orders_cold(2.7GB 大表) | 93 ms | 47 ms |
由于有了之前的结论:所以这里也是因为网络因素导致,其真实的数据也是在1ms左右。因为测试机跟数据库实例之间有20~30ms左右的网络时延。
两张表均建有 idx_time 索引,查询扫描约 4 万行:
表 / 场景 | 首访耗时 | 缓存命中均值 |
|---|---|---|
热表 orders_hot(50 万条,本地热存) | 602 ms | 319 ms |
冷表 COS trigger_demo(50 万条,COS) | 235 ms | 242 ms |
冷表 CacheDB orders_cold(5050 万条,本地缓冲) | 34411 ms | 8339 ms |
同理使用索引的范围扫描都存在20~30ms左右的网络时延。
表 / 场景 | 首访耗时 | 缓存命中均值 |
|---|---|---|
热表 orders_hot(50 万条) | 53 ms | 54 ms |
冷表 COS trigger_demo(50 万条) | 110 ms | 112 ms |
冷表 CacheDB orders_cold(5050 万条) | 10376 ms | 10462 ms |

而对于count这样的查询,在绕过网络层面直接到后台查询,也可以看到有30ms左右的误差。所以又一次佐证了前面的推论。
本次测试的全部应用层耗时包含 20~30ms 网络时延,存储引擎内核执行时间远低于应用层测量值(主键 < 1ms、50 万行全表扫描 ~80ms)。
校正后结论:
① 热存数据与 COS 的存储层性能差异很小,主键点查均为毫秒级以内;
② 冷存数据首访 COS 存在一次网络拉取(83ms 为应用层含网络开销值),预热后回落至与热存持平;
③ 大数据量(5050 万条)冷存数据,全表扫描约 10s,适合低频访问场景。
重点是通过COS分离了数据,降低了存储代价。实现了冷热数据的分离,且随时可以访问冷数据。
本次实验在真实 TDSQL Boundless 实例上完成了冷数据归档端到端验证:建表即冷表与热表 ALTER 转冷两条路径均得到验证,并通过「热表转冷」路径确定性地观测到数据上传 COS(转冷任务 Done、首访时延体现远端拉取)。以下为实验中遇到的问题与处理经验:
• 冷数据归档功能默认关闭:需在控制台实例详情页「数据归档」开关手动开启,并用 SHOW STATUS 校验 service_state = enabled。
• 建表即冷表的数据不会立即上传 COS:需 CacheDB 单节点 L2 层攒批超 2.5GB 才触发 uploader;若想快速、确定性地验证 COS 落地,应采用「先建热表写数据、再 ALTER TABLE 转冷」的路径,转冷流程会直接上传 COS。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。