ARTICLE DETAIL

资讯详情

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

MySQL 5.7与8.0版本选择及安装配置避坑手册

MySQL 5.7与8.0版本选择及安装配置避坑手册 MySQL版本选择看起来是个老生常谈但我在技术群里几乎每周都能看到有人在问到底装5.7还是8.0装了8.0之后Navicat为什么连不上登录时为什么报SSL相关错误这些问题的根子往往在动手安装之前就已经埋下了——版本没选对或者根本没理解自己到底需要哪个版本。这篇内容我就把从版本选择、下载安装到初始化配置的全过程掰开揉碎讲一遍尽量让你装完之后不出幺蛾子也少走我以前走过的弯路。1. 版本选择5.7 与 8.0 的真实差距不是差一个数字1.1 一张对照表看懂5.7与8.0的差异很多人以为MySQL版本选择就是“挑个新的装及时完事”但5.7和8.0的差别远不止大版本号不同。8.0在底层重构了数据字典、优化器、权限系统并且把默认字符集改成了utf8mb4认证方式也换成了新的caching_sha2_password。这些改动直接影响你后面怎么写SQL、用什么客户端、怎么维护数据库。我把最关键的差异列成一张表你可以直接在选型时对照用对比项MySQL 5.7MySQL 8.0默认字符集latin1需手动配置utf8mb4utf8mb4开箱即用默认认证插件mysql_native_passwordcaching_sha2_password数据字典依赖.frm、.MYD等物理文件InnoDB统一管理数据字典窗口函数不支持支持公用表表达式CTE不支持支持优化器能力相对传统新增多种优化直方图等JSON处理基础函数增加了拆表、聚合等能力在线DDL有限支持更丰富的ALGORITHM支持这张表里最直观的两个影响一个是默认字符集一个是认证插件。5.7装机后如果不在my.cnf里写character-set-serverutf8mb4建出来的库很可能就是latin1导入中文数据立刻乱码。8.0则省心很多默认utf8mb4建库建表不用折腾。认证插件更麻烦8.0默认的caching_sha2_password老版本Navicat、老版本JDBC驱动都不认识连接时会直接报错或卡住。这个后面有专门一章讲怎么处理。1.2 全新项目、存量系统、开发测试三种场景怎么选选版本不是拍脑袋得看场景。如果你是全新项目我强烈建议直接上8.0别再犹豫5.7。理由很实在8.0的功能完整度、性能表现、运维工具链都在持续更新5.7已经进入官方支持末期新项目没必要再踩一个迟早要迁移的版本。特别是你要做复杂报表、需要窗口函数和CTE的时候8.0写SQL会舒服太多。如果是存量系统情况要复杂一些。5.7跑得好好的突然要升级8.0第一步就该做全量SQL兼容性检查。我接手过一个项目5.7里用了很多旧语法比如GROUP BY隐式排序、某些不规范的日期函数在8.0下行为变了结果一堆线上SQL报错。把依赖的客户端、驱动、ORM框架版本列个清单逐个确认是否支持8.0再决定迁移节奏这步省不掉。纯开发测试环境直接容器化。Docker跑一个mysql:8.0实例用完就删比在宿主机上折腾半天快得多。另外提一句5.6和更早版本基本不用考虑了还在跑的都该列入升级计划那些版本的安全性、性能、字符集处理都跟不上现在的业务需求。1.3 我自己的选型判断流程遇到“到底用哪个版本”这种问题我一般按这个顺序走一遍客户端和驱动先过一遍JDBC版本、Navicat版本、PHP解释器版本有没有历史包袱。业务SQL清点有没有用到窗口函数、CTE这类8.0才有的能力有没有依赖旧排序规则的查询。运维能力评估团队对8.0的自适应哈希索引、redo log调优熟不熟新版本的参数体系变化大不大。周边生态确认数据库连接池、监控工具、备份工具是否兼容8.0。如果第1项里出现“很老的Navicat”“很老的JDBC驱动”这种词那你选8.0等于给自己挖坑要么升级工具要么先用5.7顶一阵。其他情况8.0就是正确答案。我个人倾向是版本越新坑越少前提是你的工具跟上来了。2. Windows平台安装Installer和ZIP解压版都实测过2.1 MySQL Installer安装流程详解Windows下安装MySQL最稳妥的路子是走官方MySQL Installer。百度搜“mysql下载官网”进到MySQL官网的Downloads页面找到“MySQL Installer for Windows”。这里有两个选项web版是只下载一个小的引导程序安装过程中按需联网拉组件full版是完整安装包体积大但离线可用。对普通开发机来说web版就够了省流量也省磁盘。运行Installer之后会让你选Setup Type。我建议选Server Only别碰Developer Default。Developer Default会附带MySQL Workbench、Connectors、Visual Studio插件等一堆东西真正用到的没几个还容易在后续组件更新时引入不兼容。安装过程中要设置端口、root密码、认证方式还有一个关键选择Windows Service名称和是否开机自启。开发机勾上“开机自动启动”倒是方便但如果你的机器上还要跑多个数据库实例建议手动控制服务免得端口冲突。还有一个细节Installer在配置实例时会问是否“Config Type”开发环境选“Development Machine”会默认分配较小的内存占用避免所有内存都被InnoDB缓存吃掉。如果你内存只有8G选这个比选“Server Machine”更舒服。装完以后在Services面板里可以看到名为MySQL80的服务默认状态是正在运行。2.2 ZIP免安装版三个坑提前告诉你如果你不想用Installer或者Installer老是崩可以下载ZIP解压版。MySQL官方同样提供portable的ZIP压缩包解压即用适合做成绿色环境。不过这种装法有三个坑我挨个说清楚。第一个坑是初始化。ZIP版没有安装向导必须在根目录自己创建一个my.ini文件不能跳过。我提供的模板如下[mysqld] basedirC:/mysql-8.0.44 datadirC:/mysql-8.0.44/data port3306 character-set-serverutf8mb4 collation-serverutf8mb4_0900_ai_ci [client] default-character-setutf8mb4注意my.ini千万别保存成UTF-8带BOM格式Windows下用记事本另存为ANSI编码更稳。BOM会导致配置解析异常MySQL启动直接报错这问题当年卡了我半天。第二个坑是初始化命令。必须以管理员身份打开cmd进入bin目录执行mysqld --defaults-fileC:/mysql-8.0.44/my.ini --initialize-insecure--initialize-insecure会生成一个无密码的root账号适合本地开发后面自己再改密码。如果你用--initialize会生成一串随机临时密码写在err日志里新手往往找不到这串密码登录时反复失败。用--initialize-insecure省心。第三个坑是注册Windows服务。初始化之后还要执行mysqld --install MySQL8 --defaults-fileC:/mysql-8.0.44/my.ini net start MySQL8如果提示服务已存在先执行mysqld --remove MySQL8再重新注册。服务注册成功后再开机自启就交给Windows了不用手工去services.msc里配。2.3 安装后立刻要做的四项检查装完MySQL别急着写业务代码先花几分钟做四件小事。第一件事验证服务运行状态。打开命令提示符执行net start找到MySQL服务确认是“已启动”。如果启动失败立刻去data目录找.err结尾的日志文件所有启动报错的原因都写在那里比猜强一百倍。第二件事测试命令行登录。执行mysql -uroot -p能进就说明服务端和客户端都正常。如果报Access denied多半是密码没设对重新执行ALTER USER rootlocalhost IDENTIFIED BY 新密码;。第三件事查端口监听。执行netstat -ano | findstr 3306确保3306端口确实被mysqld监听。如果端口被其他程序占用要么改MySQL端口要么先杀掉占用进程。第四件事回头看防火墙。Windows Defender有时会把3306堵死开发机如果要多机访问记得在“高级安全Windows防火墙”里放行3306端口。本机单机玩这步可以跳过但如果后面连不上第一个怀疑对象就是防火墙。还有人会遇到Installer阶段报0xe0434352错误这个错误码多半是Visual C Redistributable或.NET Framework组件缺失导致的。去装一下对应版本的VC运行库再把Installer重跑一遍基本能解决。3. Linux的三种安装方式yum、apt、离线RPM3.1 CentOS/RHEL用yum在线安装Linux服务器装MySQLCentOS/RHEL系最常见的是用yum仓库。先添加MySQL官方仓库rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm如果你要装5.7就把仓库包换成mysql57-community-release对应的版本。装完仓库后导入签名信息否则yum会报GPG key校验失败rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023然后直接安装yum install -y mysql-community-server systemctl start mysqld systemctl enable mysqldMySQL 8.0首次启动后会在/var/log/mysqld.log里生成临时root密码执行grep temporary password /var/log/mysqld.log拿到临时密码后登录并立刻设置新密码。常见的新手卡点是GPG key没导入、yum源里缓存了旧数据导致下载失败遇到就执行yum clean all再重试。3.2 内网离线环境RPM包和通用tar包内网环境没有外网这是运维最头疼的安装场景。解决办法是找一台能联网的机器去MySQL官方下载站点手动下载对应的RPM包然后传到内网服务器。以MySQL 8.0.44为例通常需要的包有这几个mysql-community-commonmysql-community-client-pluginsmysql-community-libsmysql-community-clientmysql-community-server把打包下载后传到目标机器同一个目录里执行rpm -ivh mysql-community-*.rpm如果遇到依赖错误比如缺libaio、libncurses先yum install -y libaio*补齐再装。RPM方式安装完数据目录会在/var/lib/mysql服务启动方式与yum安装一致临时密码同样在/var/log/mysqld.log里。另一种离线方案是下载Linux通用二进制tar包。下载时选“Linux - Generic”的glibc版本解压到指定目录手动创建mysql用户、分配目录权限然后执行初始化useradd mysql tar -xf mysql-8.0.44-linux-glibc2.12-x86_64.tar.xz -C /usr/local mv /usr/local/mysql-8.0.44-linux-glibc2.12-x86_64 /usr/local/mysql mkdir -p /var/lib/mysql chown -R mysql:mysql /usr/local/mysql /var/lib/mysql cd /usr/local/mysql mysqld --initialize --usermysqltar包方式灵活可以装到非标准路径特别适合定制化程度高的环境。缺点是systemd维护要自己写路径配置稍复杂。我建议优先用RPM而tar包留给特殊需求。3.3 Ubuntu/Debian下的apt安装Ubuntu下最简单的是直接用apt装发行版自带的MySQLapt update apt install -y mysql-server systemctl status mysqlUbuntu 22.04默认带的是MySQL 8.0安装过程会初始化好数据目录和服务root用户默认通过auth_socket插件认证本地执行sudo mysql就能以root身份进库。如果后续想用密码登录需要手动改认证方式。如果你要装官方最新版添加MySQL apt仓库也方便。去官方下载页面拿deb仓库包装上后apt update再apt install mysql-server。使用apt方式的优势是依赖自动解决升级也方便劣势是版本被Ubuntu仓库限制了不一定能第一时间拿到最新的小版本。不论哪种方式装完Linux版MySQL之后都建议顺手执行一遍安全加固脚本mysql_secure_installation这个脚本会引导你设置root密码、删除匿名用户、禁止root远程登录、删除test库。虽然交互提示看着啰嗦但效果非常值尤其是面对生产服务器时别跳过。4. Docker部署测试环境和隔离环境最省心4.1 镜像tag别直接用latest现在很多人的开发环境都切换到Docker了一个docker run就能起一个MySQL干净又清爽。但镜像tag我有必要特意叮嘱一句不要直接用mysql:latest。latest会跟着官方发布漂移今天拉的是8.0过几个月再拉可能就是8.4甚至9.x行为变化你根本感知不到排查问题时就把自己坑了。测试环境和生产环境镜像tag必须固定比如mysql:8.0.44或者至少mysql:8.0。固定版本的好处是环境可复现。团队里其他人拉同一个tag跑出来的行为完全一致这份确定性对于排查问题有多重要用过的人都懂。4.2 docker run命令参数逐行说清楚一条完整的MySQL容器启动命令像这样docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDroot123 \ -e MYSQL_DATABASEappdb \ -e MYSQL_USERapp \ -e MYSQL_PASSWORDapp123 \ -v /data/mysql-data:/var/lib/mysql \ -v /data/mysql-conf/my.cnf:/etc/mysql/conf.d/my.cnf \ --restartalways \ mysql:8.0参数逐个说。--name mysql8是容器名字-p 3306:3306把宿主机3306端口映射到容器内3306-e MYSQL_ROOT_PASSWORD是初始化时设置root密码-e MYSQL_DATABASE会自动创建一个空库MYSQL_USER和MYSQL_PASSWORD搭配使用会创建一个相对受限的普通账号-v把数据目录和配置文件挂载到宿主机这是最重要的否则容器删了数据就没了--restartalways让Docker守护进程在容器异常退出时自动拉起适合长驻服务。特别提醒MySQL官方镜像只有第一次启动且数据目录为空时才会根据环境变量初始化用户和密码。如果数据卷里已经存在旧数据你再修改-e MYSQL_ROOT_PASSWORD是没用的root密码仍然是旧库里的密码。这也是很多人容器起不来、密码不对的根源。4.3 docker-compose编排一份可用配置如果服务多了docker run敲起来太累建议用docker-compose。一份最基础的配置长这样version: 3.8 services: mysql: image: mysql:8.0.44 container_name: mysql8 restart: always environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: appdb MYSQL_USER: app MYSQL_PASSWORD: app123 ports: - 3306:3306 volumes: - mysql_data:/var/lib/mysql - ./mysql_conf:/etc/mysql/conf.d command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_0900_ai_ci volumes: mysql_data:在项目目录里执行docker-compose up -dMySQL就起来了。command里的参数会覆盖镜像默认启动参数用于指定字符集和排序规则非常实用。生产环境建议把密码放到环境变量文件里管理别直接写死在yaml里这是我踩过教训才养成的习惯。Docker方式还有一个好处是排查问题特别快。用docker logs mysql8看启动日志用docker exec -it mysql8 mysql -uroot -p进容器连库数据文件也在宿主机上方便备份恢复。我个人的经验是只要条件允许本地开发一律容器化宿主机别装那些乱七八糟的依赖省心太多。5. 装完不是说完了连接、字符集、权限排查5.1 SSL连接错误别慌先确认握手方式很多人在连接MySQL 8.0时报SSL相关错误第一反应是去网上找复杂方案其实大多数情况下没那么严重。MySQL 8.0默认开启了SSL/TLS服务器启动时会自动生成自签名证书。当客户端或驱动不支持SSL或者证书验证不通过时连接就会报错。命令行客户端遇到这个问题可以在连接参数里显式关闭SSLmysql --ssl-modeDISABLED -uroot -pJDBC连接串则可以这样调整jdbc:mysql://localhost:3306/appdb?useSSLfalseallowPublicKeyRetrievaltrueallowPublicKeyRetrievaltrue是应对caching_sha2_password认证时的公钥获取问题老驱动不配这个参数即使本地登录也会报错。生产环境如果安全要求严格不建议整体关闭SSL但本地开发、内网测试关掉SSL能少很多莫名其妙的报错。5.2 Navicat 2059/1251错误认证插件不兼容Navicat连MySQL 8.0时出现2059 - Authentication plugin caching_sha2_password cannot be loaded是最经典的新版本兼容性问题。本质是Navicat版本太老不认MySQL 8.0的新认证方式。解法有两个。一个是升级Navicat到较新版本这个最省事。另一个是动手改MySQL用户认证方式把它降级成老的mysql_native_passwordALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的新密码; FLUSH PRIVILEGES;这里要提示一下mysql_native_password在MySQL 8.0中已经开始标记过时后续8.4等版本不再默认启用。所以这个解法是过渡方案长期来看还是让你的工具跟上新版本更靠谱。修改认证方式后记得用SELECT user, host, plugin FROM mysql.user;确认变更生效。5.3 远程连不上用户host、防火墙一起查MySQL的用户认证是“用户名host”双条件即使账号密码正确host不匹配也登录不了。默认的root只有rootlocalhost远程连的时候必须创建host为%或指定IP的账号CREATE USER ops% IDENTIFIED BY strong_password; GRANT ALL PRIVILEGES ON *.* TO ops%; FLUSH PRIVILEGES;建议犯不着为了省事给root开放所有host创建独立账号更安全。远程连接失败时排查顺序是先ping IP确认网络通再telnet IP 3306确认端口通最后mysql -hIP -P3306 -uops -p确认账号可用三次测下来就知道卡在哪一层。很多新手一上来就怀疑MySQL配置结果最后发现是云服务器安全组没放行这个锅MySQL不背。5.4 字符集和排序规则不一致引起乱码字符集问题是最意外、也最多发的坑。8.0默认utf8mb45.7默认latin1。从5.7导出的数据文件导入8.0如果库表没显式指定字符集就可能出现中文乱码或者“Unknown collation: utf8mb4_0900_ai_ci”的错误。用8.0导入5.7的dump文件时如果dump里写死了utf8mb4_0900_ai_ci导入到5.7就直接报错因为5.7不认识这个排序规则。处理办法是建库时显式指定CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;连接层也要统一字符集命令行登录后执行SET NAMES utf8mb4;JDBC连接串加characterEncodingutf8。这一套配齐基本就不会乱码。还有一个容易被忽略的点同一个字符集下不同排序规则对中文字符的排序结果有差异如果业务里依赖排序结果迁移后要专门做一轮回归测试。5.5 连接池、存储过程、事务迁移的版本影响应用系统用到数据库连接池时版本差异同样不容忽视。MySQL 8.0默认max_connections还是151连接池里的连接如果长期闲置超过wait_timeout默认28800秒会被服务端主动断开客户端拿到的就是失效连接报Communications link failure。解决这类问题除了调大wait_timeout更靠连接池自带的空闲回收检测机制。比如HikariCP就靠minimumIdle和idleTimeout这两个参数配合把空闲连接及时销毁保证池里留的都是活连接。存储过程和事务这块8.0的优势主要体现在开发便利性。窗口函数、CTE让复杂统计SQL变得短一半5.7里要写子查询嵌套才能实现的排名、分区8.0用ROW_NUMBER() OVER (PARTITION BY ...)一次搞定。事务层面双版本的InnoDB都遵循ACID日常开发习惯差异不大但8.0对redo log容量和undo表空间的管理更自动了长事务运行的稳定性更高。这些点都是迁移测试时要重点关注的。5.6 问题排查速查表持续更新版现象可能原因快速处理3306端口连不上防火墙、服务未启动netstat查监听防火墙放行重启服务Access denied密码错误或host不匹配检查root密码确认账号host范围Navicat报2059客户端不支持caching_sha2_password升级客户端或改认证插件SSL连接报错TLS版本或证书验证问题命令行加--ssl-modeDISABLEDToo many connections连接数上限被占满调大max_connections排查连接泄漏初始化后不知道密码用--initialize生成随机密码查看err日志或改用--initialize-insecure服务启动失败配置路径错误、文件权限不符看.err日志检查basedir/datadir导入dump报未知排序规则5.7与8.0排序规则不兼容建库时显式指定collation提示不管是Windows、Linux还是Docker环境MySQL的日志永远是最靠谱的排查入口。Windows在data目录下找.err文件Linux在/var/log/mysqld.logDocker直接docker logs 容器名先看日志再动手大概率能少走弯路。最后聊点我自己的体会很多人一上来就问装哪个其实版本选择不是玄学它是一个基于团队当前工具的兼容性决策。你只要花十分钟对照上面的表把客户端、驱动、SQL语法、运维习惯都过一遍答案基本就出来了。装完之后也别急着用先把字符集、认证方式、远程权限、自动启动这四件事理顺后面能省下好几个通宵。我见过太多项目最后不是挂在数据库本身而是挂在第一天装库时随手留下的那点配置上。
返回列表