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