必须用不同端口、数据目录和socket文件:mysql 5.7与8.0共存时,端口(如3306/3307)、datadir(如/var/lib/mysql57/与/var/lib/mysql80/)、socket(如/mysql57.sock与/mysql80.sock)必须完全隔离,否则启动报address already in use或can't start server;服务名、pid文件、日志路径等也需一一对应区分。

必须用不同端口、数据目录和 socket 文件
MySQL 5.7 和 8.0 不能共用 3306 端口、/var/lib/mysql 数据目录或 /var/lib/mysql/mysql.sock socket 文件,否则启动时会冲突报错,比如 Address already in use 或 Can't start server: Bind on TCP/IP port。系统级服务名也得区分:mysqld 默认给 5.7,mysqld8 或自定义 service 名给 8.0。
实操要点:
- 5.7 配置中保留
port = 3306,但显式指定datadir = /var/lib/mysql57、socket = /var/lib/mysql57/mysql.sock - 8.0 配置中必须改
port = 3307(或其他未被占用端口),datadir = /var/lib/mysql80,socket = /var/lib/mysql80/mysql.sock - 两个
datadir目录需提前创建并赋权:chown -R mysql:mysql /var/lib/mysql57 /var/lib/mysql80 - 若用 systemd 启动,8.0 的 service 文件不能叫
mysqld.service,得另起名如mysqld8.service,且ExecStart要指向 8.0 的mysqld二进制路径
YUM 安装时必须禁用默认版本自动启用
CentOS 7 的 MySQL YUM 源默认只允许一个版本处于 enabled=1 状态。如果两个 repo 都开着,yum install mysql-community-server 会按优先级装最新版(通常是 8.0),5.7 就装不上。
正确做法是编辑 /etc/yum.repos.d/mysql-community.repo:
- 把
[mysql57-community]下的enabled=1,[mysql80-community]下设为enabled=0 - 运行
yum install mysql-community-server→ 装上 5.7 - 再把配置反过来:
[mysql57-community]设enabled=0,[mysql80-community]设enabled=1 - 再跑一次
yum install mysql-community-server→ 这次装的是 8.0,但注意:它不会覆盖 5.7 的二进制或配置,只是多放一套文件
装完后检查:rpm -qa | grep mysql-community-server 应该输出两行,分别带 5.7.x 和 8.0.x 版本号。
初始化与首次启动必须分开执行,不能复用同一命令
mysqld --initialize 是有状态操作,会生成 root@localhost 的临时密码,并写入对应 datadir 下的 error.log。如果两个版本共用日志路径或没指定 --defaults-file,就会互相覆盖或报错。
安全初始化步骤:
- 对 5.7:先确保
/etc/my.cnf是它的配置,然后运行mysqld --initialize --user=mysql - 对 8.0:必须用完整路径指定配置文件,例如
/usr/sbin/mysqld --defaults-file=/etc/my.cnf.d/mysql80.cnf --initialize --user=mysql - 查临时密码别搞混:
grep 'temporary password' /var/log/mysqld.log是 5.7 的;grep 'temporary password' /var/log/mysqld8.log才是 8.0 的(前提是你在它的配置里设了log-error=/var/log/mysqld8.log) - 首次登录后改密码语法也不同:5.7 可用
SET PASSWORD = PASSWORD('xxx');;8.0 必须用ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxx';
systemd 服务名、日志路径、PID 文件必须完全隔离
哪怕端口和数据目录分开了,如果两个服务都注册成 mysqld.service,systemctl start mysqld 就只会启一个,另一个根本不会响应。更隐蔽的问题是 PID 文件冲突 —— 如果都写 /var/run/mysqld/mysqld.pid,后启的服务会删掉前一个的 PID,导致 systemctl status 显示异常。
关键隔离项:
- 5.7 保持默认:
/usr/lib/systemd/system/mysqld.service,PID 文件默认在/var/run/mysqld/mysqld.pid - 8.0 新建
/usr/lib/systemd/system/mysqld8.service,其中PIDFile=改为/var/run/mysqld8/mysqld8.pid - 两个服务的
StandardError和StandardOutput日志路径也要分开,避免journald混淆 - 启动顺序无关紧要,但停止时建议先停 8.0(
systemctl stop mysqld8),再停 5.7,避免 socket 文件残留干扰
最易忽略的一点:MySQL 8.0 默认启用 caching_sha2_password 认证插件,而老客户端(比如某些 PHP 7.2 扩展)不支持,连 3307 端口也会报 Client does not support authentication protocol —— 此时得在 8.0 的配置里加 default_authentication_plugin=mysql_native_password,不是改密码,是改认证方式。











