MySQL 多版本共存的核心前提:不能共用 data 目录和端口
MySQL 同一机器上跑多个版本,最常踩的坑就是直接覆盖安装或复用
my.cnf配置——结果是服务起不来、数据被误删、或者新版本连老数据都认不出。根本原则是:每个版本必须有独立的安装路径、
data目录、配置文件、socket 文件和端口。官方不支持“一键切换版本”,所谓“切换”本质是启停不同实例,而非动态加载不同二进制。
推荐方案:按版本分目录 + 独立配置 + systemd 服务隔离
以同时运行
mysql-5.7.44和
mysql-8.0.33为例(Linux,非 Docker): 安装包解压到不同路径,例如:
/opt/mysql-5.7.44和
/opt/mysql-8.0.33各自初始化
data目录:
/opt/mysql-5.7.44/bin/mysqld --initialize --user=mysql --datadir=/var/lib/mysql57;同理用
mysql-8.0.33初始化
/var/lib/mysql80为每个版本写独立配置文件:
/etc/my57.cnf和
/etc/my80.cnf,关键项必须区分:
port(如 3307 / 3308)、
socket(如
/tmp/mysql57.sock)、
datadir、
pid-file用 systemd 管理:复制
mysqld.service模板,改名为
mysqld57.service和
mysqld80.service,在
ExecStart中指定对应
--defaults-file=/etc/my57.cnf和二进制路径
启动后,用
mysql -S /tmp/mysql57.sock -u root -p或
mysql -h 127.0.0.1 -P 3308 -u root -p显式连接目标实例。
为什么不用 alias 或 PATH 切换?
alias mysql=/opt/mysql-8.0.33/bin/mysql这类做法只影响客户端命令,对服务端完全无效。更危险的是修改
PATH优先级后执行
mysqladmin shutdown或
mysqld_safe,极易操作错实例。实际项目中,开发/测试环境需要明确知道当前连接的是哪个版本的 server,靠 shell 别名会掩盖真实依赖,导致 CI 脚本在不同机器行为不一致。
常见报错与定位方法
启动失败时先看错误日志(配置里的
log-error路径),高频问题包括:
Can't start server: Bind on TCP/IP port: Address already in use→ 端口冲突,检查
netstat -tuln | grep :330[6-9]
Failed to find valid data directory→
datadir权限不对(需属主
mysql:mysql)或路径不存在
Unknown suffix '.0' used for variable 'server_id'→ 配置项写法不兼容(如 5.7 的
server_id=1在 8.0 可用,但某些旧参数如
query_cache_type在 8.0 已移除) 连接时报
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded→ 客户端太老(如 MySQL 5.7 client 连 8.0 server),需加
--default-auth=mysql_native_password或重置用户认证方式
多版本共存不是为了“随时切着玩”,而是为了迁移验证、兼容性回归或遗留系统支撑。真正难的不是装多个版本,是确保每个实例的生命周期(启停、备份、升级)彼此绝缘,且监控能区分清楚——这点常被忽略,直到某次误操作把 5.7 的
data目录当 8.0 的传给 mysqld 做了 --initialize-insecure。
