ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Windows 同一台机器安装 MySQL 5.7 与 8.0 双版本共存完整指南

Windows 同一台机器安装 MySQL 5.7 与 8.0 双版本共存完整指南 干我们这行Windows 上同时装两个 MySQL 是早晚会遇到的事。老项目跑在 5.7 上新项目用 8.0本地开发和联调都要用总不能为个数据库专门开两台机器或者天天切换配置。我这次踩坑就是因为本地既要跑遗留系统的 MySQL 5.7又要跑新业务的 MySQL 8.0从安装到用 DBeaver 连上前后折腾了大半天问题集中在端口冲突、服务注册失败、驱动下载失败和认证插件不兼容这几类。这篇文章把整个流程和排查记录完整梳理一遍正在折腾多版本共存的人可以直接拿来当操作手册。1. 为什么要在同一台机器上装多个 MySQL1.1 典型场景与需求分析先说说我遇到的实际情况。当时我手上有一条业务链是老的 PHP 系统数据库跑在 MySQL 5.7 上连接配置、存储过程、字符集都是按 5.7 的习惯来的另一边新的 Java 服务用的是 MySQL 8.0开发时要用到窗口函数、新的 JSON 特性、还有默认的 caching_sha2_password 认证方式。两套代码库在本地都要随时能跑起来临时切换版本不但费时间还会把两边的数据环境都搞乱。所以最现实的办法就是在同一台 Windows 机器上让两个 MySQL 实例同时运行各用各的端口各用各的数据目录。这种做法对本地开发来说成本最低也不需要上 Docker 或者虚拟机。Docker 当然也是一个选项但本地开发经常要直连、要导入导出数据、要调试一些系统参数直接在宿主机上装实例反而更符合我这类人的使用习惯。需要明确一点MySQL 多版本共存并不需要什么特殊工具它的核心思路就一句话把端口、服务名、数据目录这三个东西彻底隔离两个 MySQL 就能像两台独立的数据库服务器一样运行。理解了这一点后面所有配置和报错都能对号入座。1.2 多版本共存的三个核心隔离点先说端口。MySQL 默认监听 3306两个实例同时存在必然冲突。常规做法是让用得最频繁的版本占 3306另一个版本换到 3307 或者 3308。端口背后还有一个容易忽略的细节MySQL 8.0 自带的 X Protocol 默认占用 33060如果你装的是两个 8.0 的实例或者某个实例开启了 mysqlxX Protocol 的端口也得单独指定否则照样起不来。第二个隔离点是数据目录。每个版本的 data 目录必须独立初始化实例时生成的系统库、binlog、undo log 都会写在这个目录里。两个实例共用同一个 datadir 会直接导致数据文件损坏这个没有任何商量余地。另外data 目录最好是建在对应版本的安装目录下方比如 C:\tools\mysql-5.7.44-winx64\data这样找问题、备份、清理都很直观。第三个隔离点是 Windows 服务名。mysqld 在 Windows 上以服务方式运行服务名必须唯一。我习惯把 5.7 注册成 MySQL578.0 注册成 MySQL80这样 net start、net stop、sc query 都能精确控制互不干扰。如果沿用默认的 MySQL 服务名安装第二个版本时就会报服务名已存在这是新手最容易卡住的地方。除了这三个核心点还有一个常被忽略的问题环境变量 PATH。两个版本的 bin 目录里都有 mysql.exe、mysqldump.exe、mysqladmin.exe如果把两个 bin 目录都加进 PATH命令行敲 mysql 时到底调用哪个版本完全取决于 PATH 顺序很容易混乱。我的建议是只保留日常用得最多的那个版本的 bin 在 PATH 里另一个版本用全路径调用或者写两个简单的 bat 切换脚本比反复改环境变量省心得多。2. 从零开始MySQL 5.7 与 8.0 同机安装的完整流程2.1 版本选择与安装包准备安装包的选择直接影响后面的工作量。我的建议是全部使用 ZIP 免安装版不要混用 MSI 安装版。ZIP 版解压即用服务注册和数据目录都由自己控制非常适合多版本共存MSI 版虽然图形化界面友好但会在系统里写注册表、自动注册服务两个版本装下来很容易出现服务冲突和卸载残留问题。版本号方面我选的是 MySQL 5.7.44 和 MySQL 8.0.36。5.7.44 是 5.7 系列最后几个维护版本之一对老项目的兼容性最好8.0.36 则属于 8.0 系列里比较稳定的版本特性完整该修的 bug 也修得差不多了。下载时注意区分 32 位和 64 位现在基本都是 64 位系统选 winx64 那个 ZIP 包就行。解压后的目录结构建议统一放在一个父目录下管理。我的布局是这样的C:\tools\ ├── mysql-5.7.44-winx64 └── mysql-8.0.36-winx64目录名里带上版本号时间久了也不会搞混。另外如果安装 5.7 时提示缺少 vcruntime140.dll 之类的运行库先去装一下 Visual C 2015-2022 运行库这类问题通常不是 MySQL 本身的问题而是 Windows 系统缺基础运行环境。2.2 my.ini 配置端口、目录、认证方式一次写对每个版本解压后第一件事就是在它的根目录下创建 my.ini。my.ini 是 MySQL 实例的配置文件basedir、datadir、port、字符集、认证插件都在这里指定。5.7 和 8.0 的配置有差异我直接贴出我验证过的两版配置。5.7 的 my.ini[mysqld] basedirC:/tools/mysql-5.7.44-winx64 datadirC:/tools/mysql-5.7.44-winx64/data port3307 character-set-serverutf8mb4 default-authentication-pluginmysql_native_password skip-name-resolve [client] port3307 default-character-setutf8mb48.0 的 my.ini[mysqld] basedirC:/tools/mysql-8.0.36-winx64 datadirC:/tools/mysql-8.0.36-winx64/data port3306 mysqlx-port33061 character-set-serverutf8mb4 [client] port3306 default-character-setutf8mb4这里有几个关键点值得展开。第一路径分隔符在 ini 里用正斜杠或者双反斜杠都行千万别用单反斜杠否则会被当成转义字符。第二5.7 里我显式写了 default-authentication-pluginmysql_native_password因为后面要用小版本工具和旧驱动连接时mysql_native_password 最省事8.0 默认的 caching_sha2_password 安全性更好但我把它留给 DBeaver 那节单独说本地开发时两个方案都能跑通。第三8.0 的 X Protocol 端口我改成了 33061避开默认的 33060避免和你可能安装的其他组件冲突。[client] 段也很重要。它决定了命令行客户端 mysql -u root -p 默认连哪个端口。如果 [client] 段不写 port命令行就会按默认 3306 去连当你想连 3307 的 5.7 时会出现mysql 连上了 8.0或者连接被拒绝的困惑。每个实例的 my.ini 里把 [client] 的端口和 [mysqld] 保持一致能少踩一半的坑。2.3 初始化、服务注册与环境变量处理配置文件写好之后接下来是初始化数据目录。这一步必须在安装目录下的 bin 目录里执行。以管理员身份打开 CMD先进入 5.7 的 bin 目录执行mysqld --defaults-fileC:/tools/mysql-5.7.44-winx64/my.ini --initialize-insecure--initialize-insecure 的意思是初始化后 root 用户的密码为空本地开发环境用这个最方便省得去日志里找随机密码。如果你用 --initialize不带 insecureMySQL 会生成一个随机密码写进 data 目录下的 .err 日志文件里找起来很麻烦。两个版本都用 --initialize-insecure初始化完成后 data 目录就会被自动创建出来。初始化 8.0 同理只是把 defaults-file 换成 8.0 的 my.ini。初始化过程可能看起来像卡住了一样其实是在生成系统表空间和 redo log一般十几秒到一分钟不等耐心等命令行自己返回就行。初始化完成后注册服务。注意注册服务时--defaults-file 参数要紧跟在服务名后面mysqld --install MySQL57 --defaults-fileC:/tools/mysql-5.7.44-winx64/my.ini mysqld --install MySQL80 --defaults-fileC:/tools/mysql-8.0.36-winx64/my.ini服务注册成功后会提示 Service successfully installed。接下来启动服务net start MySQL57 net start MySQL80服务启动后分别验证一下两个实例的端口监听情况netstat -ano | findstr :3306 netstat -ano | findstr :3307验证登录也很直接mysql -u root -P 3307 -p mysql -u root -P 3306 -p密码是空的直接回车就能进去。这一步一旦通了说明两个实例已经在独立运行多版本共存工作完成了一半。最后处理 PATH我建议在系统环境变量里只保留 8.0 的 bin5.7 的工具用 C:\tools\mysql-5.7.44-winx64\bin\mysql.exe 全路径调用或者干脆给常用的几个命令写个小脚本比改环境变量可控得多。3. DBeaver 连接多版本 MySQL驱动、JDK 与连接参数3.1 DBeaver 版本与 JDK 匹配问题数据库装好了接下来是客户端工具。DBeaver 是我现在的主力 SQL 客户端社区版就够用。先说一个很多人容易忽略的点新版 DBeaver 对 JDK 版本有硬性要求。DBeaver 从 23.x 开始内置运行时需要 Java 17如果你的系统原本只装了 JDK 8或者 JAVA_HOME 指向的是旧版本DBeaver 可能直接启动失败或者启动后很多功能异常。我遇到的情况是电脑上既有 JDK 8 又有 JDK 17但 JAVA_HOME 被某个老项目配置指向了 JDK 8DBeaver 启动时报了一堆类加载错误。解决方式是在 DBeaver 安装目录下编辑 dbeaver.ini在 -vmargs 之前手动指定 JDK 路径-vm C:/Program Files/Java/jdk-17.0.10/bin/javaw.exe -vmargs-vm 参数必须放在 -vmargs 之前路径指向 javaw.exe 而不是 jre 目录改完重启 DBeaver 就正常了。如果不想动配置文件也可以直接把 JAVA_HOME 临时改成 JDK 17 再启动 DBeaver但这样会影响其他依赖 JDK 8 的工具所以我更推荐用 dbeaver.ini 单独指定。3.2 新建连接一个 DBeaver 管理两个实例DBeaver 连接两个 MySQL 实例在界面上就是建两个连接彼此独立。点工具栏的新建连接选 MySQL然后在连接设置里填入对应实例的信息。第一个连接连 8.0主机填 127.0.0.1端口 3306用户名 root密码留空数据库名可以不填等连接成功后在左侧树里选择。第二个连接连 5.7同样填 127.0.0.1端口改成 3307其他一样。为了好区分连接名建议写清楚版本例如MySQL57-local和MySQL80-local比默认的连接名直观得多。这里有个常见问题很多人在数据库/Schema那一栏填了不存在的库名导致连接报Unknown database。我的做法是新建连接时不指定数据库连接成功后 DBeaver 会自动拉取该实例下的所有数据库列表再在需要的库上右键打开 SQL 编辑器这样最不容易出错。如果列表一直不出来右键连接点刷新即可。还有一点要确认连接 5.7 和 8.0 用的 JDBC 驱动尽量统一用 MySQL Connector/J 8.0.x。新版 DBeaver 默认就是 8.x 驱动这个驱动和 5.7、8.0 服务器都兼容。如果你用了很老的 5.1.x 驱动去连 8.0会碰到Unknown system variable transaction_isolation这类错误本质是旧驱动不认识新服务器的系统变量换个新驱动立刻解决。3.3 连接 URL 与驱动属性里的几个坑在 DBeaver 的编辑连接 - 驱动属性里有几个参数直接影响能否稳定连接。最典型的是连接 8.0 时默认加密认证是 caching_sha2_password如果连接走的是非 TLS 通道本地开发一般不会专门配 SSL客户端第一次握手拿不到公钥会直接报Public Key Retrieval is not allowed。解决方式是在驱动属性里加上两个参数allowPublicKeyRetrievaltrue useSSLfalse如果不用驱动属性面板也可以直接在连接 URL里写全。DBeaver 里点编辑连接 - 连接设置 - 编辑 URL手动填入jdbc:mysql://127.0.0.1:3306?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/ShanghaiserverTimezone 是另一个高频坑。MySQL 8.0 的服务端时区如果没显式设置JDBC 驱动读取系统时区时可能报The server time zone value is unrecognized之类的错误。本地开发直接在 URL 里写死 Asia/Shanghai 最省心不用去改服务器全局时区变量。还有个细节值得说如果连接 5.7 的实例时报Authentication plugin caching_sha2_password cannot be loaded那大概率是你把默认驱动换成了老版本或者服务器本身 8.0 里跑着 caching_sha2_password 的旧用户。5.7 默认走 mysql_native_password一般不会有这个问题。真的碰到了就执行下面这条 SQL 把用户认证切回旧插件ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;当然MySQL 8.0 里 mysql_native_password 已经标记为弃用8.4 之后默认禁用9.0 直接移除。如果是较新的 8.0 版本建议优先靠 allowPublicKeyRetrieval 配合新驱动来解决问题而不是改服务器的认证插件。4. 高频连接问题与排查方案速查表4.1 连接阶段最常见的报错把实际操作中收集到的报错整理成一张速查表方便你遇到问题直接对照。这里面的每一条我都亲手踩过或者帮同事排查过不是从文档里抄的。报错信息原因解决办法ERROR 2003: Cant connect to MySQL server on 127.0.0.1 (10061)服务没启动 / 端口不对netstat 查端口确认对应服务名net start 启动服务ERROR 1045: Access denied for user rootlocalhost密码错误 / 用户认证插件不匹配确认密码或按上一节的 ALTER USER 调整认证插件Public Key Retrieval is not allowed8.0 默认认证需要请求公钥驱动属性加 allowPublicKeyRetrievaltrueCommunications link failure端口连错、服务异常、防火墙拦截核对端口和主机名重启服务看 error logThe server time zone value ... is unrecognizedJDBC 驱动拿不到合法时区URL 加 serverTimezoneAsia/ShanghaiAuthentication plugin ... cannot be loaded驱动版本太老 / 认证插件不可用统一用 Connector/J 8.x必要时改用户插件远程计算机拒绝连接非本机连接防火墙未放行开放 3306/3307 端口检查 bind-address这里重点说一下端口相关的排查思路。当你看到 2003 报错时第一件事不是去翻 DBeaver 配置而是确认服务到底起来没有。在 CMD 里跑 netstat -ano | findstr :3307如果输出为空说明 3307 上根本没有进程在监听如果输出有记录再拿 PID 去 tasklist 里确认是不是 mysqld.exe。很多连不上的问题追到最后其实是对应的服务没启动或者初始化失败后服务自动退出了。4.2 驱动下载失败与离线安装驱动另一个非常典型的场景是 DBeaver 首次连接 MySQL 时需要下载 JDBC 驱动但下载过程经常失败。表现是连接弹窗提示Cant create driver instance或者Error downloading driver点开详情会发现卡在某个 Maven 仓库地址上。DBeaver 的驱动是从 Maven Central 等远程仓库拉取的网络不通或者源站响应慢都会导致这个结果。这时候不用干等直接手动安装驱动。先到 Maven Central 搜 mysql-connector-j下载和你 DBeaver 版本匹配的 jar 包比如 mysql-connector-j-8.0.33.jar。然后在 DBeaver 里点数据库 - 驱动管理器 - MySQL - 编辑切到库标签页点添加文件选本地 jar把原来尝试自动下载的那条记录删掉保存后重启 DBeaver 再连接。手动装驱动还有一个附带好处不受 DBeaver 内置驱动版本的限制可以根据服务器版本自由选择 Connector/J 的版本。比如要连老项目里的 MySQL 5.6用 8.0 的驱动也没问题但如果你非要用 5.1.x 的驱动连 8.0 服务器那多半会碰壁。所以我的经验是本地多版本环境统一用最新的 Connector/J 8.x 驱动兼容性最好。4.3 服务端配置导致的连接问题有些连接问题不是 DBeaver 的锅而是服务器端配置的问题。最常见的是 bind-address。MySQL 默认只监听本机回环地址如果你需要通过局域网 IP 连接本机的 MySQL或者要在另一台机器上用 DBeaver 连这台机器上的实例就得在 my.ini 里设置 bind-address0.0.0.0然后重启服务。另一个服务端问题是用户表里的 Host 字段。MySQL 的用户权限是用户名 来源主机绑定的。默认 root 用户只允许 rootlocalhost 登录。如果 DBeaver 填写的主机名解析后不是 localhost就会报 Access denied。保险的做法是在连接配置里统一使用 127.0.0.1并在服务端确认有 root127.0.0.1 或者 rootlocalhost 的授权。实在需要在其他机器上连接就创建新用户并授权CREATE USER dev192.168.% IDENTIFIED BY password; GRANT ALL PRIVILEGES ON *.* TO dev192.168.%; FLUSH PRIVILEGES;这里还有个连带问题Windows 防火墙会拦截外部机器对 3306/3307 端口的访问。如果同事的 DBeaver 连你这台机器连不上先在本机 telnet 一下端口不行就去防火墙入站规则里把对应端口放行这个比反复检查 MySQL 配置更管用。4.3 服务启动失败与初始化异常的排查服务启动失败是个大类问题。MySQL 5.7 初始化失败或无法启动最常见的原因有三个。第一个是 data 目录权限不对mysqld 进程没有写入权限报错信息里通常有Cant create/write to file或者Permission denied。解决方法是用管理员权限执行服务或者给 data 目录加上当前用户的完全控制权限。第二个是 my.ini 里 basedir 或 datadir 路径写错启动瞬间就退出了。第三个是端口被占用mysqld 想监听 3306 但端口已经被其他进程占用日志里会明确写 bind on TCP/IP port: 3306 失败。排查服务启动失败第一眼应该看 data 目录下的 .err 文件文件名类似你的主机名.err。这个文件记录着 mysqld 启动过程中的所有错误信息比任何日志工具都直接。初始化没报错但服务起不来时打开 .err 文件基本前几行就能定位到问题。还有一类问题是服务注册时的残留冲突。如果你之前装过 MSI 版的 MySQL系统里可能已经有名为 MySQL 的服务直接运行 mysqld --install 会提示服务名已存在。处理方式是用管理员 CMD 运行 sc delete MySQL 删除旧服务再重新注册。注意 sc delete 只删服务不删数据目录所以不会影响已有数据但操作前最好还是确认一下这个服务是不是真的不用了。4.4 一些实操心得和避坑细节折腾完这一整套我总结几个实操心得这些是文档里不会细说、但实际工作中特别影响体验的地方。第一个心得是每个实例的 my.ini 一定要亲手写不要偷懒复制别人的模板改两下就完事。路径、端口、字符集、插件配置任何一个和实际目录对不上都会在启动或连接阶段以各种诡异的方式报错。我见过有人把 5.7 的 my.ini 直接复制成 8.0 的连 basedir 都没改结果 8.0 服务起来后数据写到 5.7 的 data 目录里两个实例全崩了。写配置的时候顺带把端口、数据目录、版本号记到自己的笔记里出问题能省很多时间。第二个心得是给两个实例设置不同的 root 密码或者至少用不同的连接名、不同的驱动配置避免 DBeaver 里连接多了以后看起来一样导致误操作。我自己就把两个连接的颜色和名称都做了区分5.7 的连接叫旧系统-5.78.0 的叫新业务-8.0每次开 SQL 编辑器前都看一眼连接标签避免把测试数据写到老库里。第三个心得是命令行工具和 GUI 客户端尽量配合使用。DBeaver 适合跑查询、看执行计划、导数据但像服务启动、端口检查、初始化这类系统级操作用 CMD 和 netstat 更可靠。我见过不少同事在 DBeaver 里点连接测试失败后反复改连接配置其实问题出在服务没起来一个 net start 就解决的事。最后补充一个小技巧本地双实例跑起来之后最好写一个简单的 bat 脚本一键启动两个服务并检查端口状态。脚本内容很简单核心就三条命令net start MySQL57 net start MySQL80 netstat -ano | findstr :3306 netstat -ano | findstr :3307保存成 start-mysql.bat右键管理员运行。这样平时开发不用每次手动敲服务命令也方便确认两个实例都正常监听。多版本共存这种事配置一次到位之后日常使用其实跟单实例没什么区别麻烦全在第一次搭建和第一次连接那几条报错里。把上面这些点都过一遍剩下的就是安心干活了。
返回列表