archive引擎适合存写入后永不更新、几乎不查询的冷数据,如操作日志、审计记录、原始埋点;它仅支持insert和select,无索引、事务、update/delete,且select必全表解压扫描。

Archive引擎适合存什么数据
Archive引擎只适合存「写入后永不更新、几乎不查询」的冷数据,比如操作日志、审计记录、原始埋点。它用 zlib 压缩每行,不支持索引、事务、UPDATE/DELETE(只能 INSERT 和 SELECT),也没有缓存机制。一旦误选场景——比如要按时间范围查最近 7 天日志——性能会断崖式下跌,因为必须全表解压扫描。
- ✅ 正确场景:
INSERT频繁、SELECT极少(如每月导出一次做合规审计) - ❌ 错误场景:需要
WHERE time > '2024-01-01'或ORDER BY id DESC的实时查询 - ⚠️ 注意:
SELECT COUNT(*)会触发全表解压,比 MyISAM 慢几十倍
建表时必须显式指定 ENGINE=ARCHIVE
MySQL 不会自动把表转成 Archive,哪怕你只插数据不查;不声明引擎,默认是 InnoDB。Archive 表无法通过 ALTER TABLE ... ENGINE=ARCHIVE 在线转换,必须重建——而重建过程中原表不可写,且压缩过程极耗 CPU。
- 建表语句必须带:
ENGINE=ARCHIVE,例如:CREATE TABLE logs_archive ( id BIGINT NOT NULL AUTO_INCREMENT, msg TEXT, created_at DATETIME, PRIMARY KEY (id) ) ENGINE=ARCHIVE;
-
ALTER TABLE logs ENGINE=ARCHIVE会失败并报错:ERROR 1031 (HY000): Table storage engine for 'logs' doesn't have this option(除非原表本身是 MyISAM 或 CSV) - 想迁移现有日志?先
CREATE TABLE ... ENGINE=ARCHIVE,再INSERT INTO ... SELECT,最后删旧表
Archive 表的 SELECT 性能陷阱
Archive 没有索引,所有 SELECT 都是全表扫描+实时解压。哪怕只查一行,也要把整个 .ARZ 文件从磁盘读入、逐行解压、过滤匹配——这意味着数据量越大,单次查询延迟越不可控。
- 不能加
INDEX,也不能用FORCE INDEX,语法直接报错:ERROR 1031 (HY000) - 如果必须按时间查,得靠应用层分表:按月建
logs_202401、logs_202402等,每张都是ENGINE=ARCHIVE -
SELECT * FROM t LIMIT 10不代表只解压前 10 行——它会解压全部,再取前 10 条结果
归档后怎么安全清理老数据
Archive 表不支持 DELETE,也没分区裁剪能力。想删 2022 年前的数据?唯一安全做法是「建新表 → 导入保留数据 → 替换原表」,但这个过程锁表时间长,且中间无回滚。
- 不要用
TRUNCATE TABLE清空——虽然快,但会丢掉所有数据,且不可逆 - 若需定期清理,建议在归档前就按时间切片:每天或每月生成独立 Archive 表,过期直接
DROP TABLE -
OPTIMIZE TABLE对 Archive 无效,执行后返回note: Table does not support optimize, doing recreate + analyze instead,实际只是重建,不压缩更紧
Archive 最容易被忽略的一点:它不写 binlog(除非显式开启 binlog_row_image=FULL 且使用 ROW 格式),主从同步时如果从库没启用对应参数,归档表数据可能丢失。不是所有 DBA 都记得检查这点。










