我先把结论撂这儿:在一台服务器上装两个MySQL,这事儿真没你想的那么玄乎。很多人一听“双实例”就脑补出一堆容器化、虚拟化的大词,其实最土的办法往往最管用——直接装两遍,用不同的端口和目录隔离,一步到位,半小时搞定。我前几天刚在一台CentOS 7的破机器上实操了一遍,从解压到跑通,全程没碰Docker,也没碰什么复杂的中间件,就是老老实实配了两个独立的数据目录和两个独立的配置文件。今天把这套流程掰开揉碎了给你讲清楚,你照着抄作业就行。

第一步,先把两个MySQL的安装包准备好。我建议你别用yum或者apt直接装,因为系统自带的包管理器会把MySQL装成唯一的服务,后面改起来麻烦。直接去官网下社区版的二进制tar包,解压到两个不同的目录,比如/usr/local/mysql-8.0.36和/usr/local/mysql-8.0.37,这样版本都不一样,彻底物理隔离。解压完了别急着初始化,先建两个专用的系统用户,比如mysql1和mysql2,分别把两个目录的属主改掉。这一步很多人会偷懒用同一个mysql用户,结果后面权限乱了,两个实例互相踩脚,哭都来不及。
接着就是初始化数据目录。这一步是整个流程里最容易翻车的地方,因为MySQL 8.0之后默认的初始化命令变成了mysqld --initialize-insecure,它会生成一个空密码的root账号,但如果你同时跑两个实例,必须给每个实例指定独立的datadir和basedir。我用的命令是这样的:/usr/local/mysql-8.0.36/bin/mysqld --initialize-insecure --user=mysql1 --basedir=/usr/local/mysql-8.0.36 --datadir=/data/mysql1/data。注意,datadir一定要提前建好,而且属主必须是mysql1,否则初始化直接报错。第二个实例同理,把路径换成mysql2的,命令一模一样,只是目录不同。这一步做完,两个独立的数据文件就诞生了,互不干扰。
然后是最关键的配置文件。每个MySQL实例都得有自己的配置文件,不能共用。我习惯把第一个实例的配置文件放在/etc/f,第二个放在/etc/f。写配置的时候有几个参数必须区分开:port、socket、pid-file、log-error,还有datadir和basedir。比如第一个实例用3306端口,socket文件放在/tmp/mysql1.sock,第二个实例用3307端口,socket文件放在/tmp/mysql2.sock。千万别小看socket文件,如果你忘了区分,后面用命令行连接的时候,客户端会默认去找/tmp/mysql.sock,结果两个实例抢一个socket,直接连不上。另外,如果你要开binlog,记得log-bin也要分别命名,比如mysql1-bin和mysql2-bin,不然日志文件会互相覆盖。
接下来就是启动两个实例了。启动方式很简单,直接用mysqldsafe脚本,分别指定各自的配置文件。命令长这样:/usr/local/mysql-8.0.36/bin/mysqldsafe --defaults-file=/etc/f &,第二个实例同理。启动完了别急着高兴,先检查一下进程和端口:netstat -tlnp 3307',确认两个端口都监听了,再看一下各自的error log有没有报错。我之前第一次搞的时候,第二个实例死活起不来,后来发现是datadir的属主忘了改,权限不对,MySQL直接拒绝启动。这种低级错误排查起来特别费时间,所以每一步做完都建议顺手验证一下,别等一起炸。
两个实例都跑起来之后,连接管理也得分开。默认的mysql命令客户端会去找/tmp/mysql.sock,但你两个实例用了不同的socket,所以连接的时候必须显式指定。比如连接第一个实例:mysql -S /tmp/mysql1.sock -uroot -p,连接第二个实例:mysql -S /tmp/mysql2.sock -uroot -p。如果你嫌麻烦,也可以在各自的配置文件里把socket路径设成一样,但那样就没法同时连了,所以我劝你还是老老实实用不同的socket。另外,如果你需要远程连接,记得在配置文件的bind-address参数里写0.0.0.0,然后分别给两个实例创建不同的远程用户,授权的时候也要注意别搞混了。
还得提一嘴服务管理的事。如果你用的是systemd,建议给两个实例分别写一个service文件,比如mysql1.service和mysql2.service,每个文件里指定各自的mysqld_safe启动脚本和配置文件路径。这样以后重启机器或者管理服务的时候,直接systemctl start mysql1和systemctl start mysql2,干净利落。要是懒得写service文件,也可以用nohup手动启动,但那样每次开机都得手动拉起,有点烦。我自己的习惯是写两个service文件,一劳永逸,反正就几行配置的事。
回头再看整个过程,你会发现所谓“一步搞定”的秘诀其实就是两件事:目录隔离和配置隔离。只要把这两个点抓住了,别说两个MySQL,装五个六个都没问题,无非是多复制几份配置文件的事。我见过很多人一提到多实例就上云、上容器,其实在单机场景下,这种最土的物理隔离方案反而最稳,出了问题也好排查——哪个实例挂了,直接看对应的error log,不会互相污染。所以下次你再遇到“能不能一台机器跑俩数据库”这种需求,别慌,照着这套流程走一遍,半小时内保你两个实例同时跑得欢。


