一台服务器装两台MySQL完全可行,主流方案是同一版本用官方多实例功能,不同版本共存则用Docker容器,按本文步骤操作即可稳定运行。
为什么会产生一台服务器装两个MySQL的需求
很多技术朋友遇到过一个尴尬场景:测试环境需要模拟线上数据,但线上数据库表结构改了,测试库不敢动;或者公司接到一个老项目维护,对方用的MySQL 5.7,你手上新项目已经用上MySQL 8.0,手头预算有限,老板只批了一台服务器,这时候“一台服务器跑两个MySQL”就成了刚需。
行业共识认为,一台物理机上部署多个MySQL实例,只要做好端口、数据目录、内存资源的隔离,稳定性并不比单实例差,据MySQL官方文档说明,多实例部署属于官方支持的运行方式,并非歪门邪道。
一台服务器装两个mysql实例的三种方案
动手之前先理清思路,当前主流做法分三条路,各自适用场景不同。
官方多实例(mysqld_multi)同版本首选
适合两个MySQL版本一致、需要长期稳定运行的场景,比如两个业务库都是MySQL 8.0,只是库名不同、账号不同,这种方式的优势是资源利用率高,两个实例共享一套二进制文件,只分配各自的数据目录和端口。
Docker容器化版本不同或快速隔离
适合不同版本共存,比如一个5.7一个8.0,容器方案把每个MySQL装进独立环境,互不干扰,缺点是性能有轻微损耗,但对绝大多数中小业务来说感知不到。
源码编译安装或官方tar包双份部署
适合对性能极致敏感、又不想用容器的情况,需要把MySQL安装包解压到两个目录,分别初始化数据目录,优点是完全隔离,缺点是升级维护要弄两遍,操作繁琐。
对比下来,如果你问“一个服务器怎么装两台mysql最简单”,答案是多实例方案。
linux服务器多实例mysql安装详细步骤
下面以CentOS 7 + MySQL 8.0为例,逐步拆解多实例部署过程,全程使用命令行操作,路径规划是重点。
第一步:规划目录结构和端口
两个实例定位如下:
- 实例A:业务主库,端口3306,数据目录
/data/mysql/3306 - 实例B:报表或测试库,端口3307,数据目录
/data/mysql/3307
先创建目录并授权:
mkdir -p /data/mysql/{3306,3307}
chown -R mysql:mysql /data/mysql
第二步:准备两份配置文件
MySQL 8.0默认读取/etc/my.cnf,多实例场景下建议
显式指定配置文件,避免相互覆盖。
实例A的配置写在/etc/my-3306.cnf:
[mysqld] port=3306 datadir=/data/mysql/3306 socket=/tmp/mysql-3306.sock pid-file=/tmp/mysql-3306.pid log-error=/var/log/mysql-3306.log
实例B的配置写在/etc/my-3307.cnf:
[mysqld] port=3307 datadir=/data/mysql/3307 socket=/tmp/mysql-3307.sock pid-file=/tmp/mysql-3307.pid log-error=/var/log/mysql-3307.log
注意两个文件里端口、socket、pid文件必须全部不同,这是“一台服务器装两台mysql”最容易出错的地方,漏改socket会导致两个实例抢同一个文件,启动直接报错。
第三步:分别初始化数据目录
用mysqld命令初始化,注意指定各自的配置文件:
mysqld --defaults-file=/etc/my-3306.cnf --initialize-insecure mysqld --defaults-file=/etc/my-3307.cnf --initialize-insecure
加--initialize-insecure表示root账号初始密码为空,方便首次登录后自行修改,生产中建议去掉这个参数,改用自动生成的临时密码。
第四步:启动两个实例
推荐用mysqld_safe分别拉起:
mysqld_safe --defaults-file=/etc/my-3306.cnf & mysqld_safe --defaults-file=/etc/my-3307.cnf &
启动后用端口检查确认状态:
netstat -tlnp | grep -E '3306|3307' ss -lntp | grep mysql
两个端口都处于LISTEN状态,说明安装成功。
第五步:设置开机自启
编辑/etc/rc.local,加入两行启动命令:
mysqld_safe --defaults-file=/etc/my-3306.cnf & mysqld_safe --defaults-file=/etc/my-3307.cnf &
并赋予执行权限:
chmod +x /etc/rc.local
第六步:登录验证和账号隔离
用不同端口登录各自实例:
mysql -uroot -p --socket=/tmp/mysql-3306.sock mysql -uroot -p --socket=/tmp/mysql-3307.sock
两个实例的root密码是独立设置的,互相看不到对方的数据,日常业务账号也建议分开授权,实例A只开放3306的权限给应用服务器,实例B单独管理。
一台服务器跑两个MySQL的内存分配策略
多实例部署后,内存是最大的瓶颈,常见的坑是两台MySQL默认配置一样,各吃2GB内存,加起来直接撑爆低配服务器。
核心思路是让两个实例错峰使用内存,实例A作为主力业务,保留默认InnoDB缓冲池大小;实例B是辅助角色,大幅调低资源占用。
实例B的配置建议调整如下:
[mysqld] innodb_buffer_pool_size=256M max_connections=100 performance_schema=OFF skip-name-resolve
实例A如果业务量大,配置保持默认即可。
按这个策略,一台8GB内存的服务器,跑两个MySQL实例完全够用,如果你在纠结“服务器跑多个mysql数据库会不会卡”,先检查内存总量和缓冲池分配比例,多数情况下的卡顿都来自这里。
不同版本MySQL共存一台服务器的Docker实践
如果两个实例版本不同,比如一个MySQL 5.7兼容老程序,一个MySQL 8.0跑新业务,多实例方案就不适用了,因为二进制文件是同一套版本,此时用Docker最省心。
容器部署步骤
先拉镜像,再分别映射端口:
docker run -d --name mysql57 -p 3306:3306 -v /data/docker/mysql57:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=OldPass123 mysql:5.7 docker run -d --name mysql80 -p 3307:3306 -v /data/docker/mysql80:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=NewPass456 mysql:8.0
这里的关键点在于容器内部的3306被映射到宿主机不同端口,外部访问时用3306连老库,3307连新库。
容器方案和数据安全问题
容器方案虽然方便,但数据持久化必须挂在宿主机目录,上面命令里的-v参数把容器内数据目录映射到/data/docker/下,即使容器删了重建,数据还在。
备份方面建议用mysqldump在宿主机定时执行:
docker exec mysql57 mysqldump -uroot -pOldPass123 --all-databases > /backup/mysql57_$(date +%F).sql
两个MySQL实例的日常管理维护清单
装好只是开始,日常运维才是重点,以下清单按重要性排序。
端口和连接数监控
长期运行的隐患是连接数被占满,实例B如果被大量慢查询拖住连接,可能拖垮整台服务器,建议在crontab里加监控脚本:
/5 mysql -h127.0.0.1 -P3307 -uroot -pXXX -e "show status like 'Threads_connected';" >> /var/log/mysql3307_monitor.log
日志分开查看
两个实例的报错日志一定要分开配置,否则查问题时会混淆,log-error参数已在配置文件中区分,排查时按端口找日志即可。
定期备份策略
实例A做每日全量备份,实例B做每周全量备份,备份文件命名带上端口号,防止恢复时搞混。
mysql多实例配置常见问题排查
实际部署中,几个高频故障点值得提前了解。
第二个实例启动失败,提示端口被占用
运行netstat -tlnp | grep 3307查看端口占用情况,如果没被占用,检查my.cnf里是否残留了默认的3306配置,多实例场景下每个实例都必须显式指定--defaults-file。
两个实例都能启动,但无法同时登录
大概率是socket文件路径写重复了,或者socket文件权限不对,确认两个配置文件中的socket路径不同,且mysql用户有权限在/tmp下创建文件。
实例B运行一段时间后内存暴涨
检查是否有慢查询累积导致缓冲池膨胀,同时确认是否关闭了performance_schema,辅助实例没必要开启性能监控,关掉能省10%左右的内存开销。
一台服务器装两个MySQL的数据安全边界
多实例不是数据隔离的替代品,两个MySQL共用一台物理机,意味着以下风险依然存在:
- 磁盘故障会影响两个实例
- 操作系统层被入侵,所有数据文件都可被读取
- 误操作
rm -rf /data/mysql会同时清掉两份数据
所以核心业务和生产环境,不建议长期依赖单机多实例方案,比较合适的使用场景是开发测试、预发布验证、以及非核心业务的分库承载。
如果公司要求高可用,应把实例A和实例B分别做主从复制,或者直接上云数据库。
Q&A:关于一个服务器装两个mysql实例的高频疑问
两个MySQL实例同时运行,性能损耗有多大?
主要是内存争抢和磁盘IO竞争,按前面内存分配策略操作,实例A性能几乎不受影响,实例B适合处理非实时型任务,查询量大的场景建议把两个实例的数据文件放在不同磁盘,至少放在不同分区,能明显减少IO等待。
一台服务器装两个mysql收费吗?
MySQL社区版本身免费,无论装几个实例,官方都不收取授权费,如果公司有商业授权需求,则按订阅方式计费,和实例数量无关,省钱的前提是容量规划合理,避免因内存不足导致频繁OOM。
如何快速验证两个实例是否都正常工作?
一条命令检查端口监听状态,再分别执行简单查询:
mysql -h127.0.0.1 -P3306 -uroot -pXXX -e "select version();" mysql -h127.0.0.1 -P3307 -uroot -pXXX -e "select version();"
两个端口都能返回版本号,说明实例运行正常,据MySQL官方文档说明,多实例场景下各实例的版本号可以独立升级维护,互不制约。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/746234.html





