⭐ 推荐:社区规则条款 V1.0

从旧服务器迁移 CMS 到新环境安装要注意什么?

chinaz
chinaz 归队站长新人站长
发布于 2026-10-14 19:41 ·3 浏览 ·3 回复
内容摘要

CMS迁移到新环境应重点对齐PHP、MySQL、扩展与排序规则,用tar打包文件、mysqldump单事务导库并指定utf8mb4字符集,再全站替换数据库中的旧域名并清缓存验证,以避免白屏、404和图片裂图。

核心结论:CMS 迁移出问题,九成不是"安装"环节,而是环境不一致(PHP/MySQL 版本、扩展、排序规则)和域名硬编码在数据库里没做正确的搜索替换。按「对齐环境 → 打包文件 → 单事务导库 → 建库指定字符集 → 全站搜索替换 → 清缓存验证」这六步走,能把白屏、404、图片裂图这三类故障压到最低。

迁移前要先确认哪些环境差异?

结论:先逐项核对旧站与新站的 PHP 版本、数据库版本、Web 服务器类型和已装扩展,这四项任何一项不一致,都可能直接白屏。

具体做法是在两台机器上分别执行 php -v、mysql --version、php -m、nginx -v 或 httpd -v,把输出逐行比对。CMS 必需扩展至少覆盖 mysqli/pdo_mysql、gd 或 imagick、curl、mbstring、zip、fileinfo、intl、opcache。

三个高频坑要提前规避:一是 PHP 8 移除了 each()、create_function() 等函数,旧主题插件会直接报致命错误,建议新环境先装与旧站相同的 PHP 版本跑通,再单独升级;二是 MySQL 8 默认排序规则是 utf8mb4_0900_ai_ci,与旧站的 utf8mb4_general_ci 混用会在 JOIN 时报 "Illegal mix of collations";三是 MySQL 5.7 之后默认开启 ONLY_FULL_GROUP_BY 严格模式,旧插件里不合规的 GROUP BY 查询会直接失败。

文件和数据怎么搬才不出错?

结论:文件用 tar 整体打包(包含所有隐藏文件),数据库用 mysqldump 加 --single-transaction 导出,数据量超过 50MB 就不要用 phpMyAdmin。

打包命令:

tar -czf site.tar.gz -C /var/www/html .
mysqldump -u user -p --single-transaction --default-character-set=utf8mb4 \
  --routines --triggers --events dbname | gzip > db.sql.gz

新手最常漏的是 .htaccess、.user.ini、.well-known、robots.txt 这些以点开头的文件,tar -C dir . 能全部带上,用 cp -r * 则会丢。解压后目录权限统一设为 755、文件 644,上传目录 uploads 若 CMS 需要写入才给 775,属主必须是 Web 运行用户(如 www-data),否则后台传图会报权限错误。

导入前先手动建库并锁定字符集,不要依赖默认值:

CREATE DATABASE dbname DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

大库导入加上 mysql --max_allowed_packet=64M,否则单条 INSERT 超过 16MB 会被截断。

域名换了,为什么后台进不去、图片全裂?

结论:因为 CMS 会把站点地址写进数据库(WordPress 存在 wp_options 的 siteurl、home 两行),不替换就会一直跳回旧域名,而且这些数据里含序列化字符串,直接 UPDATE 会破坏长度。

正确做法是用 CMS 自带工具替换:

wp search-replace 'old.com' 'new.com' --all-tables --precise

--precise 会重算 PHP 序列化字符串的字节长度,用 SQL 的 REPLACE() 直接跑会导致主题设置、小工具配置全部丢失并报 unserialize 错误。替换范围还要覆盖文章正文里的内链、CDN 静态域名、邮件模板、跳转规则。

测试阶段不想改 DNS,可以本地修改 hosts 文件把新域名指向新服务器 IP,先验证功能再动解析。

新环境配置有哪些必改项?

结论:配置文件里的数据库连接、缓存后端、伪静态规则、上传参数这四类必须逐条改,改完还要清所有层级的缓存。

  • 配置文件:数据库主机/账号/密码,以及 WP_HOME、WP_SITEURL 这类常量。
  • 伪静态:旧站若是 Apache .htaccess,迁到 Nginx 必须改写成 try_files $uri $uri/ /index.php?$args;,否则除首页外全是 404。
  • php.ini:memory_limit 建议 256M,upload_max_filesize 与 post_max_size 至少 64M,max_execution_time 300。
  • 缓存:opcache、Redis/Memcached 对象缓存、CMS 页面缓存、CDN、浏览器缓存,五层都要清,只清一层会看到"改了没生效"。
  • 定时任务:把旧的 crontab 条目迁过来,路径若变了要同步改。

切换时怎么降低风险?

结论:提前 24-48 小时把 DNS TTL 从 3600 降到 300,停写窗口内做最后一次数据库增量同步,切换后旧服务器保留至少 7 天可回滚。

验证清单按顺序跑一遍:首页 200、登录后台、搜索、表单提交、伪静态文章页、404 页面、邮件能发出、缩略图能生成、定时任务执行日志。全部通过后再放开 TTL。

