首先要明确核心结论:Mycat 不负责实现主从复制,仅依赖 MySQL 自身的主从复制机制,再通过 Mycat 配置将读请求转发到从库、写请求转发到主库(即读写分离)。
之前的对话中已经提到:Mycat 是数据库中间件,作用是「请求路由」,而非「数据同步」。数据同步(主从复制)的核心是 MySQL 自身的功能,Mycat 只需要感知主从节点的存在,就能实现读写分离。
因此,你问的「Mycat 中配置主从复制」,本质是 「先搭建 MySQL 主从复制(数据同步),再在 Mycat 中配置主从节点关联(请求路由)」 。以下是完整的分步实操(基于 CentOS 环境,MySQL 8.0 + Mycat 1.6.x):
Mycat 读写分离的基础是「主从数据一致」,必须先让 MySQL 主库和从库完成数据同步,Mycat 仅负责转发请求。
- 主库(Master):IP
192.168.1.101,MySQL 8.0,数据库 db1
- 从库(Slave):IP
192.168.1.103,MySQL 8.0,数据库 db1(需手动创建,与主库同名)
- 主从库网络互通,关闭防火墙或开放 3306 端口(MySQL 通信端口)
vim /etc/my.cnf.d/mysql-server.cnf
在 [mysqld] 节点下添加以下配置(开启二进制日志,指定主库唯一 ID):
[mysqld]
server-id = 101 # 主库唯一 ID(1-2^32-1,不能与从库重复)
log-bin = mysql-bin # 开启二进制日志(主从复制的核心,记录所有写操作)
binlog-do-db = db1 # 仅同步 db1 数据库(按需配置,不写则同步所有库)
binlog-ignore-db = mysql # 忽略同步系统库(可选)
expire_logs_days = 7 # 二进制日志保留 7 天(避免占用磁盘)
systemctl restart mysqld
mysql -uroot -p
mysql> show variables like 'server_id';
mysql> show variables like 'log_bin';
从库需要通过该用户连接主库同步数据:
CREATE USER 'repl'@'192.168.1.103' IDENTIFIED BY 'Repl123!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.103';
FLUSH PRIVILEGES;
mysql> show master status;
+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+
| mysql-bin.000001 | 156 | db1 | mysql | |
+
- 注意:记录
File(如 mysql-bin.000001)和 Position(如 156),后续从库配置需要用到。
vim /etc/my.cnf.d/mysql-server.cnf
在 [mysqld] 节点下添加以下配置(指定从库唯一 ID,开启中继日志):
[mysqld]
server-id = 103 # 从库唯一 ID(与主库不同)
relay-log = relay-bin # 开启中继日志(从库同步主库日志的临时文件)
replicate-do-db = db1 # 仅同步 db1 数据库(与主库一致)
replicate-ignore-db = mysql # 忽略同步系统库(可选)
read_only = 1 # 从库设为只读(避免直接写从库,root 用户除外)
systemctl restart mysqld
mysql -uroot -p
mysql> show variables like 'server_id';
mysql> show variables like 'relay_log';
mysql> stop slave;
mysql> change master to
master_host='192.168.1.101',
master_user='repl',
master_password='Repl123!',
master_log_file='mysql-bin.000001',
master_log_pos=156;
mysql> start slave;
mysql> show slave status\G;
- 关键验证项:
Slave_IO_Running: Yes(从库 IO 线程正常,能连接主库并读取二进制日志)
Slave_SQL_Running: Yes(从库 SQL 线程正常,能执行中继日志中的 SQL)
- 若为 No,查看
Last_IO_Error 或 Last_SQL_Error 字段排查原因(如密码错误、日志文件 / 位置错误、主从数据不一致)。
在主库 db1 中创建表并插入数据,查看从库是否同步:
use db1;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO user (id, name, age) VALUES (1, '张三', 20);
use db1;
select * from user;
MySQL 主从复制搭建完成后,Mycat 只需配置「主库(写节点)」和「从库(读节点)」,即可实现读写分离(写请求走主库,读请求走从库)。
vim /usr/local/mycat/conf/schema.xml
配置逻辑库、分片、主从节点关联,核心是 balance="1"(开启读写分离)和 readHost(关联从库):
<?xml version="1.0" encoding="UTF-8"?>
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="mycat_db" checkSQLschema="false" sqlMaxLimit="100">
<table name="user" dataNode="dn1" primaryKey="id" />
</schema>
<dataNode name="dn1" dataHost="host1" database="db1" />
<dataHost name="host1"
maxCon="1000" minCon="10"
balance="1" <!-- 开启读写分离:读请求转发到从库 -->
writeType="0"
dbType="mysql" dbDriver="native">
<heartbeat>select 1</heartbeat>
<writeHost host="master-101"
url="192.168.1.101:3306"
user="mycat"
password="123456">
<readHost host="slave-103"
url="192.168.1.103:3306"
user="mycat" <!-- Mycat 连接从库的用户(需在从库授权) -->
password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
Mycat 需要连接从库执行读请求,需在从库创建 Mycat 连接用户并授权:
GRANT ALL ON *.* TO 'mycat'@'%' IDENTIFIED BY '123456';
FLUSH PRIVILEGES;
/usr/local/mycat/bin/mycat stop
/usr/local/mycat/bin/mycat console
- 启动成功标志:日志中出现
Mycat Server startup successfully。
mysql -h127.0.0.1 -umycat_app -p123456 -P8066
use mycat_db;
INSERT INTO user (id, name, age) VALUES (2, '李四', 22);
SELECT * FROM user;
登录主库,查看 MySQL 日志,确认有 INSERT 操作:
set global general_log = on;
set global log_output = 'table';
select * from mysql.general_log where argument like '%INSERT INTO user%';
- 结果:能看到 Mycat 转发的 INSERT 请求(用户为
mycat_app)。
登录从库,查看日志,确认有 SELECT 操作:
set global general_log = on;
set global log_output = 'table';
select * from mysql.general_log where argument like '%SELECT * FROM user%';
- 结果:能看到 Mycat 转发的 SELECT 请求(主库日志无该 SELECT 记录)。
从库执行查询,确认主库的 INSERT 数据已同步:
use db1;
select * from user;
- 原因:主库 IP / 端口错误、复制用户密码错误、主库防火墙未开放 3306 端口。
- 解决方案:
- 验证从库能否 ping 通主库:
ping 192.168.1.101。
- 验证从库能否连接主库复制用户:
mysql -urepl -pRepl123! -h192.168.1.101 -P3306。
- 主库开放 3306 端口:
firewall-cmd --permanent --add-port=3306/tcp && firewall-cmd --reload。
- 原因:主从库数据不一致(如主库已存在表,从库无)、SQL 语法不兼容。
- 解决方案:
- 备份主库
db1 并导入从库:mysqldump -uroot -p db1 > db1.sql(主库),mysql -uroot -p db1 < db1.sql(从库)。
- 从库执行
stop slave; reset slave; 后,重新执行 change master to ... 配置。
- 原因:
schema.xml 中 balance 参数配置错误(如 balance="0",未开启读写分离)。
- 解决方案:确认
balance="1"(读请求转发到从库),重启 Mycat。
- 原因:从库未授权 Mycat 用户、从库 3306 端口未开放、从库 MySQL 未启动。
- 解决方案:
- 从库重新授权 Mycat 用户:
GRANT ALL ON *.* TO 'mycat'@'%' IDENTIFIED BY '123456';。
- 开放从库 3306 端口:
firewall-cmd --permanent --add-port=3306/tcp && firewall-cmd --reload。
- Mycat 不实现主从复制,仅依赖 MySQL 自身的主从复制保证数据一致,Mycat 负责「请求路由」(写主读从)。
- 配置流程:先搭 MySQL 主从复制(数据同步)→ 再配置 Mycat 关联主从节点(读写分离)。
- 关键验证点:MySQL 主从同步状态(两个 Yes)、Mycat 读写请求分发正确(写主读从)。
按照以上步骤,即可完成「MySQL 主从复制 + Mycat 读写分离」的完整配置,实现系统并发能力提升~