mysql8.0.x大表归档到历史表
一、归档操作的目标
把主表(业务表)中 历史数据(如 3 个月前的数据)迁移到一个 历史表(history 表)中,以:
- 降低主表体积、提升查询性能
- 避免数据删除带来的锁表或性能问题
- 保留历史数据以供审计或分析
二、基本思路
一般流程如下:

三、操作步骤
假设:
- 主表:
orders - 历史表:
orders_history - 按字段
create_time归档,保留最近 90 天数据
3.1创建历史表(结构完全一致)
1 | CREATE TABLE IF NOT EXISTS orders_history LIKE orders; |
如果是分区表或带触发器、索引的表,请确认归档表结构保持一致,但可以 删除不必要索引 提高写入效率。
3.2插入归档数据
例如归档 3 个月前的数据:
1 | INSERT INTO orders_history |
建议一次归档一个时间段(如一周或一个月),避免大事务。
3.3删除主表中的已归档数据
1 | DELETE FROM orders |
大表注意:
- 不要一次性删除太多行,会锁表。
- 建议 分批删除,每次 1 万或 10 万行。
1 | -- 分批删除版本 |
然后循环执行直到删除完毕。
3.4优化表空间
清理完后压缩表空间:
1 | OPTIMIZE TABLE orders; |
四、自动化实现方式
方式一:存储过程 + 定时事件(MySQL Event)
1 | DELIMITER // |
前提:
event_scheduler=ON
方式二:外部脚本(Python/Golang/Shell)
这种适合运维自动化任务,比如定时归档 + 日志记录。
例:Shell 简版
1 |
|
五、针对大表的优化策略
| 问题 | 推荐方案 |
|---|---|
| 删除慢、锁表 | 使用 pt-archiver 工具(Percona 工具包) |
| 写入归档慢 | 临时关闭归档表索引再重建索引 |
| 主从复制延迟 | 归档在从库执行 |
| 死锁风险 | 按主键范围批量处理,如 WHERE id BETWEEN x AND y |