在 Ubuntu 上运行多个 MySQL 实例是完全可行的,关键在于为每个实例配置独立的 数据目录、端口、socket 文件和 配置文件。以下是完整步骤(以两个实例为例:mysql1 和 mysql2):
✅ 前提条件
- 已安装 MySQL Server(推荐用官方 APT 源):
sudo apt update sudo apt install mysql-server - 确保
/etc/mysql/目录结构清晰(Ubuntu 默认使用/etc/mysql/mysql.conf.d/mysqld.cnf)。
⚠️ 注意:不要直接修改主配置文件
mysqld.cnf来启动多实例;应创建独立配置文件。
🔧 步骤详解
1️⃣ 创建独立的数据目录与用户权限
# 创建数据目录(避免放在 /var/lib/mysql,防止冲突)
sudo mkdir -p /data/mysql1 /data/mysql2
# 创建对应系统用户(可选但推荐,提高安全性)
sudo useradd -r -s /bin/false mysql1
sudo useradd -r -s /bin/false mysql2
# 设置所有权与权限
sudo chown -R mysql:mysql /data/mysql1
sudo chown -R mysql:mysql /data/mysql2
sudo chmod 750 /data/mysql1 /data/mysql2
2️⃣ 初始化数据库实例(仅首次)
对第一个实例(port=3306):
sudo mysqld --initialize-insecure
--user=mysql
--datadir=/data/mysql1
--basedir=/usr
--socket=/tmp/mysql1.sock
--port=3306
--skip-grant-tables=false
-insecure表示不生成随机 root 密码(后续需手动设置);生产环境建议去掉该参数。
对第二个实例(port=3307):
sudo mysqld --initialize-insecure
--user=mysql
--datadir=/data/mysql2
--basedir=/usr
--socket=/tmp/mysql2.sock
--port=3307
3️⃣ 创建独立配置文件
示例:/etc/mysql/conf.d/mysql1.cnf
[mysqld]
user = mysql
pid-file = /run/mysqld/mysqld1.pid
socket = /tmp/mysql1.sock
port = 3306
datadir = /data/mysql1
basedir = /usr
bind-address = 127.0.0.1
log-error = /var/log/mysql/mysql1.err
symbolic-links = 0
innodb_buffer_pool_size = 256M
示例:/etc/mysql/conf.d/mysql2.cnf
[mysqld]
user = mysql
pid-file = /run/mysqld/mysqld2.pid
socket = /tmp/mysql2.sock
port = 3307
datadir = /data/mysql2
basedir = /usr
bind-address = 127.0.0.1
log-error = /var/log/mysql/mysql2.err
symbolic-links = 0
innodb_buffer_pool_size = 256M
💡 提示:
/run/mysqld/目录需存在且属主为mysql:sudo mkdir -p /run/mysqld sudo chown mysql:mysql /run/mysqld
4️⃣ 启动多个实例
方式一:使用 mysqld_safe(推荐用于调试/开发)
# 启动实例1
sudo mysqld_safe --defaults-file=/etc/mysql/conf.d/mysql1.cnf &
# 启动实例2
sudo mysqld_safe --defaults-file=/etc/mysql/conf.d/mysql2.cnf &
方式二:使用 systemd(生产环境推荐)
创建两个 unit 文件:
/etc/systemd/system/mysql1.service
[Unit]
Description=MySQL Instance 1
After=network.target
[Service]
Type=forking
User=mysql
Group=mysql
PIDFile=/run/mysqld/mysqld1.pid
ExecStart=/usr/sbin/mysqld --defaults-file=/etc/mysql/conf.d/mysql1.cnf
ExecStop=/usr/bin/mysqladmin --defaults-file=/etc/mysql/conf.d/mysql1.cnf shutdown
Restart=on-failure
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
/etc/systemd/system/mysql2.service
类似,仅将 mysql1 改为 mysql2,路径更新为 mysql2.cnf 等。
然后启用并启动:
sudo systemctl daemon-reload
sudo systemctl enable mysql1 mysql2
sudo systemctl start mysql1
sudo systemctl start mysql2
验证状态:
systemctl status mysql1 mysql2
mysqladmin -S /tmp/mysql1.sock ping # 或 -h 127.0.0.1 -P 3306
mysqladmin -S /tmp/mysql2.sock ping
5️⃣ 连接与管理
# 连接实例1(默认 root 无密码,若初始化时用了 -insecure)
mysql -S /tmp/mysql1.sock
# 或使用 TCP
mysql -h 127.0.0.1 -P 3306 -u root
# 连接实例2
mysql -S /tmp/mysql2.sock
mysql -h 127.0.0.1 -P 3307 -u root
🛑 安全提醒:首次登录后请立即为 root 设置密码,并创建专用应用账号!
🔍 常见问题排查
| 问题 | 解决方案 |
|---|---|
Address already in use |
检查端口是否被占用:sudo ss -tlnp | grep 330[67] |
Can't connect to local MySQL server through socket |
确认 socket 路径正确;检查 --socket 与客户端 -S 匹配 |
Permission denied on datadir |
chown -R mysql:mysql /data/mysqlX + chmod 750 |
mysqld: [ERROR] ... bind address conflict |
确保 bind-address 未重复监听同一 IP:Port |
📌 最佳实践建议
- 使用不同用户隔离(如上面创建的
mysql1/mysql2),避免单点故障风险。 - 日志分离便于监控:
tail -f /var/log/mysql/mysql1.err - 备份策略独立:
mysqldump --defaults-file=... > backup.sql - 考虑使用 Docker 容器化部署(更轻量、易管理):
docker run -d --name mysql1 -p 3306:3306 -v mysql1-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=xxx mysql:8.0
需要我提供自动化脚本(一键部署多实例)、Docker Compose 示例,或针对 MariaDB 的适配方案吗?
CLOUD技术笔记