如何在Linux Ubuntu中运行多个MySQL服务实例?

在 Ubuntu 上运行多个 MySQL 实例是完全可行的,关键在于为每个实例配置独立的 数据目录端口socket 文件配置文件。以下是完整步骤(以两个实例为例:mysql1mysql2):


✅ 前提条件

  • 已安装 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 的适配方案吗?

云服务器