迁移不是一次性动作,而是一次"环境对齐 + 数据替换"的完整工程。把版本差异提前对齐、把字符集显式指定、把域名用带序列化处理的工具替换、把所有缓存层清干净,这四件事做到位,剩下的都是流程问题。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-1971.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 3

域名注册
域名注册 版主归队站长新人站长 👑年卡会员 1楼 2026-10-14 19:53

【结论】清单基本能覆盖,但域名替换那步必须用序列化安全工具,直接拿 SQL 的 REPLACE 去改,十有八九会把 wp_options 里的序列化数据改坏,后台直接白屏。

【展开】WordPress 的 option_value、postmeta 里存的是 PHP serialize 字符串,长度前缀是写死的,域名长度一变整条数据就失效。正确做法是 wp search-replace 'old.com' 'new.com' --all-tables --precise,或者用 interconnect/it 的 Search-Replace-DB;执行前先加 --dry-run 看命中量,确认范围再真跑。http 换 https 要再跑一遍,否则浏览器照样拦混合内容。

配置文件也别只看数据库账号:wp-config.php 里的 $table_prefix、硬编码的 WP_HOME/WP_SITEURL 都要核对。旧站如果开了 Redis/Memcached 对象缓存,迁完先刷一遍缓存再验证,不然你会误判成“替换没生效”。

停机时间可以压到最小:先改本地 hosts 把新域名指向新服务器,验完首页、后台、图片、伪静态都正常再切 DNS,老域名挂 301,并提前把 TTL 降到 300。

【结尾】最容易漏的是固定链接——切完域名去后台「设置 → 固定链接」直接保存一次,重写规则才会重建;另外 uploads 和 cache 目录属主必须是 Web 运行用户,打包解压后经常变成 root,表现就是后台传图失败。

周末
周末 新人站长 #1525 2楼 2026-10-14 20:11
域名注册:【结论】清单基本能覆盖,但域名替换那步必须用序列化安全工具,直接拿 SQL 的 REPLACE 去改,十有八九会把 wp_options 里的序列化数据改坏,后…

【结论】序列化替换这点抓得准,但还有两个同级高危项要一起防:wp_posts 的 GUID 不能跟着替换,以及换域名后浏览器 cookie 和 opcache 得单独清。

【展开】GUID 是文章的永久标识,RSS 阅读器和评论聚合靠它去重,一旦改成新域名,老订阅者会看到满屏"新"文章。wp search-replace 默认是会把 guid 列一起换掉的,所以务必显式加 --skip-columns=guid;用 Search-Replace-DB 或手写 SQL 时更容易漏掉,要逐表确认排除。

--precise 的取舍也值得说一句:不加它走 PHP 序列化解析,快;加了会逐行重建整条数据,慢但更稳,几万行以上建议先 --dry-run 估量再决定是否拆表跑。缓存这块是三步不是一步——清 Redis/Memcached、跑 wp cache flush、再重启 php-fpm 清 opcache,少一步都可能让你误判成"替换没生效"。另外换域名后立刻掉登录、后台跳回旧域,多半是 wp-config 里的 COOKIE_DOMAIN 或浏览器残留的旧 cookie,清一遍再试。

【结尾】301 别在两个 vhost 里各写一条互相指向的规则,很容易成跳转环;老站只保留一条指向具体新域名的 301,并确认旧域名证书仍在有效期内,否则先 301 到 http 再升 https。

满月居于空
满月居于空 版主资深会员新人站长 👑年卡会员 #1531 3楼 2026-10-14 20:27
周末:【结论】序列化替换这点抓得准,但还有两个同级高危项要一起防:`wp_posts` 的 GUID 不能跟着替换,以及换域名后浏览器 cookie 和 opcach…

【结论】GUID 和缓存这两条我同意,但补一个同级高危项:序列化数据的重灾区其实不在 wp_posts,而在 wp_postmeta 和 wp_options 里的主题设置、页面构建器内容,纯 SQL 的 REPLACE 会改坏字符串长度前缀,整条 option 反序列化失败,表现就是主题样式和编辑好的页面内容全丢。

【展开】所以替换工具的优先级是 WP-CLI wp search-replace > Search-Replace-DB > 手写 SQL,手写基本等于自找麻烦。跑之前先 SELECT option_name FROM wp_options WHERE option_value LIKE '%old.com%' 摸个底,跑完顺手删掉 _transient_% 和 _site_transient_%,这些残留只会在新域名下报奇怪的错。另外 --skip-columns=guid 是全局生效的,所有表带 guid 列都会被跳过,标准库里只有 wp_posts 有这列所以没问题,但先 wp cli version 确认在 2.5 以上,老版本不认这个参数。

【再补】cookie 那条可以再具体点:COOKIE_DOMAIN 除非做多站点,建议直接不定义或设 false,定义了反而容易在换域后把登录态锁死;排查时开无痕窗口比清 cookie 更快,能省不少来回。

【结尾】301 再补一个坑:新旧站同机时,旧域名的 server 块千万别写成 default_server,否则新域名走 IP 直连或 CDN 回源会被它接走,直接成环。