我干了差不多十年的 MySQL 运维和开发,Windows 10 环境下从 MySQL 5.5 一路升到 5.7 的活接过不少,中间踩过的坑、填过的雷,够写一本小册子了。今天这篇不聊虚的,就把 Windows 10 平台上的完整升级路径拆开揉碎,从备份到落地、从配置到验证,全部端上来。这套流程不只适用 5.5 升 5.7,你把思路顺下来,后续版本跨度更大的升级也能照猫画虎。
先给个预判:在 Windows 上做 MySQL 大版本升级,最核心的两个字是"稳"和"备份"。很多人一上来就装新版本、覆盖老数据目录,结果服务起不来或者数据乱套,这种悲剧我见得太多了。所以这篇指南会一直强调先备份、再动手,宁可多花半小时,也别拿生产数据开玩笑。适合谁看?Windows 环境下的开发者、小型团队 DBA、以及被老项目绑住手脚的运维同学。如果你是刚入门 MySQL,这篇文章也能帮你把"升级数据库"这件事的完整闭环搞清楚。
1. 内容整体设计与思路拆解
1.1 为什么偏偏是 5.5 升 5.7,而不是直接上 8.0
很多人问过我这个问题:2010 年发布的 MySQL 5.5,直接跳到我 2025 年还在维护的 5.7,中间还有 5.6,为什么非要卡在 5.7?原因很现实,也很技术。
MySQL 5.7 是一个口碑极好的"长稳版本",它把 5.5、5.6 时代很多粗糙的地方打磨掉了:默认开启sql_mode严格校验、内置 JSON 类型、性能大幅提升的 InnoDB 缓冲池、以及更安全的密码认证策略。与此同时,5.7 的 SQL 语法和配置习惯,又跟老项目里 5.5 的写法保持了相当程度的兼容度。相比之下,MySQL 8.0 的变化就激进太多了,caching_sha2_password默认认证、用户表结构重构、窗口函数等新特性,对于还在跑老业务逻辑的系统来说,改动成本是几何级上升的。
所以 5.5 升 5.7,本质上是"用最小的业务改动,换取性能和安全性上的明显进步"。对 Windows 10 用户来说尤其如此,这套环境通常承载的是中小型业务、本地开发或内部系统,没必要直接承受 8.0 那种大版本跳跃带来的兼容性风险。5.7 是那个"够用、稳、不折腾"的中间点。
1.2 升级路径设计:原地升级与迁移升级怎么取舍
升级 MySQL 大版本,业内就两条路:原地升级(in-place upgrade)和逻辑迁移(logical migration)。这两者的差别,我拿搬家来打比方。
原地升级像"连家具带墙一起翻新"——你保留旧的数据文件目录,安装新版本程序,然后启动新版本让 MySQL 自己跑升级脚本。好处是迁移速度快、数据结构原样保留;坏处是一旦中途出错,旧版本可能已经被动过了,回退非常麻烦。
逻辑迁移像"把东西打包搬去新家"——用mysqldump把数据导出成 SQL 文件,在新的 MySQL 5.7 实例上重新导入。好处是干净、可控、随时能回退;坏处是数据量大了之后导出导入耗时较长。
我在 Windows 10 场景下,绝大多数情况推荐逻辑迁移,理由很简单:Windows 上的 MySQL 大多是中小数据量,几百 MB 到几 GB 的库,mysqldump完全扛得住。而且逻辑迁移能顺手把字符集、存储引擎、表结构这些历史包袱"洗"一遍,升级效果更彻底。如果你手头确实有几十 GB 以上的大库、停机窗口又短,那再考虑原地升级,但必须有完整文件备份兜底。这条思路在后面的实操章节会一直贯穿。
2. 升级前的准备工作:把老底子摸清楚
2.1 现有环境盘点:版本信息、实例配置、服务形态
动手之前,先给自己的 MySQL 做个全面体检。Windows 10 系统上的 MySQL 5.5 安装形态千奇百怪,有官方 MSI 装的,有免安装 zip 解压版,还有集成环境(比如 phpStudy、小皮面板)里自带的。不同形态,后续处理方式差异很大。
第一步,登录数据库看版本和基础信息,这个操作很简单但你得真的去看一眼:
SELECT VERSION(); SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%'; SHOW VARIABLES LIKE 'innodb_buffer_pool_size';第二步,确认你的服务是怎么跑的。在 Windows 命令行下执行:
sc query mysql wmic service where "name='mysql'" get name,pathname,state,startmode这里我特别强调一下pathname,它能直接告诉你 MySQL 的可执行文件在哪个目录、是不是解压版、配置文件用的是哪个my.ini。很多 Windows 老机器的 MySQL 服务名不叫mysql,可能叫MySQL55甚至自定义的名字,用wmic可以一网打尽。
第三步,记录当前所有数据库列表、各库的大致体积、有哪些关键表。这些信息在升级后做对比验证时非常关键。我通常会把information_schema.TABLES查出来的数据存成一个快照文件,升级完再跑一遍,两个结果 diff 一下,比手动抽查省心得多。
2.2 备份策略:mysqldump 的正确打开方式
备份是升级里最不能省的一环。我见过不止一次,有人拍着胸脯说"数据不重要",结果升级完才发现里面有半年的订单记录,欲哭无泪。所以备份永远要做,而且要验证备份文件是真的能用的。
Windows 10 下用mysqldump的时候,有几个参数必须用对:
mysqldump -uroot -p --single-transaction --routines --events --triggers --databases dbname > D:\backup\dbname_before_upgrade.sql参数拆解一下:--single-transaction是 InnoDB 表的一致性快照导出,不加这个参数的话,导出过程中如果有写入,备份出来的数据可能是不一致的;--routines和--triggers是存储过程、函数和触发器,很多人忘加这两个参数,结果升级完发现存储过程全没了,这种事故在论坛上一搜一大把。
如果你要备份整个实例的所有库,直接这样:
mysqldump -uroot -p --single-transaction --routines --events --triggers --all-databases > D:\backup\all_before_upgrade.sql注意,MySQL 5.5 默认存储引擎是 InnoDB,但可能还有 MyISAM 表。--single-transaction对 InnoDB 有效,MyISAM 表不受这个参数保护。如果你的库里混着 MyISAM 表且数据还在被写入,稳妥起见,备份期间最好停掉写入业务,或者直接用--lock-tables兜底。
备份完成后的黄金法则是:必须验证备份文件可用性。至少做一次 grep 检查文件末尾有没有-- Dump completed结束标记,最好再挑一个核心库,在临时表里导入验证一下。我自己的习惯是备份完顺手查一下文件大小,如果前一周是 800MB,这次备份只有 300MB,那肯定哪里出问题了。
2.3 版本差异梳理:5.5 和 5.7 之间的"隐性断崖"
先声明:MySQL 5.5 到 5.7 的升级,官方文档里写着是"不支持直接跳过版本的原地升级",意思是 in-place upgrade 必须 5.5 → 5.6 → 5.7 逐级升。这也是我倾向逻辑迁移的第二个核心原因:逻辑迁移完全没有这个限制,导出的是逻辑数据,导入到 5.7 就行,中间的物理格式差异由 SQL 层消化掉了。
除了升级方式,5.5 和 5.7 的差异点主要集中在三块:
第一,系统表结构变了。5.5 的mysql.user表没有plugin字段相关的完整认证体系,5.7 对用户密码哈希、认证插件管理做了重构。逻辑迁移时,mysqldump导出的mysql库系统表数据不能直接照搬,所以我在实操时通常只导出业务库,然后在 5.7 上手工重建用户和权限。这也是为什么方案里我要专门留一节处理账号权限。
第二,默认字符集。5.5 时代很多库是latin1或utf8,5.7 默认已经是utf8mb4。这里有个经典误区:utf8在 MySQL 里其实只能存 3 字节的字符,遇到 emoji 等 4 字节字符就会报错。升级到 5.7 后建议尽快把字符集切到utf8mb4,彻底解决表情符号和生僻字的存储问题。
第三,SQL 模式。5.7 默认开启了STRICT_TRANS_TABLES,意味着插入超长字符串、无效日期时会直接报错,而不是像 5.5 那样静默截断或存个 '0000-00-00'。这个变化是升级后最容易让旧系统"崩"的点,后续章节我会给具体的排查和规避方案。
这三条理解了,你对这次升级的技术路线就有了底。剩下的事情是按部就班地做。
3. 核心实操:从 5.5 到 5.7 的完整落地
3.1 方案A:双实例逻辑迁移(强烈推荐)
这套方案的核心思路是:老 MySQL 5.5 继续运行,新 MySQL 5.7 并行安装,把备份数据导入新实例,测试通过后切换端口或服务。全程老库不受影响,随时能回退。我第一次在 Windows 10 上做这套流程的时候,心里就一个字:稳。
具体的操作顺序是这样的:
第一步,还是备份,沿用 2.2 节的全库导出命令,但注意--all-databases里会包含mysql系统库,这个后面要小心处理。我更推荐业务库逐个导出,或者用--databases指定业务库名字,把系统库留给新实例自己初始化。
第二步,下载 MySQL 5.7 安装包。建议用官方 MSI 安装包,因为它在 Windows 上会自动帮你注册服务、初始化数据目录、生成默认的my.ini。下载时注意区分 32 位和 64 位,Windows 10 基本都用 64 位安装包mysql-installer-community-5.7.x.msi。安装过程中选 "Server only" 即可,开发组件那一堆以后需要再说。
第三步,安装时端口冲突问题。老 MySQL 5.5 已经占了 3306,新 5.7 安装时就把端口改成 3307,两个实例共存互不干扰。安装完成之后,先检查新实例能不能正常启动:
net start mysql57 mysql -uroot -p -P3307第四步,创建同名用户和数据库,然后把备份的 SQL 导入:
CREATE DATABASE `yourdb` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;导入命令直接走重定向:
mysql -uroot -p -P3307 yourdb < D:\backup\dbname_before_upgrade.sql这里有个实操细节:如果备份文件里带着CREATE DATABASE语句,那你导命令时就不用指定库名,直接全文件灌进去就行。但如果有多个业务库在同一个备份文件里,导入前务必确认目标实例没有同名的旧库,否则数据会叠加甚至冲突。
第五步,验证数据。手动跑几个核心查询,比对行数、最新一条记录。这个环节别偷懒,一条条对。
第六步,切换。确认新实例没问题之后,停掉老 MySQL 服务、把 5.7 的端口改回 3306、重启服务,然后把业务连接串指向新实例。我用过的切换方案有两种:直接改数据库服务端口,或者在业务配置里改jdbc:mysql://localhost:3307/yourdb。能改配置的情况优先改配置,应急时再动端口。
这套方案的好处值得再强调一遍:整个升级过程老实例一直在跑,新实例是"影子",所有问题都发生在影子身上,原系统零风险。
3.2 方案B:原地升级(适合数据量大、停机窗口短的场景)
虽然我平常用逻辑迁移更多,但原地升级在一些特定场景确实有优势,尤其是那类有几十 GB 数据、停机时间只有一两个小时的业务。原地升级的操作流程在 Windows 10 下大概是这样:
第一步,全量文件备份。逻辑备份之外,直接复制整个数据目录。默认路径一般是C:\ProgramData\MySQL\MySQL Server 5.5\data。复制前务停服务,这一步极其关键,热拷贝文件很容易出现写一半的文件,恢复时会莫名其妙报错。
第二步,卸载旧版本 MySQL 5.5,但注意不要删除数据目录。控制面板里卸载程序,卸载时如果弹出"是否删除数据目录"的选项,必须选否。
第三步,安装 MySQL 5.7,安装向导会让你选择数据目录,这里必须手动指到旧版本留下的那个 data 目录上,让新程序沿用旧数据文件。
第四步,启动服务。此时 MySQL 5.7 检测到旧版本的数据格式,会在启动日志里记录一个升级过程,你会在错误日志里看到类似"Upgrading MySQL Server"的字样。等待启动完成后,登进去手动跑一下:
mysql_upgrade -uroot -pmysql_upgrade是原地升级必不可少的一步,它会检查所有表、更新系统表结构、把旧格式的表升级到新版本兼容的状态。5.7 版本跑完之后,MySQL 会要求你重启一次服务,必须照做。
原地升级的最大风险点在于:如果 5.7 启动时升级到一半失败,你的数据目录已经被动过了,这时候只能用第一步的全量文件备份回滚。所以这个方法对备份的依赖比方案A高得多,踩坑概率也更大。
3.3 安装细节:MSI 安装器与免安装版的差异
Windows 10 下装 MySQL 5.7,MSI 安装器和 zip 免安装版的坑各有各的"精彩"。MSI 版方便,但容易踩两个雷:一是安装器要求先装 .NET Framework 和 Visual C++ Redistributable,旧系统没装会直接卡安装界面;二是服务自动注册后,如果你之前手动配置过my.ini,安装器可能会覆盖掉你的自定义配置。
zip 免安装版的使用场景通常是"我就想快速验证一下 5.7"。流程也很简单:解压到指定目录 → 复制一份my-default.ini改名my.ini→ 执行mysqld --initialize-insecure初始化数据目录 → 用mysqld --install注册服务 → 启动。这里注意 5.7 跟 5.5 的关键区别:5.5 初始化数据目录通常不用显式执行,5.7 必须执行--initialize或--initialize-insecure才能生成 data 目录和 root 账号,不初始化直接启动会报错。
这条路径下,我常用的初始化命令是:
mysqld --initialize-insecure --basedir=D:\mysql-5.7.44-winx64 --datadir=D:\mysql-5.7.44-winx64\data--initialize-insecure会生成一个密码为空的 root 账号,适合本地开发环境;如果要用--initialize则会在日志里生成一个随机密码,必须去错误日志里翻出来才能登录。生产环境建议用后者,本地测试怎么方便怎么来。怎么区分?看my.ini里的log-error配置项指向的文件,随机密码就在里面。
3.4 迁移后重建用户与权限
这是我做逻辑迁移时最常被问到的一步:为什么备份文件导完了,应用却连不上数据库?答案基本都是用户没有重建。mysqldump --all-databases导出的mysql库数据,在 5.7 上直接导入是高风险操作,很容易因为系统表结构不兼容导致新实例的用户表损坏。所以正确的做法是:在新实例上手工重建所有业务账号。
第一步,查询旧实例的账号和权限。登录 5.5 后执行:
SELECT user, host, authentication_string FROM mysql.user; SHOW GRANTS FOR 'appuser'@'localhost';把要保留的账号和授权语句记下来。注意 5.5 里密码字段是Password,5.7 里改成了authentication_string,所以这个查询语句本身不能在新旧实例通用,需要我上面写法各跑各的。
第二步,在 5.7 新实例上重建账号并授权:
CREATE USER 'appuser'@'localhost' IDENTIFIED BY '你的密码'; GRANT SELECT, INSERT, UPDATE, DELETE ON yourdb.* TO 'appuser'@'localhost'; FLUSH PRIVILEGES;第三步,测试登录:
mysql -uappuser -p -P3307 yourdb这里我额外提一个细节:如果你在迁移前知道业务连接串里用的是旧密码,而你想保持密码不变,那在新实例CREATE USER时可以指定旧的mysql_native_password哈希。在 5.5 上执行SELECT PASSWORD('你的密码')拿到哈希串,然后在 5.7 上用:
CREATE USER 'appuser'@'localhost' IDENTIFIED WITH mysql_native_password AS '哈希串';这样应用端密码配置就一个字都不用改。不过这种方式比较取巧,如果你的密码本身强度很低,建议趁升级的机会换成强密码,反正业务改配置也是顺手的事。
3.5 my.ini 配置核对:那些"不写就会出事"的参数
升级过程中的配置核对,直接决定了你升级之后跑得顺不顺。我总结了一份 Windows 10 下 MySQL 5.7 的推荐配置清单,你可以对着旧配置逐项比对:
[mysqld] server-id = 1 port = 3306 basedir = D:/mysql-5.7.44-winx64 datadir = D:/mysql-5.7.44-winx64/data character-set-server = utf8mb4 collation-server = utf8mb4_general_ci default-storage-engine = InnoDB sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION max_connections = 200 innodb_buffer_pool_size = 512M log-bin = mysql-bin binlog_format = row skip-name-resolve逐个说下为什么这些参数重要。character-set-server和collation-server是字符集问题的治本之策,你库里已经乱的数据单靠改配置救不回来,但新数据至少不再制造新乱;sql_mode建议先不要做得太严,如果老业务有大量"插入非法日期"的写法,可以先把 5.7 默认的ONLY_FULL_GROUP_BY去掉,给业务一个缓冲期,具体后面章节展开;innodb_buffer_pool_size是性能大头,Windows 8GB 内存的机器给 512MB 起步,16GB 内存可以给 1GB 以上;skip-name-resolve能显著加快连接速度,但代价是远程连接的账号 host 不能写域名,只能写 IP,设之前想清楚你的连接方式。
还要提醒一个 Windows 特有的坑:路径分隔符。my.ini里的basedir、datadir路径,有的版本用正斜杠/稳妥,有的用双反斜杠\\,实测下来正斜杠在 Windows 上从来不出问题。路径里千万不要出现中文和空格,我踩过D:\Program Files\MySQL 5.7这种带空格的坑,日志反复报找不到文件,最后把 MySQL 移到纯英文无空格目录才消停。
另外,log-bin如果你原来没开,升级到 5.7 可以顺势开启。binlog 除了是主从复制的基础,也是数据误删后的后悔药。但要注意,开启 binlog 会额外增加磁盘占用,Windows 上默认不自动清理,所以一定要配置expire_logs_days = 7(5.7 里这个参数还叫这个名字,8.0 改成了binlog_expire_logs_seconds)。不配这个参数,日志文件会一路涨到撑爆磁盘,别问我是怎么知道的。
4. 常见问题与排查技巧实录
4.1 服务启动失败:看日志是唯一的正确姿势
Windows 10 下 MySQL 5.7 服务启动失败,是最常见也最让人抓狂的问题。一次典型的场景是:安装完 5.7,双击服务想启动,提示"本地计算机上的 MySQL 服务启动后停止"。这种提示不解决任何问题,真正的原因全在错误日志里。
找日志的方法:打开my.ini,看log-error配置项指向的文件路径;或者直接去数据目录下找*.err结尾的文件。打开之后,常见的报错和对应原因我列一个速查表:
| 日志关键报错 | 真实原因 | 处理方向 |
|---|---|---|
Unknown storage engine 'InnoDB' | 5.7 安装时 InnoDB 插件没加载或损坏 | 检查my.ini里innodb_buffer_pool_size是否异常,尝试删除 data 目录下的 ib_logfile 再重启 |
Can't open the mysql.plugin table | 系统表损坏或旧版本数据不兼容 | 备份后执行mysql_upgrade,或直接重建实例 |
The server quit without updating PID file | 数据目录权限不对或路径配置错误 | 检查 datadir 路径是否存在、MySQL 服务账号是否有写权限 |
[ERROR] Failed to open the referenced table 'mysql' | 系统库表缺失 | 使用--initialize重新初始化数据目录,彻底重来 |
我要特别提醒的一点是:任何情况下都不要在 Windows 上直接删掉 InnoDB 的.ibd文件来重置表。你可能会在论坛上看到"删除 ibdata1 和 ib_logfile 重建 InnoDB"的说法,这个操作在 MySQL 5.5 时代偶尔有人这么干,但 5.7 下风险极高,很容易把系统表的数据搞坏,基本等于重装实例。我处理启动失败问题的顺序永远是:看日志 → 定位配置问题 → 实在不行回滚备份 → 最后才考虑重建。
4.2 字符集乱码:utf8 与 utf8mb4 的历史遗留
我把字符集单独拎出来,是因为这是 5.5 升 5.7 后最典型的历史遗留问题,几乎每个老库都会遇到。症状是升级后中文正常、但 emoji 变成???,或者导入数据时直接报错。
根因前面说过:MySQL 的utf8最多存 3 字节,BMP 之外的字符(emoji 基本都在这)存不了。5.5 时代即使你写了utf8,也照样存不下这些字符。所以升级到 5.7 后,正确的迁移姿势是:在导出备份之前,先把旧库的字符集统一成能自动转码的状态,然后新建库时直接用utf8mb4。
实操建议分两步走。第一步,检查每个表当前的字符集:
SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA = '你的库名';第二步,如果有多张表还是latin1或utf8,在新库里重建表结构时全部转成utf8mb4。我一般这样处理:备份 SQL 文件导出来后,用编辑器全局替换DEFAULT CHARSET=utf8为DEFAULT CHARSET=utf8mb4,再把文件导入 5.7。注意,如果原表字段还有VARCHAR(255)这种,转utf8mb4后索引长度会变长,InnoDB 的索引最大长度限制可能导致建表失败,需要把超长的索引字段长度调小或加前缀索引。这个细节在 CREATE TABLE 报 1071 错误时最容易遇到。
这里还有个容易忽略的点:客户端连接的字符集也要对齐。5.7 默认的character_set_client可能是utf8mb4,如果你的旧业务连接串里没指定字符集,可能出现"程序里显示正常、数据库里乱码"或者反过来。统一在连接参数里加characterEncoding=utf8mb4(Java 侧)或用SET NAMES utf8mb4做测试,能省掉后续无数麻烦。
4.3 SQL 兼容性异常:严格模式带来的连锁反应
升级后最常见的 SQL 兼容性问题来自sql_mode的变化。5.5 时代宽松得很,日期可以存0000-00-00、字符串超长会被截断、GROUP BY可以随意取非聚合列。5.7 默认的STRICT_TRANS_TABLES把这些路都堵了,业务 SQL 原地报错是家常便饭。
最常见的报错场景,我用一个实际例子说明。一个老系统里有一张订单表,状态字段status允许为空,业务代码里插入时传了空字符串,5.5 下没问题,升级到 5.7 后直接报Data too long for column或Incorrect integer value。遇到这种问题,我的处理策略分两个阶段。
升级后的第一周,属于"过渡期"。这个阶段我会在my.ini里把sql_mode配置成兼容模式,去掉STRICT_TRANS_TABLES和ONLY_FULL_GROUP_BY:
sql_mode = NO_ENGINE_SUBSTITUTION这样做的目的是让业务先跑起来,别因为一次升级把整个系统卡死。但要注意,这只是治标。过渡期里,我会把所有报错过的 SQL 收集起来,逐个让开发改掉。改完之后,在测试环境把sql_mode设回 5.7 默认值,回归验证一遍。最后在正式环境切回严格模式。这套"先兼容、后整改、再严格"的节奏,是我在多次升级项目里总结出来的最平滑路径。
4.4 认证插件与远程登录问题
MySQL 5.7 的认证插件默认是mysql_native_password,对于老业务的客户端来说兼容性没问题。但如果你升级后新建了用户,泄露的端倪往往出现在远程登录上:本地localhost能登,远程 IP 死活连不上。
这里有个特别容易被忽略的细节:Windows 10 上的 MySQL 服务,默认监听端口可能被防火墙挡住。升级完成后,我第一次远程连 5.7 失败,排查半天才发现 Windows 防火墙没有放行 3306 端口。处理方法很简单,以管理员身份在 PowerShell 里执行:
New-NetFirewallRule -DisplayName "MySQL 3306" -Direction Inbound -LocalPort 3306 -Protocol TCP -Action Allow端口放行之后,再确认用户表里的 host 字段。如果你在 5.7 里创建的账号是'appuser'@'localhost',那远程连接自然失败,需要改成'appuser'@'%'或者'appuser'@'192.168.1.%'。这里要注意,MySQL 对用户匹配是精确优先,'localhost'和'%'两条记录会同时存在,如果两条记录的密码不一致,很可能出现"本机能连、远程密码对但连不上"的诡异现象。排查方法很简单,逐条执行:
SELECT user, host, plugin FROM mysql.user WHERE user = 'appuser';还有个小细节,5.5 升级上来后如果应用用的是非常老的客户端连接库(比如 5.1 之前版本的 JDBC 驱动),可能对 5.7 的握手协议支持不好。如果应用连接时直接报Access denied或Communications link failure,先别急着怀疑密码,查一下驱动版本,升级到对应支持 5.7 的版本往往就好了。
5. 升级后的验证与日常维护建议
5.1 数据完整性验证清单
升级完成、服务正常启动,并不能说明大功告成。我每次升级完,都会照着固定清单做一遍验证。这套清单你可以直接复制使用,省得临时想。
第一项,版本与系统状态确认:
SELECT VERSION(); SHOW STATUS LIKE 'Uptime'; SHOW PROCESSLIST;Uptime应该接近你启动服务的时间,如果刚启动就报异常,进程列表里能看到卡住的线程。
第二项,表数量与行数对比。把升级前用information_schema.TABLES导出的快照和升级后跑同样的查询做对比。重点看每个库的表数量是否一致,核心表的最大 id 或行数是否吻合。写个简单的统计查询就能搞定:
SELECT TABLE_SCHEMA, COUNT(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;第三项,抽查关键数据。比如用户表的最新注册时间、订单表的最新订单号、配置表的最后修改时间。挑选的标准是"这些记录如果丢了,业务立刻能发现"。
第四项,存储过程和触发器的完整检查:
SELECT ROUTINE_NAME, ROUTINE_TYPE FROM information_schema.ROUTINES; SHOW TRIGGERS;这一步特别重要,逻辑迁移时很容易因为备份命令漏加--routines而把这些对象丢了,而且丢了不一定立刻报错,往往是某天某个功能突然失效才发现。
第五项,业务冒烟测试。让开发配合跑一遍核心链路:登录、查询、下单、导出报表。比对着数据文件看半天,这一步最能发现问题。我在一次升级里就靠这步发现了一个字符集的隐性 bug:某个导出的 Excel 文件名是中文,升级后乱码,根源就是连接串没加characterEncoding。
5.2 升级后的日常维护建议
升级到 5.7 之后,有几件事建议趁热打铁做掉,别拖到出了事故再补。
第一件是开启或确认慢查询日志。在my.ini里加上:
slow_query_log = 1 slow_query_log_file = D:/mysql-log/slow.log long_query_time = 11 秒以上的查询记下来,然后定期分析。5.7 自带mysqldumpslow工具可以汇总慢日志,Windows 下直接在安装目录的 bin 文件夹里调用即可:
mysqldumpslow -s t slow.log第二件是定期做逻辑备份并验证恢复。我的建议是每周日凌晨跑一次全量mysqldump,每天中午做一次 binlog 增量备份。Windows 计划任务就可以实现,关键是备份文件必须放到独立磁盘或网络位置,别和数据库在同一块盘上——同一块盘上,盘挂了全玩完。
第三件是监控表空间膨胀。InnoDB 表如果频繁删改,ibdata1文件长期只增不减是正常现象,但膨胀到几 GB 就需要关注了。5.7 的innodb_file_per_table默认是开启的,如果你从 5.5 带过来的配置里把它关掉了,建议升级后开启并做一次重建表的整理。这个操作我一般选在业务低峰期执行:
ALTER TABLE your_table ENGINE = InnoDB;执行完会影响一部分磁盘 IO,但能显著回收碎片空间。
5.3 我的实测经验杂谈
写了这么多,最后分享几个我在 Windows 10 平台做 MySQL 升级时从不外传的小习惯。
第一,永远保持"升级窗口"的概念。哪怕是内部系统,我也会选在夜深人静或者周末做切换,给自己留足至少 4 小时的排错时间。人一旦着急,判断力会断崖式下降,升级这种容错率低的操作,必须从容。
第二,my.ini改动要"一次只动一个变量"。我见过同事图省事,一次改了缓冲池大小、又改了日志格式、还调了最大连接数,结果启动失败后根本分不清是哪一项惹的祸。正确的做法是:改一个参数、重启一次、验证正常,再改下一个。慢一些,但永远不会把自己绕晕。
第三,把升级过程写成文档。包括每一步用了什么命令、花了多长时间、遇到什么问题、如何解决的。这份文档既是自己的复盘材料,也是团队里其他人下次升级时的指路地图。我手头最新的一份升级文档,已经沉淀了四次真实升级的踩坑记录,每次新项目都能直接从中找到答案。
我个人的体会是,MySQL 5.5 到 5.7 这次升级,真正的难点从来不是"安装新版软件"这个动作,而是升级前对数据的敬畏、升级中对细节的把控、升级后对结果的验证。你要是把这一整套流程跑通,后面再遇到任何数据库版本升级,都不会慌。最后再送一个小技巧:升级完之后,把旧版本的安装包和数据目录的压缩包留三个月再删,给自己留足后悔药。数据库这行,谨慎永远比激进活得久。