能配,但必须每个实例独占datadir、socket、port、pid-file和log-error;推荐用--defaults-file指向专属配置文件初始化,systemd需使用mysqld@.service模板,连接时须显式指定-p或--socket。

能配,但必须每个实例独占 datadir、socket、port、pid-file 和 log-error,缺一不可;用同一套二进制文件完全可行,不需装多个 MySQL 版本。
初始化时必须显式指定 --defaults-file 或全部参数
很多人卡在初始化失败,报错类似 Can't find messagefile '/usr/share/mysql/errmsg.sys' 或直接段错误——根本原因是没告诉 mysqld 该读哪个配置文件,它默认去找系统级 /etc/my.cnf,而那个文件往往不包含你为多实例准备的路径。
- 推荐方式:用
--defaults-file指向每个实例专属的配置文件(如/data/mysql3307/etc/my.cnf),再加--initialize-insecure(开发环境)或--initialize(生产环境,会生成临时密码) - 备选方式:所有路径参数全写死在命令行,例如:
mysqld --initialize --user=mysql --datadir=/data/mysql3307/data --socket=/data/mysql3307/socket/mysql.sock --port=3307 --log-error=/data/mysql3307/log/error.log - 千万别省略
--user=mysql,否则初始化出来的数据目录属主是 root,后续启动会因权限拒绝
my.cnf 中必须隔离五类关键路径
一个配置项写错,两个实例就可能抢同一个 socket 文件或 pid 文件,导致启动失败或互相 kill。重点检查以下五项是否全部独立:
-
datadir:必须指向各自的数据目录,不能共用,也不能嵌套(比如/data/mysql/instance1/data和/data/mysql/instance1会冲突) -
socket:建议用绝对路径,且文件名带端口号,如/data/mysql3307/socket/mysql.sock -
pid-file:必须唯一,否则systemctl start时无法判断进程是否存活 -
log-error:错误日志路径不同,才能快速定位是哪个实例挂了 -
port:这是最基础的,但容易被忽略的是:如果绑定bind-address=127.0.0.1,那其他机器连不上;若要远程访问,得设成0.0.0.0或具体内网 IP,并确认防火墙放行对应端口
systemd 启动必须用模板服务(mysqld@.service)
硬写多个 mysqld3306.service、mysqld3307.service 不仅重复,而且升级后容易被覆盖。标准做法是启用 systemd 的实例化模板:
- 创建模板文件
/etc/systemd/system/mysqld@.service,其中ExecStart要带%i占位符,例如:ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql%i/etc/my.cnf - 重载配置:
systemctl daemon-reload - 启用并启动:
systemctl enable mysqld@3307 && systemctl start mysqld@3307 - 验证:
systemctl status mysqld@3307看是否 active,再用ss -tlnp | grep :3307确认端口监听
连接客户端时必须显式指定 --socket 或 --port
即使配置了多个实例,mysql 命令默认仍连 3306 + /var/lib/mysql/mysql.sock。不指定就会连错,甚至误操作到生产实例。
- 连本地非默认端口:
mysql -u root -p -P 3307(注意大写-P) - 连本地非默认 socket:
mysql -u root -p --socket=/data/mysql3307/socket/mysql.sock - 远程连接必须用
-h+-P,例如:mysql -h 192.168.1.100 -P 3307 -u root -p - 别依赖
~/.my.cnf里的通用配置,它对多实例场景反而是隐患;如需简化,可为每个实例建单独的 alias,如alias mysql3307='mysql -P 3307 -u root -p'
最容易被跳过的其实是 server-id ——虽然单机多实例不涉及复制,但如果你后续开启 GTID 或打算做主从,这个值必须全局唯一;建议从实例初始化起就设好,比如 3306 实例设 server-id = 3306,3307 就设 3307,避免以后补救。











