在云服务器上隔离运行两个独立的 MySQL 实例,核心思路就是“多实例”或者“容器化/虚拟化”。
这里不扯虚的,直接给三种最主流、最稳妥的方案,按推荐程度排序。你要根据你的业务场景(是开发测试用,还是生产环境用)来选。
方案一:使用 systemd 管理多实例(最原生、资源占用最低)
这是 Linux 原生支持的方式,适合对性能要求高、不想引入额外开销的场景。原理是通过不同的配置文件和数据目录启动多个 mysqld 进程。
1. 准备工作
假设你要跑两个实例:mysql_3306 和 mysql_3307。
- 实例 A (默认): 端口 3306,数据目录
/var/lib/mysql,配置/etc/my.cnf - 实例 B (新实例): 端口 3307,数据目录
/data/mysql_3307,配置/etc/my_3307.cnf
2. 初始化数据目录
# 创建新实例的数据目录
mkdir -p /data/mysql_3307
chown -R mysql:mysql /data/mysql_3307
# 初始化数据库(以 CentOS/RHEL 为例,Ubuntu 类似但命令可能略有不同)
mysqld --initialize-insecure --user=mysql --datadir=/data/mysql_3307 --port=3307
3. 编写配置文件 /etc/my_3307.cnf
关键是要把 socket, pid-file, port, datadir 都改一下,避免冲突。
[mysqld]
port=3307
socket=/tmp/mysql_3307.sock
pid-file=/var/run/mysqld/mysqld_3307.pid
datadir=/data/mysql_3307
user=mysql
# 其他参数可以根据需要调整,比如 innodb_buffer_pool_size
4. 创建 Systemd Unit 文件
在 /etc/systemd/system/ 下新建 mysqld_3307.service:
[Unit]
Description=MySQL Server on port 3307
After=network.target
[Service]
Type=notify
User=mysql
Group=mysql
ExecStart=/usr/sbin/mysqld --defaults-file=/etc/my_3307.cnf
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=65535
Restart=on-failure
RuntimeDirectory=mysqld
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
5. 启动并设置开机自启
systemctl daemon-reload
systemctl enable mysqld_3307
systemctl start mysqld_3307
systemctl status mysqld_3307
优点:纯二进制运行,无虚拟化开销,CPU/内存利用率最高。
缺点:配置稍繁琐,故障排查时需要看具体的日志文件。
方案二:Docker 容器隔离(最灵活、环境一致性最好)
如果你熟悉 Docker,这是目前互联网公司的标准做法。即使你不做微服务,用 Docker 跑 MySQL 也能实现完美的文件系统隔离和端口映射。
1. 拉取镜像
docker pull mysql:8.0
2. 启动第一个实例(默认 3306)
docker run -d
--name mysql-primary
-p 3306:3306
-e MYSQL_ROOT_PASSWORD=root123
-v /data/mysql_primary:/var/lib/mysql
mysql:8.0
3. 启动第二个实例(独立隔离 3307)
docker run -d
--name mysql-secondary
-p 3307:3306
-e MYSQL_ROOT_PASSWORD=root456
-v /data/mysql_secondary:/var/lib/mysql
mysql:8.0
注意:这里 -p 3307:3306 意思是宿主机的 3307 端口映射到容器内部的 3306 端口。这样你在宿主机连接时,连的是 3307,但实际上进的是第二个 MySQL 实例。
优点:
- 彻底隔离:文件系统、环境变量、网络栈完全独立。
- 迁移方便:整个实例就是一个文件夹(Volume),备份恢复极其简单。
- 版本混用:你可以一个跑 5.7,一个跑 8.0,互不影响。
缺点:需要安装 Docker,且通过 NAT 端口映射会有极微小的网络延迟(通常可忽略)。
方案三:云厂商托管数据库 + 自建(架构级隔离)
如果你的服务器是阿里云 ECS、腾讯云 CVM 等,强烈建议不要自己在同一台机器上搞复杂的多实例。
最佳实践:
- 主库:购买云厂商的 RDS(如阿里云 RDS MySQL、腾讯cdb)。这是真正的物理/逻辑隔离,有自动备份、高可用、监控报警。
- 从库/备用库/测试库:在你的云服务器(ECS/CVM)上自己部署第二个 MySQL(用方案一或二)。
为什么?
- 云服务器本身不是为高可用设计的。如果单机磁盘坏了,你自己跑的 MySQL 就没了。
- 云 RDS 虽然贵点,但它包含了运维成本、备份策略和安全加固。
- 对于非核心业务,放在 ECS 上自建更省钱。
关键注意事项(避坑指南)
-
防火墙规则:
- 如果你用方案一或二,记得在云服务器安全组里放行 3306 和 3307 端口。
iptables或firewalld也要配好,别只开了 3306 忘了开 3307。
-
权限问题:
- MySQL 用户(通常是
mysql)必须有权访问新的数据目录。chown -R mysql:mysql /new/datadir这一步千万别漏,否则启动失败。
- MySQL 用户(通常是
-
连接方式:
- 应用连接时,如果是本地 Unix Socket,要注意 socket 路径变了(方案一)。
- 如果是 TCP/IP 连接,直接用 IP:Port 即可。
- Docker 环境下,应用如果在同一个 Docker Network 里,可以直接用容器名访问;如果在宿主机,要用
localhost:3307。
-
资源竞争:
- 两台 MySQL 跑在一台机器上,最大的风险是争抢 IOPS 和内存。
- 建议在
my.cnf中合理分配innodb_buffer_pool_size。比如总内存 8G,每个实例分 2G-3G,留足系统和其他服务空间。别两个都设成 7G,那肯定 OOM(内存溢出)。
-
备份策略:
- 多实例意味着你要写两份备份脚本,或者用一个脚本循环处理多个端口。
- 推荐使用
mysqldump或xtrabackup分别对 3306 和 3307 进行定时备份。
总结建议
- 个人学习/轻量级测试:用 Docker,最快上手,清理也干净。
- 生产环境高性能需求:用 Systemd 多实例,但务必做好资源限制。
- 正经业务:云 RDS + 自建备用,这才是正确的姿势。别在单台 ECS 上扛所有核心数据库的压力。
云技术博客