◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
不锁表执行SQL语句,每次处理500~1000条,并输出日志记录执行情况的操作方法
摘要:
...
总字数:8820SQL执行语句,不锁表,每次处理100~1000条,并输出日志记录执行情况的操作方法:
一键执行脚本(包含建表、过程、调用)
如何查看执行情况与日志?
这套方案为什么是“最优解”?
极度安全(Idempotent 幂等性): 因为使用了 message LIKE '%旧URL%' 作为前提条件,这个脚本哪怕中途因为网络原因断开,你再次运行它也是安全的,绝不会把新链接又重复替换坏。 业务零感知(Zero Downtime): 行级锁 + DO SLEEP(0.1) 的组合,就像是在高速公路上一点点修补沥青,而不像全表 UPDATE 那样直接把高速公路封死。用户发帖、浏览毫无卡顿感。 高度掌控(Observability): pre_migration_log 表让你对到底改了哪个 ID 段的数据、改了多少条,了如指掌。
第一部分:关于通过后台 PHP 页面执行这个 SQL
如果你的帖子表很大,整个存储过程可能需要跑 5 分钟甚至 30 分钟。 而 PHP 默认的 max_execution_time 通常是 30 秒或 60 秒。Nginx 也有 fastcgi_read_timeout。 时间一到,页面会直接报 502 Bad Gateway 或 504 Gateway Timeout。虽然底层的 MySQL 存储过程可能还在继续跑,但你的前端页面已经断开了,你无法知道执行结果,很容易引起运维恐慌。
页面加载,PHP 查出 MIN(pid)。 PHP 执行一次 UPDATE ... WHERE pid >= 1 AND pid < 1000,然后页面输出一条日志:“已处理 1-1000 条”。 页面通过 JavaScript 或 <meta http-equiv="refresh"> 自动刷新,并将下一批的起始 ID(1000)传给 PHP。 如此循环,直到处理完毕。 (Discuz 官方后台的“数据库升级”和“更新缓存”功能,底层全都是这种 AJAX 分批请求的设计,就是为了绕过 PHP 超时。)
第二部分:文件迁移,用 PHP 还是人工(专用工具)?
单线程且极慢: PHP 默认是单线程的,一张张图片上传到对象存储,几十万个附件能传到地老天荒。 内存溢出(OOM): 读取大文件(如几十MB的压缩包)容易撑爆 PHP 内存(memory_limit)。 网络抖动灾难: 传输过程中一旦发生网络闪断,PHP 脚本中断,你很难知道哪些传成功了,哪些失败了,没有断点续传功能。
阿里云 OSS: 使用 ossutil 工具。 腾讯云 COS: 使用 coscli 或桌面版 COSBrowser。 通用开源神器: Rclone (强烈推荐,支持国内外几乎所有对象存储)。
多线程并发: 可以同时开启 20 个甚至 50 个线程上传,榨干你的服务器带宽,速度是 PHP 的几十倍。 断点续传: 中途断网了、服务器重启了?没关系,重新运行命令,它会自动跳过已上传的文件,接着传剩下的。 MD5 完整性校验: 传完后,工具会自动对比 A服务器和 B对象存储 文件的 MD5 值,确保文件没有损坏或漏传。 增量同步: 命令跑完后,你可以再跑一次,它只会把这两次期间论坛新产生的增量附件传过去。
🏆 资深工程师的终极迁移工作流(Best Practice)
9KKD.com
9KKD.com
这里的内容可以随意更改,在后台-主题配置中设置。
