简介:面向 Windows 初学者的 MySQL 8.4.6 安装配置教程项目,以源码包形式承载完整操作指引,适合开发人员、系统管理员以及刚接触数据库的新手,重点解决从官网下载、版本选择、安装配置到命令行连通性验证的全流程困惑。资源共 3 个文件:HTML 教程页面为主体,.inscode 文件用于在线运行环境配置,.gitignore 提供版本控制支持;压缩包整体仅 5KB,体积小巧但流程完整。目前已有 88 人学习下载。内容涵盖官网下载、MSI 安装器基本版与网络版的差异判断、自定义安装、数据存储目录规划、root 密码安全设置、bin 目录环境变量配置和命令行连接测试,并针对版本误选、密码策略不理解、命令无法识别等易错点做了说明。读者可对照页面逐步操作,安装结束后能回看关键环节用于排错,既可作为首次安装向导,也可作为日常配置速查参考。
1. 为什么 MySQL 8.4.6 安装配置一眼看过去全是坑
做 Java 后端或者数据类项目的朋友,应该都经历过类似场景:项目代码里依赖 MySQL,本地开发环境装的是 5.7,CI 服务器上用的是 8.0.x,生产环境一查是 8.4.6 LTS。三个环境的认证插件、密码策略、字符集默认值各不相同,代码一跑就翻车。MySQL 8.4.6 属于 8.4 LTS 通道里的维护版本,修复了一批安全漏洞,也是目前很多公司“既想上新版又不愿意当小白鼠”的折中选择。这篇内容直接围绕“下载哪个包、初始化怎么做、项目连接串怎么配置、遇到 2002 和 1820 之类报错怎么排”展开,尽量让新手机器能装完就连上库,让熟手看到边界参数和玄学现场。
2. 选型与拿包:为什么不是 9.x,也不是 8.0.4x
2.1 8.4 LTS 通道与 8.0 系列的关键差异
MySQL 从 8.4 开始调整了版本节奏,8.4 是 LTS 长期支持版本,之后的 9.x 属于 Innovation 创新版本。作为一线实践者,我的建议很直白:给项目用,优先选 LTS,别追创新版,除非你有专门团队陪跑升级。LTS 意味着安全补丁维护周期更长,第三方中间件和驱动适配得更稳定,这对生产项目来说比“多几个新功能”重要得多。
8.4 和 8.0 系列有个容易踩的细节:默认认证插件是caching_sha2_password,这个从 8.0 后期开始就是默认值,但旧项目里不少人还在用mysql_native_password。8.4 里对 native 密码插件的支持进一步弱化,老驱动(比如 5.1.x 的 JDBC)直连大概率直接拒绝握手。另一个差异是validate_password组件默认生效,初始密码规则偏严,想设一个简单测试密码会报 ERROR 1819。
2.2 从 MySQL 下载官网挑对安装包:tar.gz、zip、还是包管理器
先说结论:Linux 服务器上我一般用官方二进制 tar.gz 包,不用 yum/apt 自带的源。原因不复杂——官方包的 glibc 版本明确、目录可控、清理时直接删目录就行;系统源里的 MySQL 经常被替换成 MariaDB 或者版本滞后,生产环境不想给自己埋雷。Windows 开发机就用官方 zip 绿色版,不跑安装向导,解压即用,方便多版本共存。
下载官网页面上的文件名带linux-glibc2.17或glibc2.28之类的标签,需要先确认服务器系统 glibc 版本,命令是ldd --version。选错 glibc 版本的包,mysqld 初始化时会直接报version GLIBC_2.28 not found,这是新手最常见的翻车点之一。Windows 端文件名一般带winx64.zip,这个一般不分版本,只要别下成 debug 版就行。
校验文件完整性的步骤不能省。官方镜像站给每个包都附了 MD5 或 SHA256 校验值,下载后核对一下再解压,能挡掉不少传输损坏和第三方镜像的狸猫换太子问题。
wget https://dev.mysql.com/get/Downloads/MySQL-8.4/mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz md5sum mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz # 期望输出应该和官网页面上列出的 MD5 完全一致 tar -xvf mysql-8.4.6-linux-glibc2.17-x86_64.tar.xz -C /usr/local/MD5 校验这条命令的逻辑很朴素:对比输出结果与官网给出的值是否一致,不一致就重新下载。这里强调一个习惯——不要用-C /直接解压,先解压到临时目录再移到目标路径,能避免权限错乱。tar.xz 格式比 tar.gz 压缩率高,但解压时间长一点,属于正常现象。
提示:MySQL 下载官网最近把下载页改成 Oracle Web 登录后才能下某些包,但二进制 tar 包和 zip 包通常可以直接 wget,只是路径里需要带具体版本号,建议在浏览器下载页用“复制链接地址”拿到真实 URL。
2.3 三类安装方式对比和适用场景
| 安装方式 | 适用场景 | 优点 | 坑点 |
|---|---|---|---|
| 官方 tar.gz/zip 二进制包 | 生产服务器、开发机多版本共存 | 目录可控、卸载干净、升级明确 | 需手动初始化、手动配 systemd |
| 包管理器(yum/apt/dnf) | 只想快速体验、内部测试 | 依赖自动解决、路径固定 | 版本滞后、可能被替换成 MariaDB |
| Docker 镜像(mysql:8.4.6) | 本地联调、CI 跑测试 | 环境隔离、起停快 | 数据卷权限、认证插件与宿主不一致 |
这里多说一句 Docker 方案。容器里装的 MySQL 8.4.6 和宿主机直装本质上是同一个二进制,但配置文件与数据目录映射容易出问题,尤其是权限:容器内 mysql 用户 uid 是 999,宿主机目录如果属主不是 999,启动直接失败。这个只影响容器场景,不在本文主线上展开,但值得心里有数。
3. 安装与初始化:从空白服务器到 mysql -uroot 能登录
3.1 Linux 二进制包最小安装步骤
有了 tar 包之后,安装顺序就固定了:解压、建系统用户、建数据目录、写 my.cnf、初始化数据目录、启动、设置开机自启。下面这段脚本覆盖了完整流程,先复制执行再逐个解释。
# 1. 移动解压目录并改名 mv /usr/local/mysql-8.4.6-linux-glibc2.17-x86_64 /usr/local/mysql # 2. 创建 mysql 系统用户,用于隔离权限 useradd -r -s /sbin/nologin mysql # 3. 创建数据目录并授权 mkdir -p /data/mysql chown -R mysql:mysql /data/mysql # 4. 初始化数据目录,注意这里会产生临时 root 密码 /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql # 5. 查看初始密码 grep 'temporary password' /data/mysql/error.log初始化这一步是所有新手绕不过去的分水岭。--initialize会生成一个全新的数据目录,里面包括系统库mysql、performance_schema等,同时为 root 生成随机初始密码,写进 error log。如果没有这一步直接启动 mysqld,会报错“数据目录为空,无法启动”。反过来,如果你重复跑两次--initialize,第二次会说数据目录非空——我第一次装 8.0 时就犯过这个错,还以为初始化可以覆盖执行。
--initialize-insecure是另一个变体,生成无密码的 root 账户,仅建议在临时测试环境用。生产环境走标准--initialize,把临时密码从 error.log 里取出来再做首次修改。
初始化完成后,真正启动服务还需要一个启动脚本或 systemd unit 文件。手工mysqld_safe启动只适合验证,服务器重启后不会自动拉起来。我一般直接写一个 systemd 配置,这样systemctl start mysqld和开机自启都解决好。
[Unit] Description=MySQL 8.4.6 Server After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld ExecStartPre=/usr/local/mysql/bin/mysqld --validate-config TimeoutSec=180 [Install] WantedBy=multi-user.targetsocket路径如果不在默认的/tmp/mysql.sock,客户端连接时会报ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock',这个我们后面单独展开。ExecStartPre 里的--validate-config是个容易忽略的好习惯:如果 my.cnf 里有非法参数,unit 拉起时直接失败,不会出现服务假死的状态。
3.2 Windows 上 zip 包安装:不需要安装向导
Windows 开发机上最顺滑的方式是下载 zip 包解压后手动注册 Windows 服务。解压到D:\mysql-8.4.6-winx64这样的目录,然后手动写一个最小 my.ini。
[mysqld] basedir=D:/mysql-8.4.6-winx64 datadir=D:/mysql-8.4.6-winx64/data port=3306 character-set-server=utf8mb4 collation-server=utf8mb4_0900_ai_ci [client] default-character-set=utf8mb4注意 Windows 路径里的斜杠用正斜杠,反斜杠在某些配置解析场景会出问题。datadir 指向解压目录下的 data 文件夹,这个文件夹不需要手动创建,初始化命令会自动生成。
cd D:\mysql-8.4.6-winx64\bin .\mysqld --initialize-insecure --console .\mysqld --install MySQL84 net start MySQL84--initialize-insecure在这里是可以接受的,因为 Windows 开发机通常只需要本地测试,root 空密码登录后马上创建业务账号。如果必须用--initialize,临时密码同样会写进 data 目录下的.err文件里,路径一般在D:\mysql-8.4.6-winx64\data\下,文件名和机器名一致,后缀是.err。
注册 Windows 服务时,MySQL84是自定义服务名,决定你在服务管理器里看到的名字。若之前装过旧版 MySQL,建议服务名区分开,比如 MySQL80 和 MySQL84 共存,互不影响。卸载服务用.\mysqld --remove MySQL84。
3.3 my.cnf 关键参数:哪些该调,哪些别乱动
配置参数这个问题,新手容易陷入“抄作业”的误区。实际上生产环境最值得调的就这么几项:
| 参数 | 建议值 | 说明 |
|---|---|---|
innodb_buffer_pool_size | 物理内存的 60%~70% | InnoDB 缓存池,性能调优最先看它 |
max_connections | 按项目并发定,默认 151 往往不够 | 连接数上限,设太大内存会爆 |
log_bin | 生产环境建议开启 | 数据恢复和主从复制的后悔药 |
character-set-server | utf8mb4 | 避免中文乱码和表情符号写入失败 |
default-authentication-plugin | caching_sha2_password | 8.4 默认值,不要改回 native 除非驱动太旧 |
bind-address | 127.0.0.1 或内网 IP | 默认只监听本机,远程连不上先查这个 |
[mysqld] user = mysql basedir = /usr/local/mysql datadir = /data/mysql port = 3306 socket = /tmp/mysql.sock character-set-server = utf8mb4 collation-server = utf8mb4_0900_ai_ci default-authentication-plugin = caching_sha2_password innodb_buffer_pool_size = 2G log-error = /data/mysql/error.log slow_query_log = 1 slow_query_log_file = /data/mysql/slow.log long_query_time = 2socket路径这里特意写成/tmp/mysql.sock,因为有太多客户端工具默认在这个路径找 socket。如果改到别的目录,每次 mysql 命令都得手动加-S参数,容易翻车。slow_query_log和long_query_time一起开起来,是排查项目慢 SQL 的基础设施,顺手就配置好,别等线上卡了才想起。
innodb_buffer_pool_size是 MySQL 性能调优的第一参数。这台机器如果只有 4G 内存,设 2G 就偏高了,留给 OS 的余量不足会造成 swap 抖动。经验值先取系统内存的 50%,线上观察命中率再微调。
4. 项目侧连库配置:从 root 过度到业务账号
4.1 初始化后的第一件事:登录并修改 root 密码
拿到临时密码后,执行下面的命令进入 MySQL 环境。这一步一定要做的原因有两个:一是临时密码过期策略默认开启,不修改的话操作几次就会被强制下线;二是 root 账号权限实在太大,项目代码绝不能直连 root。
/usr/local/mysql/bin/mysql -uroot -pALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStr0ng!Pass'; FLUSH PRIVILEGES;MySQL 8.4 的默认密码策略是 validate_password 组件生效,要求密码至少包含大写、小写、数字、特殊字符,长度至少 8 位。如果设的密码不够强,会收到ERROR 1819 (HY000): Your password does not satisfy the current policy requirements。开发机想降低规则,可以执行SET GLOBAL validate_password.policy = LOW;再加SET GLOBAL validate_password.length = 6;,但生产服务器不建议这么干。
“临时密码用一次就丢”是我自己的一个习惯。拿到grep输出后立即登录改密,改完把 error.log 里的日志轮转掉,避免临时密码留在磁盘上被其他运维同事看到。这不是强迫症,是安全习惯。
4.2 创建业务账号:不直接用 root 连项目
项目代码连接 MySQL 时,最忌讳直接拿 root 账号。常见做法是给业务单独建账号,权限只给够用的库,这样即使连接串泄露,影响面也可控。
CREATE DATABASE IF NOT EXISTS app_db DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'AppUser!123'; CREATE USER 'app_user'@'%' IDENTIFIED BY 'AppUser!123'; GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'localhost'; GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%'; FLUSH PRIVILEGES;这里的%表示允许任意主机远程连接,如果项目应用和数据库在同一台机器,只保留localhost就够。远程连接授权这一步,是 Navicat/Workbench 连不上的常见原因,排查顺序是:先看账号 host 是否覆盖来源 IP,再看 bind-address,最后查防火墙。
GRANT ALL PRIVILEGES ON app_db.*的含义是只对 app_db 这一个库授予全部权限,*.*则代表所有库——除非你是 DBA 角色,否则不要给业务账号*.*权限。最小化授权在生产上是铁律。
4.3 JDBC 连接串与 Workbench 连接参数
项目代码接入 8.4.6,最容易炸的地方是 JDBC 驱动版本和连接串参数。5.1.x 版本的老驱动直接连 8.4 大概率报Unable to load authentication plugin 'caching_sha2_password',解决路径是升级驱动到 8.0.33 以上,或者 8.4 配套驱动。连接串里的几个参数一并在下面标出来。
jdbc.url=jdbc:mysql://localhost:3306/app_db?useSSL=false\ &allowPublicKeyRetrieval=true\ &serverTimezone=Asia/Shanghai\ &characterEncoding=utf8mb4 jdbc.username=app_user jdbc.password=AppUser!123useSSL=false是关闭 SSL 加密通道,本地开发可以这样省去证书配置;生产环境建议useSSL=true并配证书,安全性高。allowPublicKeyRetrieval=true这个参数很多人忽略,不设的话连接 8.0+ 的 caching_sha2 认证会报Public Key Retrieval is not allowed,尤其是从老版本 MySQL 迁移过来时最容易遇到。serverTimezone是时区参数,不写的话驱动会用 JVM 默认时区,可能导致CST和Asia/Shanghai混乱,时间字段读写相差 13 个小时的诡异现象就是这么来的。
MySQL Workbench 使用教程里,连接配置界面同样有个细节容易被跳过:默认连接方式选 TCP/IP 时,Host 填 localhost 实际走的是 TCP 还是 socket 取决于界面选项。Workbench 连 Linux 服务器上的 MySQL 时,如果服务器端 socket 不在默认路径且 bind-address 限制了监听地址,界面会报 2002 或 10061 错误。解决办法是 Host 填服务器内网 IP,端口填 3306,别填 localhost。
HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/app_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai"); config.setUsername("app_user"); config.setPassword("AppUser!123"); config.setMaximumPoolSize(20); config.setMinimumIdle(5);上面的 HikariCP 配置里maximumPoolSize=20和 MySQL 的max_connections必须对齐。常见问题:应用端配了 200,MySQL 默认最大连接数才 151,一压测直接报Too many connections。连接池大小按应用线程数估算,不是越大越好,HikariCP 官方文档里的经验是core size = 2 * CPU 核数 + 磁盘数,这个可以作为起点。
注意:连接池最大连接数不要超过 MySQL
max_connections的 70%,留出 DBA 手动维护连接和后台任务的余量,否则高峰期一个慢查询就能把连接池打满,业务全部卡死。
5. 避坑排查:5 个让 MySQL 8.4.6 安装配置翻车的典型现场
5.1 ERROR 2002:socket 文件路径不一致
现象:执行mysql -uroot -p报错ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'。
原因:客户端默认去/tmp/mysql.sock找 socket 文件,但服务端启动时把 socket 写到了/var/lib/mysql/mysql.sock,或socket参数被 my.cnf 改了路径。
解决:先确认服务确实在跑,ps -ef | grep mysqld,再用mysql --socket=/var/lib/mysql/mysql.sock -uroot -p登录验证。长期解决是把 my.cnf 里[client]段的 socket 路径与服务端统一,或者用 TCP 方式连接mysql -h127.0.0.1 -P3306 -uroot -p。这里有个隐藏细节:-hlocalhost和-h127.0.0.1对 MySQL 客户端而言语义不同,前者走 socket,后者走 TCP。
5.2 Access denied:root 密码和 host 不匹配
现象:输入正确密码仍然报ERROR 1045 (28000): Access denied for user 'root'@'localhost'。
原因:MySQL 的账号是“用户名 + host”组合判断的。root@localhost和root@127.0.0.1是两个不同的账号。如果初始化时 root 只有 localhost,用-h127.0.0.1连接就走 IPv4 回环,匹配不到账号。
解决:统一用mysql -uroot -p走 socket 登录,或者创建root@127.0.0.1账号。另外一种情况是密码确实忘干净了,这时只能走skip-grant-tables弱恢复流程:
[mysqld] skip-grant-tablessystemctl restart mysqld mysql -uroot ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStr0ng!Pass';重启前记得把skip-grant-tables从配置里删掉,否则 MySQL 会一直处于不校验密码状态,这是一种比门没锁还危险的裸奔状态。这个方案是真正意义上的后悔药,但只允许在单机维护窗口使用,任何暴露在网络的服务器开着 skip-grant-tables 就等于被人直接进家门。
5.3 ERROR 1820 / 1819:密码策略导致初始化失败
现象:登录后执行任意业务 SQL 报ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.,或者设新密码时报 1819 不满足策略。
原因:8.4.6 初始化时默认把 root 的密码设为 expired 状态,首次登录后必须先改密才能操作;validate_password组件的默认策略是 MEDIUM,弱密码直接拒绝。
解决:老老实实先改 root 密码,再创建业务账号。如果测试环境确实需要弱密码,临时策略调整如下:
SET GLOBAL validate_password.policy = LOW; SET GLOBAL validate_password.length = 6;这两个参数是会话级还是全局级要搞清楚:SET GLOBAL只对之后新建的账号生效,已存在的账号密码不会自动放宽。这组参数重启后恢复默认,需要固化到 my.cnf 里得加validate_password.policy=LOW之类的配置项。
5.4 JDBC 连接报 Public Key Retrieval is not allowed
现象:Java 项目启动时连接池报错CachingSha2PasswordPlugin: Public Key Retrieval is not allowed。
原因:MySQL 8 默认的 caching_sha2_password 认证方式在 SSL 未开启时,需要客户端向服务器请求 RSA 公钥来加密传输密码。新版驱动默认不自动获取公钥,防止中间人攻击。
解决:JDBC URL 加上allowPublicKeyRetrieval=true&useSSL=false两个参数。这里要解释一下为什么useSSL=false也救不了:即使关掉 SSL,caching_sha2 仍需要公钥协商,这个参数就是“允许客户端向服务器要公钥”的开关。生产环境建议反过来,开 SSL 并配置证书,这样allowPublicKeyRetrieval就不需要了。
5.5 远程连接超时或拒绝:bind-address、防火墙和 host 授权三连查
现象:用 Navicat/Workbench 从本机连远程服务器 MySQL,报Can't connect to MySQL server on 'x.x.x.x' (10061)或直接超时。
原因:三层阻碍——MySQL 没监听外网地址、系统防火墙拦截了 3306 端口、账号 host 未包含来源 IP。
解决:按顺序排查。先看监听地址:
netstat -tlnp | grep 3306如果只监听127.0.0.1:3306,回 my.cnf 把bind-address改成实际内网 IP 或者0.0.0.0再重启。然后检查防火墙,CentOS 的 firewalld 和 Ubuntu 的 ufw 命令不同,不要记混:
firewall-cmd --permanent --add-port=3306/tcp && firewall-cmd --reload # 或 Ubuntu ufw allow 3306/tcp最后确认账号 host。mysql.user表里业务账号的 host 如果是localhost,远程就是死路一条,改成%或者具体网段。这三层检查完再重新连接,90% 的远程连接问题都能解决。
6. 用 mysqldump 做定时备份:8.4.6 项目上线前最后一道安全网
前面把安装、配置、连接、排查全部理顺之后,项目真正跑起来之前还欠一道工序:备份。MySQL 的崩溃恢复能力再好,也防不住一条DELETE FROM table WHERE id > 0或者DROP TABLE的手滑。我的习惯是任何项目环境,哪怕本地开发机,都要在初始化完成后立刻配置一个全量备份脚本,每天凌晨跑一次,保留最近 7 天,这样出任何问题都有后悔药。
#!/bin/bash BACKUP_DIR=/data/backup/mysql KEEP_DAYS=7 DATE=$(date +%F_%H%M) DB_USER=backup_user DB_PASS='Backup!Pass' mkdir -p ${BACKUP_DIR} /usr/local/mysql/bin/mysqldump \ --single-transaction \ --set-gtid-purged=OFF \ -u${DB_USER} -p${DB_PASS} \ --databases app_db > ${BACKUP_DIR}/app_db_${DATE}.sql find ${BACKUP_DIR} -type f -name '*.sql' -mtime +${KEEP_DAYS} -delete脚本里的backup_user建议单独创建:CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'Backup!Pass';然后给SELECT, SHOW VIEW, TRIGGER权限即可,不需要 SUPER 权限。--single-transaction是 InnoDB 引擎做非锁定备份的关键参数,它通过一致性视图导出数据,不影响在线业务写。--set-gtid-purged=OFF在 8.4 里尤其重要:开启 GTID 的实例如果不加这个参数,导出的 SQL 会包含SET @@GLOBAL.GTID_PURGED语句,恢复到其他实例时直接报错。
恢复流程也有讲究,别急着在生产环境直接导入。先在一台临时实例上建好库再导入,确认数据量对得上再指向新库:
mysql -uroot -p -e "CREATE DATABASE app_db DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci" mysql -uroot -p app_db < /data/backup/mysql/app_db_20240721_0300.sql还原后的数据目录和二进制日志可能与你原来的主从架构不兼容,这点在 8.4 上要格外注意。如果项目后续要做主从复制,备份策略要改成mysqldump --source-data=2或者用xtrabackup级别的一致性快照,单纯 mysqldump 的 SQL 备份只能保底不能支撑高可用切换。
crontab 里加一行0 2 * * * /usr/local/bin/mysql_backup.sh让脚本每天凌晨 2 点执行,然后写个简单的定时任务检查:第二天早上看一眼备份文件大小,低于 100M 的说明库里数据可能有问题或者连接串错了,备份文件直接为空就是认证失败的信号。
这套流程跑顺之后,MySQL 8.4.6 的安装配置算是真正闭环了:装得上、连得上、项目代码跑得通、数据还有得救。我自己这些年迭代出的习惯是——每换一个新版本环境,先把备份脚本写好,再往上堆业务代码。顺序颠倒过一回,恢复数据时看着空空的备份目录,那种无助感这辈子不想来第二次。希望这篇文章能帮你把 8.4.6 的部署之路走顺,少踩几个我当年踩过的坑。
本文还有配套的精品资源,点击获取