跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

php怎么实现自动化数据归档_php如何将历史数据迁移到冷存储

直接用mysqldump导出导入冷库存有锁表、主从延迟、磁盘爆满风险;应优先用SELECT...INTO OUTFILE+LOAD DATA INFILE,限流分批删除,并按查询需求选ARCHIVE或MyISAM引擎。 为什么
mysqldump
直接导出再导入冷库存有风险 直接用
mysqldump
导出全表再导入归档库,看似简单,但容易触发锁表、主从延迟、磁盘爆满三连击。特别是对大表(比如千万级
order_log
),
mysqldump --single-transaction
虽能避免锁表,但会拉长事务时间,拖慢线上写入;而
--skip-lock-tables
又可能导出不一致快照。 优先走
SELECT ... INTO OUTFILE
+
LOAD DATA INFILE
,绕过 MySQL 客户端协议开销,速度更快、内存占用低 务必在从库或低峰期操作,禁止在主库高峰期执行大查询 导出前加
SET SESSION sort_buffer_size = 268435456
(256MB),避免磁盘临时文件拖慢
ORDER BY
或
GROUP BY
导出路径必须是 MySQL 服务端可写的本地路径(如
/var/lib/mysql-files/
),不是 PHP 进程所在机器的路径 PHP 中用
PDO::exec()
分批删除归档数据的正确姿势 归档的核心不是“搬完就完”,而是“搬完立刻删干净”。但一次性
DELETE FROM order_log WHERE create_time 会锁死整张表,甚至触发 InnoDB 死锁或日志写满。必须分批、带索引、带休眠。
WHERE 条件必须命中索引字段(比如
create_time
上有单独索引或联合索引最左前缀),否则
EXPLAIN
显示
type=ALL
就别执行 每次只删 5000 行:
DELETE FROM order_log WHERE id IN (SELECT id FROM (SELECT id FROM order_log WHERE create_time
PHP 循环里用
usleep(100000)
(100ms)让出 CPU,避免打满 IO 和复制线程 删完立刻
$pdo->exec('OPTIMIZE TABLE order_log')
(仅 MyISAM 必须;InnoDB 视情况,大删后建议做) 冷库存储选
MyISAM
还是
ARCHIVE
?看这三点 归档库不是线上库的镜像,它只读、不更新、空间敏感。MySQL 原生
ARCHIVE
引擎压缩率高(通常 90%+)、写入快、无索引开销,但不支持
UPDATE
/
DELETE
、不支持事务、
COUNT(*)
极慢;
MyISAM
支持索引和快速
COUNT
,但压缩率低、崩溃恢复弱。 如果只是按时间范围查(如
SELECT * FROM archive_order WHERE create_date BETWEEN ? AND ?
),且字段少、量极大(>1亿行),选
ARCHIVE
如果要高频查某个 ID 或需要
GROUP BY
统计,且能接受 2~3 倍存储空间,选
MyISAM
并建好复合索引(如
(user_id, create_date)
) 切忌在
ARCHIVE
表上建任何索引——引擎根本不认,建了也无效 迁移后执行
ANALYZE TABLE archive_order
,让优化器更新统计信息,避免执行计划误判
LOAD DATA INFILE
报错
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option
这是 MySQL 5.7+ 默认开启的安全限制,
--secure-file-priv
指定了唯一允许
LOAD DATA INFILE
读取的目录。PHP 里调用失败,不是权限问题,是路径没对上。 PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载 立即学习 “ PHP免费学习笔记(深入) ”; 先查实际路径:
SHOW VARIABLES LIKE 'secure_file_priv';
,结果通常是
/var/lib/mysql-files/
或
NULL
导出时必须用这个路径:
SELECT ... INTO OUTFILE '/var/lib/mysql-files/archive_2022.csv' ...
如果值为
NULL
,说明禁用该功能,需改配置文件
my.cnf
加
secure_file_priv = "/tmp/"
并重启 MySQL PHP 不要尝试用
fopen()
读取 CSV 再逐行
INSERT
—— 效率差 10 倍以上,且网络传输易中断 归档逻辑本身不难,难的是每一步都得卡在线上负载、存储结构、MySQL 配置的边界上。一个
LOAD DATA INFILE
路径写错,或者删数据没限行,半夜告警就来了。

相关文章