能配但必须严格隔离端口、socket文件、数据目录、pid文件;mysqld_multi不推荐用于生产,因其共用配置易误改全局参数、无法指定不同basedir、状态报告不准、日志粒度粗;手动启多实例须显式指定唯一socket路径,客户端连接需明确-s或host=127.0.0.1;初始化须用--initialize并及时改密;systemd管理需确保pid目录权限及selinux策略正确。

能配,但必须严格隔离四个关键资源:端口、socket 文件、数据目录、PID 文件。漏掉任意一个,轻则连接错乱,重则实例互相覆盖数据。
为什么 mysqld_multi 不推荐用于生产多实例
它用单个 /etc/my.cnf 统一管理所有实例,看似方便,实则埋雷:
- 配置项容易误改全局参数(比如改了
[mysqld]下的max_connections,所有实例都跟着变) - 无法为不同实例指定不同
basedir—— 想跑 MySQL 5.7 和 8.4 共存?做不到 -
mysqld_multi report偶尔不准确,尤其在进程卡住时,状态显示为 “running” 实际已僵死 - 日志路径、错误码捕获粒度粗,排障时要翻多个
error.log手动比对
手动启动多实例时 socket 路径必须显式指定
很多人只改了 port,却忘了 socket,结果 mysql -u root -S /tmp/mysql.sock 总连到第一个实例 —— 因为所有实例默认都写 /tmp/mysql.sock,后启动的直接覆盖前一个。
- 每个实例的
socket必须唯一,建议按端口命名:/tmp/mysql_3307.sock、/tmp/mysql_3308.sock - 客户端本地连接必须显式带
-S参数:mysql -u root -S /tmp/mysql_3307.sock - PHP/Python 连接时,
host=localhost会走 socket,不是 TCP;想走端口得写host=127.0.0.1 - 若 socket 目录不存在(如
/tmp权限太严),MySQL 启动会静默失败,查error.log才能看到Can't start server: Bind on unix socket...
初始化数据目录必须用 --initialize,不能用 --initialize-insecure
MySQL 5.7+ 默认启用密码策略,--initialize-insecure 生成空密码 root 用户,但会跳过 validate_password 插件加载,后续执行 ALTER USER 可能报错 ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
- 坚持用
mysqld --initialize --user=mysql --datadir=/data/mysql/3307/data --socket=/tmp/mysql_3307.sock --port=3307 - 临时密码在对应
error.log最末行,格式是:A temporary password is generated for root@localhost: xxxxxx - 首次登录后必须立刻改密:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPass123!'; - 如果初始化后没及时登录改密,实例可能因密码过期被锁,再连就报
ERROR 1862 (HY000): Your password has expired.
systemd 管理多实例最容易忽略 PID 文件权限
用 systemctl start mysql@3307 这类模板单元时,常见失败原因是 PID 文件路径不可写,或 SELinux 拦截。
- PID 文件路径(如
/var/run/mysqld/mysqld_3307.pid)所属用户必须是mysql,且目录存在:mkdir -p /var/run/mysqld && chown mysql:mysql /var/run/mysqld - 检查 SELinux 状态:
getenforce,若是Enforcing,需加上下文:semanage fcontext -a -t mysqld_var_run_t "/var/run/mysqld(/.*)?" && restorecon -Rv /var/run/mysqld - systemd 单元文件里
User=mysql和Group=mysql必须显式声明,否则以 root 启动会写入失败 - 不要复用官方
mysqld.service,应新建/etc/systemd/system/mysql@.service,用%i替换端口号
真正麻烦的从来不是启动几个进程,而是让它们互不感知、互不干扰——端口和 socket 是门牌号,datadir 是住宅,PID 是身份证,缺一不可。初始化完不看 error.log,等于没装;连上不改密,等于白启。











