如果你搜到这篇《MySQL 8.0 完整安装与配置教程纯文字版》大概率是和我一样手头有台服务器要么想搭一套数据库环境要么正被 Zabbix、PHP 项目之类的事情卡住必须先搞定 MySQL 8.0。我特意把内容写成纯文字不带截图因为命令和配置文件才是真正能直接复现的东西。这篇会从安装方式选择开始讲 Linux 和 Windows 两套完整链路覆盖初始化、权限、常见配置调优并把部署 Zabbix 7.0 LTS 时和 MySQL 8.0 配合的坑单独拎出来说。适合看这篇的人有三类第一次装数据库、想快速搭开发环境的新手已经装了 MySQL 但被密码、远程登录、服务启动折磨到怀疑人生的老哥以及正在给监控平台、Web 应用准备后端数据库需要一份能直接照着执行的清单的运维同学。全文以命令和实际操作为主不会绕弯子你照着敲就能跑。1. 装之前必须分清的三件事版本、环境与安装方式1.1 为什么“别用 8.0”已经是过时的说法MySQL 8.0 刚发布那几年确实有不少人劝退理由无非是默认认证插件变了、部分老客户端连不上、5.7 到 8.0 的升级路径有坑。但放到现在这些理由基本都不成立了。MySQL 8.0 已经是非常成熟的长期支持版本官方在 2023 年后对 5.7 的更新支持已经停止新项目再开 5.7 的坑等于把一个生命周期快到头的数据库放进生产环境。相比 5.78.0 最核心的变化是默认字符集变成了 utf8mb4数据字典改用 InnoDB 管理支持窗口函数和公共表表达式JSON 查询能力大幅增强性能也比 5.7 有明显提升。更重要的一点是很多监控、运维、BI 工具的新版本都在围绕 8.0 做适配比如 Zabbix 7.0 LTS 官方推荐的就是 MySQL 8.0 系列。所以现在装库直接用 8.0不要犹豫。1.2 平台选择决定了后面所有步骤安装 MySQL 8.0 之前先想清楚你在什么系统上装因为后续步骤完全不同Linux 服务器这是生产环境最主流的场景。推荐用官方 Yum/Apt 仓库安装原因后面会说。CentOS、Rocky Linux、AlmaLinux 这类 RHEL 系系统走 rpm 路线Ubuntu、Debian 走 apt 路线。Windows 桌面或开发机适合本地开发、测试、学习。有两套方案一是官方 Installer 图形界面二是 ZIP 压缩包手动安装。我建议开发机用官方 Installer但如果你想练一下对 MySQL 目录和服务的掌控能力ZIP 方案值得走一遍。Docker 容器适合快速拉起一个临时数据库或者跑自动化测试。不过生产环境用 Docker 跑 MySQL 需要额外考虑数据卷、权限、网络模式的问题不建议新手一上来就容器化部署先把常规安装链路走通再说。1.3 安装方式对比很多人上来就问“我该下载哪个包”这里先给一张对比表你看着选就行安装方式优点缺点适合场景官方 Yum/Apt 仓库安装简单、升级方便、依赖自动处理需要联网拉取仓库Linux 生产/开发环境通用二进制包可自定义目录、适合内网离线部署初始化和服务脚本要手动处理有一定经验的管理员源码编译可定制编译参数耗时、依赖多、维护成本高极少见除非有特殊需求Docker启动快、环境隔离数据持久化、权限处理复杂开发测试、临时环境我个人的建议很直接Linux 上优先官方仓库Windows 上优先官方 Installer离线内网才考虑二进制包。源码编译我不推荐除非你确实需要定制某些底层功能否则纯属浪费时间。2. 在Rocky/CentOS上用官方仓库安装MySQL 8.02.1 先清场处理系统自带的 MariaDB很多 RHEL 系系统默认带着 MariaDB 的库文件如果不清理后面装 MySQL 时会出现冲突或者mysql命令被 MariaDB 的客户端占住。先检查一下rpm -qa | grep -i mysql rpm -qa | grep -i mariadb如果有输出先移除sudo yum remove -y mariadb-libs注意有些系统组件比如 Postfix依赖 mariadb-libs直接卸载可能会连带卸载掉一些组件所以卸载后建议跑一下sudo yum check或者干脆把 Postfix 这类不重要的组件也一并处理掉。我遇到过一次卸载 mariadb-libs 后 Postfix 被自动移除结果邮件告警功能失效排查了半天才发现是这个原因。2.2 添加官方 Yum 源并安装这里不推荐用系统自带的 AppStream 里的 mysql 模块因为版本通常不是最新的 8.0 小版本。官方 Yum 仓库的好处是版本新、依赖全、后续yum update可以直接升级。先安装仓库 rpm 包sudo rpm -ivh https://repo.mysql.com/mysql80-community-release-el9-5.noarch.rpm如果你用的是 CentOS 8、Rocky 8、AlmaLinux 8就把链接里的el9换成el8。安装完后检查仓库是否生效yum repolist all | grep mysql然后安装 server 包sudo yum install -y mysql-community-server这一步会自动拉取客户端、共享库、libaio 等依赖。装完后验证版本mysql --version正常情况下会输出类似mysql Ver 8.0.xx for Linux on x86_64的信息。2.3 启动服务并拿到初始临时密码MySQL 8.0 装完不会让你直接设置密码而是把初始密码写进日志。先启动服务sudo systemctl start mysqld sudo systemctl enable mysqld然后去日志里找临时密码sudo grep temporary password /var/log/mysqld.log输出会类似这样[Note] [MY-010454] [Server] A temporary password is generated for rootlocalhost: xxxxxxxx把这串密码复制下来这是你第一次登录用的。登录命令mysql -uroot -p输入临时密码后系统会强制你修改 root 密码否则什么都干不了ALTER USER rootlocalhost IDENTIFIED BY Your_New_Password2024;这里要注意密码强度。8.0 默认装了 validate_password 组件要求密码至少 8 位并且包含大小写字母、数字和特殊字符。如果不想用这么强的策略后面我会讲怎么调。2.4 初始化之前就把数据目录规划好datadir 迁移很多人的习惯是装完就直接用等数据量大了才发现/var/lib/mysql所在分区不够用然后被迫迁移数据目录。迁移虽然可以做但会有一段时间的停机业务方不会开心。所以我强烈建议在初始化之前就决定好数据目录放在哪。如果你有独立数据盘比如/data先把目录建好sudo mkdir -p /data/mysql sudo chown mysql:mysql /data/mysql sudo chmod 750 /data/mysql然后把/etc/my.cnf里的datadir改成你规划的路径[mysqld] datadir/data/mysql注意如果服务已经启动过、/var/lib/mysql下已经有数据了再去改datadir会导致启动失败。正确的顺序是装完包之后先别systemctl start mysqld直接改配置文件再启动。MySQL 8.0 在服务启动时发现datadir是空目录会自动完成初始化。如果你用的是全新系统数据盘我建议顺序是分区挂载 - 创建目录 - chown - 改 my.cnf - 启动服务。3. Windows 安装中容易踩的三个细节3.1 用官方 Installer 还是 ZIP 压缩包Windows 上安装 MySQL 8.0 有两条路官方 Installermysql-installer-community-8.0.xx.msi适合大多数用户。它会引导你选择安装类型我建议在安装时选择 Server only不要勾选 MySQL Workbench、MySQL Shell 以外的一堆插件保持环境干净。Installer 会自动处理服务注册和 my.ini 生成很适合开发机。ZIP 压缩包mysql-8.0.xx-winx64.zip适合想完全掌控目录结构的人。下载后解压到你想要的路径比如D:\mysql-8.0.xx然后在目录下手动创建my.ini[mysqld] basedirD:/mysql-8.0.xx datadirD:/mysql-8.0.xx/data port3306 character-set-serverutf8mb4这里有个坑路径里的分隔符建议用正斜杠/因为反斜杠在配置解析里会被转义容易出幺蛾子。我见过有人写成D:\mysql\data结果服务起不来日志里全是路径错误。3.2 手动初始化时 --initialize 和 --initialize-insecure 怎么选ZIP 包不会自动初始化需要你手动执行mysqld --initialize --console这个命令会在 data 目录生成初始化数据并随机生成 root 密码输出在控制台上务必保存。另一种方式是mysqld --initialize-insecure --console这个会生成一个 rootlocalhost 且密码为空的账户登录后需要立刻设置密码。我的建议是本地开发想省事用 --initialize-insecure登录后立刻改密码想贴近生产习惯就用 --initialize体验一遍“临时密码 - 修改密码”的流程。注意命令必须在你自己的basedir目录下执行而且 data 目录必须不存在或者是空目录否则会报错。3.3 注册 Windows 服务与常见启动失败初始化完成后把 mysqld 注册成系统服务mysqld --install MySQL80 --defaults-fileD:/mysql-8.0.xx/my.ini然后启动net start MySQL80如果启动失败先看错误日志Windows 下日志默认在datadir目录下文件名是主机名.err。最常见的失败原因有三个my.ini里路径写错或者文件编码不对保存时必须用 ANSI 或 UTF-8无 BOM编码不要用 UTF-8 with BOM。data 目录权限不对或者被杀毒软件拦截了 mysqld 进程。3306 端口被其他程序占用比如你电脑上装过旧的 MySQL 或 MariaDB。端口排查用系统命令netstat -ano | findstr 3306有输出就看 PID 对应什么进程必要时改配置里的端口或者停掉占用程序。4. 初始化安全与权限配置能连上才算装完4.1 mysql_secure_installation 到底替你做了哪些事Linux 上装完后官方推荐的下一步是跑一遍mysql_secure_installationsudo mysql_secure_installation它会按顺序问你几个问题是否修改 root 密码是否移除匿名用户是否禁止 root 远程登录是否删除 test 数据库是否刷新权限表我每次装完都会跑一遍因为移除匿名用户和清理 test 库这两件事手动做很容易漏掉。尤其 test 库默认情况下任何用户都能访问虽然数据不重要但作为一个隐患不值得留。4.2 远程访问用户创建与 localhost/% 区分root 账号默认只能从本机登录这是好事生产环境千万不要开 root 远程访问。你需要的是为业务单独创建用户。比如要创建一个用户仅允许从应用服务器192.168.1.10连接可以这样CREATE USER app192.168.1.10 IDENTIFIED BY StrongPassword2024; GRANT ALL PRIVILEGES ON app_db.* TO app192.168.1.10;如果应用服务器 IP 不固定或者你只想图省事也可以允许任意主机CREATE USER app% IDENTIFIED BY StrongPassword2024; GRANT ALL PRIVILEGES ON app_db.* TO app%;这里的%表示除 localhost 外的任意地址。注意applocalhost和app%是两个不同的账号如果你只创建了app%在数据库本机用mysql -uapp -p登录时会匹配到applocalhost然后提示找不到用户。这是一个非常容易踩的坑。修改权限后如果是通过 GRANT 语句授权的不需要刷新权限表如果你是手动INSERT INTO mysql.user改的才需要FLUSH PRIVILEGES;。4.3 caching_sha2_password 带来的“老客户端连不上”问题MySQL 8.0 默认的认证插件是caching_sha2_password相比老版的mysql_native_password安全性更高但问题在于早期版本的 PHP 7.1 以下、Navicat 旧版、部分 Java 老驱动都不支持这个新插件会直接报Authentication plugin caching_sha2_password cannot be loaded之类的错。解决方法有两种第一种升级客户端到最新版这也是官方推荐的做法。PHP 7.4、Navicat 16、较新的 JDBC 驱动都支持。第二种如果你确实没办法升级客户端比如被生产环境的 PHP 版本锁死就只能把特定用户的认证插件改回旧的ALTER USER app% IDENTIFIED WITH mysql_native_password BY StrongPassword2024;这里我多说一句能用新协议就用新协议改回旧插件只是权宜之计。MySQL 8.4 开始已经默认移除mysql_native_password你迟早要面对升级。4.4 root 密码丢失后的两种思路忘记 root 密码是每个人都会经历的尴尬时刻处理思路分两种。第一种临时跳过授权表。先编辑/etc/my.cnf在[mysqld]下加一行skip-grant-tables然后重启服务sudo systemctl restart mysqld mysql -uroot登录后先刷新权限再改密码因为跳过授权表时很多操作会被拒绝FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY NewPassword2024;然后删掉skip-grant-tables配置重启服务。注意skip-grant-tables 状态下不校验任何密码等于裸奔只允许在本地操作并且处理完必须立刻删掉配置。第二种更干净的方式是用init-file参数。在/etc/my.cnf中指定一个含 SQL 语句的文件[mysqld] init-file/tmp/mysql-init.sql然后在/tmp/mysql-init.sql里写ALTER USER rootlocalhost IDENTIFIED BY NewPassword2024;重启服务时会自动执行这条 SQL执行完后立刻删除该文件和配置项。这种方式的好处是可以审计也不会有裸奔窗口。5. my.cnf 里值得调整的几个核心参数5.1 配置文件读取顺序与分文件管理Linux 下 MySQL 读取配置文件的顺序大致是/etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf后读的会覆盖先读的。你可以用以下命令查看实际生效的配置文件路径mysqld --verbose --help | grep -A 1 Default options8.0 的 RPM 包默认在/etc/my.cnf里通过!includedir /etc/my.cnf.d引入目录下的所有.cnf文件。我的习惯是把不同功能的配置拆到不同文件里比如/etc/my.cnf.d/character-set.cnf、/etc/my.cnf.d/log.cnf、/etc/my.cnf.d/innodb.cnf这样做的好处是改动某个模块时不会动到主配置回滚也方便。5.2 字符集、连接数与 InnoDB 缓冲池字符集在 8.0 里已经默认是 utf8mb4不需要特别折腾但我还是建议在[mysqld]下显式声明一下character-set-serverutf8mb4 collation-serverutf8mb4_0900_ai_ciutf8mb4_0900_ai_ci是 8.0 的默认排序规则比 5.7 常用的utf8mb4_general_ci更准确。如果你要和 5.7 的数据做兼容可以考虑用utf8mb4_general_ci否则保持默认即可。连接数max_connections不是越大越好。每个连接都要占用线程和内存盲调到 5000 只会让系统更容易 OOM。简单估算方式按 256MB 内存支撑约 100 个并发连接来粗算结合你的应用线程池大小。一般 Web 应用 300 到 500 就够除非你确实测过连接池上限。InnoDB 缓冲池这是 MySQL 性能最关键的一个参数。默认值是 128MB生产环境必须调。通用经验专用 MySQL 实例给物理内存的 60% 到 70%。比如 32G 内存的机器innodb_buffer_pool_size20G设置后通过以下命令验证SHOW VARIABLES LIKE innodb_buffer_pool_size; SHOW GLOBAL STATUS LIKE Innodb_buffer_pool_read_requests; SHOW GLOBAL STATUS LIKE Innodb_buffer_pool_reads;如果Innodb_buffer_pool_reads明显偏高说明大量数据要从磁盘读缓冲池可能还不够。5.3 日志、慢查询和二进制日志生产环境建议把慢查询打开这是排查 SQL 性能的必备工具slow_query_log1 slow_query_log_file/var/log/mysql/slow.log long_query_time1 log_queries_not_using_indexes1long_query_time1表示超过 1 秒的 SQL 都会被记录。测试环境你可以设成 0.5 甚至 0.1生产环境我建议先 1 秒否则日志刷得太快。二进制日志是主从复制和数据恢复的基础。如果你是单机可以在初始化后开启server-id1 log-binmysql-bin binlog_expire_logs_seconds604800binlog_expire_logs_seconds604800表示二进制日志保留 7 天单位是秒这是 8.0 的写法老版本是expire_logs_days。还有两个 8.0 特有的参数值得注意innodb_redo_log_capacity1G8.0.30 之后重做日志改用innodb_redo_log_capacity控制大小官方建议生产环境不要低于 100MB通常设到 1G 以上可以减少频繁刷盘的性能抖动。5.4 修改配置后的验证方法改配置不是改完就好必须验证。重启服务后用下面几组 SQL 确认SHOW VARIABLES LIKE character_set_server; SHOW VARIABLES LIKE max_connections; SHOW VARIABLES LIKE slow_query_log;看到的值和你配置的一致才算真正生效。如果发现没生效优先级最高的嫌疑是配置文件路径不对或者参数被后面的配置文件覆盖了。用 5.1 的方法查看实际读取了哪些配置文件逐层排查。6. 给部署 Zabbix 7.0 LTS 的人提个醒MySQL 8.0 配合细节6.1 建库与建用户不要漏掉字符集很多人部署 Zabbix 时会顺手用系统自带的 MariaDB但 Zabbix 7.0 LTS 官方推荐的是 MySQL 8.0 系列所以如果你追求官方支持路径就在装好 MySQL 8.0 之后单独为 Zabbix 建库建用户。先登录 MySQLmysql -uroot -p然后执行CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE USER zabbixlocalhost IDENTIFIED BY Zabbix_Password2024; GRANT ALL PRIVILEGES ON zabbix.* TO zabbixlocalhost;这里有两个重点。第一个数据库字符集建议用utf8mb4_bin因为 Zabbix 官方文档和 schema 里的表默认使用这个排序规则避免大小写敏感问题导致数据匹配异常。第二个如果你的 Zabbix server 和 MySQL 不在同一台机器用户主机部分要写成 Zabbix server 的实际 IP或者用%同时确保 MySQL 允许远程连接bind-address 不是 127.0.0.1 才行。6.2 导入 SQL schema 时最常见的三个错误Zabbix 安装包里有初始化数据库的 SQL 文件路径一般是/usr/share/zabbix-sql-scripts/mysql/server.sql.gz。导入命令zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql -uzabbix -p zabbix这一步有三个高频错误一是没建库直接导会报No database selected。必须先建库再导入。二是用户权限不足只给了SELECT权限导致导入失败。建用户时直接GRANT ALL就完事别想着最小化权限Zabbix schema 会创建表、触发器、存储过程权限不够必报错。三是导入过程中中断比如网络不稳或超时。SQL 文件很大全量导入可能要几分钟。建议直接在 Zabbix server 本机执行不要在远程客户端上导减少中断概率。如果导到一半失败可以DROP DATABASE zabbix;后重建再导不要试图“接着导”因为事务不会完全回滚数据会处于残缺状态。导入完成后检查一下表数量是否正常USE zabbix; SHOW TABLES;正常会有几十张表包括hosts、items、triggers这些核心表。6.3 Zabbix server 连接 MySQL 的常见排查顺序Zabbix server 的数据库配置在/etc/zabbix/zabbix_server.conf里改这几个参数DBHostlocalhost DBNamezabbix DBUserzabbix DBPasswordZabbix_Password2024改完重启sudo systemctl restart zabbix-server如果日志报错连不上数据库按顺序排查MySQL 是否在运行systemctl status mysqld端口是否监听ss -lntp | grep 3306账号密码能否手动登录mysql -uzabbix -p -h 127.0.0.1 zabbix如果前面都通过再看/var/log/zabbix_server.log我遇到最多的问题其实是 DBHost 和登录方式不匹配Zabbix server 和 MySQL 同机时DBHostlocalhost会用 socket 连接如果你把DBHost127.0.0.1走 TCP 连接但 Zabbix 用户可能只创建了localhost的权限导致 TCP 登录被拒。这个细节很容易被忽略因为zabbix用户确实存在只是 host 匹配不上。另外Zabbix 前端PHP 页面也需要能连 MySQL。如果你是 nginx php-fpm 的部署方式先确认 PHP 装了 pdo_mysql 扩展php -m | grep pdo_mysql没有的话需要安装对应扩展包。前端页面的数据库配置在/etc/zabbix/web/zabbix.conf.php改完确保 web 目录可写否则安装向导写不进去配置文件。7. 服务起不来、密码连不上、端口不通——三个故障现场复原7.1 mysqld 启动失败的排查路径服务启动失败时第一步永远不是百度而是看错误日志。Linux 下默认日志位置是/var/log/mysqld.log。用journalctl -u mysqld也行但日志文件更直接sudo tail -50 /var/log/mysqld.log常见原因大致分几类目录权限问题。如果报错里出现Permission denied检查 datadir 属主和 SELinux 上下文sudo ls -ld /data/mysql如果属主不是 mysql执行sudo chown -R mysql:mysql /data/mysql如果 SELinux 是 enforcing 状态即便属主正确也可能被拦截。查看状态getenforce临时放行可以这样sudo chcon -R -t mysqld_db_t /data/mysql长期方案是把 SELinux 对 MySQL 的相应布尔值打开或者针对数据目录持久化上下文。如果只是开发机嫌麻烦也可以把 SELinux 设为 permissive但生产环境建议保留 enforcing 并正确配置。磁盘空间满。MySQL 启动时要写临时文件、redo log磁盘不够会直接起不来df -h/var/lib/mysql或数据目录所在分区使用率到 100% 时先清理再启动。配置错误。my.cnf里某个参数写错或者 datadir 路径指向不存在的目录。用mysqld --validate-config可以快速检查配置项是否合法mysqld --defaults-file/etc/my.cnf --validate-config没有输出说明配置基本没毛病。7.2 ERROR 1045/2003/2013 的常见原因这三个报错是连接 MySQL 时最常遇到的我分别说下。ERROR 1045 (28000): Access denied for user账号密码错误或者授权主机不匹配。先确认密码大小写和特殊字符再检查用户表里的 Host 字段。常见场景你用root从远程连但 root 只允许 localhost或者你新建的用户app%在被访问的机器上登录时匹配不到。ERROR 2003 (HY000): Cant connect to MySQL server on x.x.x.x连不上服务原因通常是服务没监听、端口不对、防火墙拦截。在服务器本机先自测mysql -uroot -p -h 127.0.0.1 -P 3306如果本机能连远程不行大概率是防火墙问题。ERROR 2013 (HY000): Lost connection to MySQL server during query连接建立后中途断开。常见原因有max_allowed_packet太小遇到大查询或大数据包直接断开网络不稳导致超时MySQL 的wait_timeout太短导致空闲连接被断开。这类问题要结合具体业务场景调参不一定是配置错误。7.3 防火墙、SELinux 与 bind-address远程连不上 MySQL 时除了账号权限还有两个系统层面的因素必须排查。bind-addressMySQL 默认监听 127.0.0.1只允许本机连接。要让远程机器能访问在my.cnf里改bind-address0.0.0.0也可以指定具体网卡 IP。改完重启服务用ss -lntp | grep 3306确认监听地址。防火墙CentOS/Rocky 默认用 firewalldsudo firewall-cmd --permanent --add-port3306/tcp sudo firewall-cmd --reload sudo firewall-cmd --list-ports这步操作前要确认你对服务器防火墙策略有清楚认知不要为了省事把整个 zone 设为允许那样会引入不必要的风险。最后分享一个我自己的习惯所有配置改动我都会在my.cnf里写一行注释标注修改日期和原因例如# 2025-03-20: 提高并发能力应用侧连接池确认峰值为300 max_connections500数据库这东西慢就是稳稳就是省心。按照这套链路走完MySQL 8.0 的安装配置、权限设计、基础调优和故障排查你基本都能做到心里有数后面再遇到问题也知道从哪里下手。