数据为什么需要归档

业务跑几年,订单表、日志表、流水表动辄上亿行。数据越来越多,问题一串串冒出来:查询越来越慢,因为索引和缓冲池都喂不饱大数据量;备份越来越重,全量备份时间从小时级变成天级;历史数据挤占了热数据的缓存空间,明明只查最近三个月,却被五年前的数据拖慢。

归档的本质是给数据分级:把还在被频繁访问的"热数据"留在原表,把很少访问、只为合规留存或偶尔追溯的"冷数据"移到归档区。数据总量不变,但热库变轻了,性能、备份、运维全部受益。

本文核心知识点
  • 热数据高频访问,留在原表。
  • 冷数据低频访问,移入归档区。
  • 分区表按时间分区,便于裁剪与搬移。
  • 生命周期定义数据的产生、归档与销毁。
数据归档与冷热分层配图:蓝紫渐变背景左侧档案柜上层抽屉橙色表示热数据、下层抽屉灰色表示冷数据,中间传送带输送蓝色方块到右侧多层货架,扁平科技插画
上层活跃、下层归档,数据像文件柜里的文件一样分级存放。

冷热分层与访问模式

冷热分层的第一步是摸清访问模式:哪些表的数据只在最近 N 天被查?哪些表的历史数据只有对账、审计时才被碰?通过慢日志与查询统计就能画出热度曲线。常见规律:订单与流水按时间衰减,近 90 天占查询九成;日志类数据近 30 天之后几乎无人问津。

分层不是一刀切,可以按温度分多档:热库(在线、毫秒级查询)、温库(在线但少查,可放低成本存储)、冷库(离线归档,接受分钟级查询或查原始文件)。分层越细,成本优化空间越大,但管理复杂度也越高,小团队先做热冷两档就够了。

-- 查看各表数据量与最后访问时间,确定冷热
SELECT table_name, table_rows,
       UPDATE_TIME, CREATE_TIME
FROM information_schema.tables
WHERE table_schema = 'appdb';

归档表与分区表设计

归档区可以放在原库的归档表,也可以放到独立库甚至独立存储。设计归档表时,字段结构与原表保持一致,但可以去掉只在热查询里用到的二级索引,减少写入成本;唯一约束要保留,防止重复归档。分区表是冷热分层的最佳搭档:按业务时间做 RANGE 分区,归档就是搬一个分区,而不是删百万行。

CREATE TABLE orders (
  id BIGINT,
  order_time DATETIME,
  -- 其他业务字段省略
) PARTITION BY RANGE (YEAR(order_time) * 100 + MONTH(order_time)) (
  PARTITION p202501 VALUES LESS THAN (202502),
  PARTITION p202502 VALUES LESS THAN (202503),
  PARTITION p202510 VALUES LESS THAN (202511)
);

分区表让查询自动裁剪:带分区键的查询只扫对应分区,不带分区键则全分区扫描,所以业务查询要尽量带上时间条件。归档时用 EXCHANGE PARTITION 把整个分区原子地换到归档表,秒级完成,不产生大量删除日志。

归档流程与定时任务

归档是个周期性动作,靠定时任务驱动。典型流程:任务扫描分区或按时间条件找过期数据;先把数据复制到归档表,确保归档区完整;再删除原表数据;最后记录归档日志,更新元数据。复制与删除之间要留窗口,防止业务查询读到正在搬移的数据。

-- 归档示意:插入归档表再删原表
INSERT INTO orders_archive
  SELECT * FROM orders
  WHERE order_time < DATE_SUB(NOW(), INTERVAL 90 DAY)
  LIMIT 10000;

DELETE FROM orders
  WHERE order_time < DATE_SUB(NOW(), INTERVAL 90 DAY)
  LIMIT 10000;
归档任务要点
  • 分批小批量循环,避免长事务。
  • 窗口错开业务高峰执行。
  • 幂等重复执行不产生重复数据。
  • 日志记录每批归档的条数与时间。

分区表的归档更简单:到期分区直接 EXCHANGE 出去,再把新分区挂进来。定时任务要加互斥锁,防止多实例同时跑把数据搬重了。

查询改造与数据生命周期

归档后,原来"一条 SQL 查全表"的写法要改造:历史查询走归档库或归档接口,近期查询走热库;对账类任务改为按时间分段并行跑,先热库后冷库再合并结果。应用层要感知数据分层,不能让用户感觉"查不到历史数据",常见做法是提供统一的查询入口,底层自动路由冷热。

// 查询路由示意:先热库,再归档库
result = queryHot("orders", conditions);
if (result.empty) {
  result = queryArchive("orders_archive", conditions);
}

数据生命周期管理把归档纳入常态:定义每类数据的留存期限、归档时机与最终销毁策略;合规要求保留五年的,到期才能销毁;销毁要可审计、可验证,不能删完才发现还要用。生命周期表(数据类别、留存期限、归档目标、销毁时间)是治理的元数据基础。