一、引言
在当今互联网高并发、大数据量的业务场景下,单一 MySQL 实例已无法满足性能与可用性需求。主从复制 实现了数据读写分离与高可用,MyCat 分库分表则突破了单表数据量的存储瓶颈,二者结合是构建大型分布式数据库系统的经典方案。
本文将从原理、环境搭建、实战配置到效果验证,完整讲解 MySQL 主从复制与 MyCat 分库分表的实现流程,帮助开发者快速掌握这一核心技术。
二、核心原理剖析
2.1 MySQL 主从复制原理
MySQL 主从复制(Master-Slave Replication)是基于 ** 二进制日志(Binary Log)** 实现的异步数据同步机制,核心流程如下:
- 主库(Master):当执行 INSERT/UPDATE/DELETE 等写操作时,会将数据变更记录到二进制日志(Binary Log)中。
- 从库(Slave) :通过 I/O 线程连接主库,请求获取指定位置之后的二进制日志,并写入本地中继日志(Relay Log)。
- 从库(Slave):通过 SQL 线程读取中继日志,重放其中的 SQL 操作,从而实现与主库的数据一致。
主从复制的核心作用:
- 读写分离:主库处理写请求,从库分担读请求,提升系统并发能力。
- 数据备份:从库可作为主库的实时备份,降低数据丢失风险。
- 故障转移:主库宕机时,可快速将从库提升为新主库,保证服务可用性。
2.2 MyCat 分库分表原理
MyCat 是一个开源的分布式数据库中间件,它实现了数据库分库分表 与读写分离,对应用层透明,让开发者可以像操作单库一样操作分布式数据库集群。
核心特性:
- 水平分表:将一张大表按规则(如范围、哈希、取模)拆分到多个数据库实例中,解决单表数据量过大问题。
- 垂直分库:将不同业务模块的表拆分到不同数据库,实现业务解耦与资源隔离。
- 读写分离:结合 MySQL 主从复制,自动将写请求路由到主库,读请求路由到从库。
- 跨库 Join:支持在分库分表场景下执行多表关联查询,简化开发复杂度。
三、实验环境准备
3.1 服务器规划
本次实验采用 3 台 CentOS 7 服务器,具体角色分配如下:
| 主机名 | IP 地址 | 角色 | 安装软件 |
|---|---|---|---|
| Mysql-server | 192.168.10.101 | MySQL 主库(Master) | MySQL 5.7.36 |
| Slave-server | 192.168.10.102 | MySQL 从库(Slave) | MySQL 5.7.36 |
| Mycat-server | 192.168.10.103 | MyCat 中间件节点 | JDK 8、MyCat 1.6 |
3.2 基础环境配置
-
关闭防火墙与 SELinux
systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config -
配置主机名与 hosts 解析
# 在各节点分别设置主机名 hostnamectl set-hostname Mysql-server hostnamectl set-hostname Slave-server hostnamectl set-hostname Mycat-server # 编辑/etc/hosts,添加以下内容 192.168.10.101 Mysql-server 192.168.10.102 Slave-server 192.168.10.103 Mycat-server -
同步系统时间
yum install -y ntpdate ntpdate cn.pool.ntp.org
四、MySQL 主从复制实战
4.1 安装 MySQL 5.7.36
在 ** 主库(Mysql-server)和从库(Slave-server)** 上执行相同安装步骤:
-
下载并安装 MySQL YUM 源
wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm rpm -ivh mysql57-community-release-el7-11.noarch.rpm -
安装 MySQL 服务
yum install -y mysql-community-server -
启动 MySQL 并设置开机自启
systemctl start mysqld systemctl enable mysqld -
获取初始密码并修改
grep 'temporary password' /var/log/mysqld.log mysql -uroot -p ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@123';
4.2 配置主库(Master)
-
编辑 MySQL 配置文件
/etc/my.cnf[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock server-id=101 # 唯一ID,主库为101,从库为102 log-bin=mysql-bin # 开启二进制日志 binlog-format=ROW # 推荐使用ROW模式,数据一致性更高 expire_logs_days=7 # 日志保留7天 -
重启 MySQL 服务
systemctl restart mysqld -
创建用于复制的账号
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.10.%' IDENTIFIED BY 'Repl@123'; FLUSH PRIVILEGES; -
查看主库状态
SHOW MASTER STATUS;记录下
File(如mysql-bin.000001)和Position(如154),后续从库配置需要用到。
4.3 配置从库(Slave)
-
编辑 MySQL 配置文件
/etc/my.cnf[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock server-id=102 # 唯一ID,不能与主库相同 relay-log=relay-bin # 开启中继日志 read_only=1 # 设置从库为只读(可选,保证数据一致性) -
重启 MySQL 服务
systemctl restart mysqld -
配置主从同步
CHANGE MASTER TO MASTER_HOST='Mysql-server', MASTER_USER='repl', MASTER_PASSWORD='Repl@123', MASTER_LOG_FILE='mysql-bin.000001', # 主库SHOW MASTER STATUS结果 MASTER_LOG_POS=154; # 主库SHOW MASTER STATUS结果 -
启动从库复制线程
START SLAVE; -
验证主从状态
SHOW SLAVE STATUS\G若
Slave_IO_Running和Slave_SQL_Running均为Yes,则表示主从复制配置成功。
4.4 主从复制效果验证
-
在主库创建测试数据库和表
CREATE DATABASE testdb; USE testdb; CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20)); INSERT INTO user (name) VALUES ('Tom'), ('Jerry'); -
在从库查询验证
USE testdb; SELECT * FROM user;若能查询到主库插入的数据,则说明主从复制生效。
五、MyCat 分库分表实战
5.1 安装 MyCat
在Mycat-server节点上执行安装步骤:
-
安装 JDK 8
yum install -y java-1.8.0-openjdk-devel -
下载并解压 MyCat
wget http://dl.mycat.org.cn/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/ -
配置环境变量
echo 'export MYCAT_HOME=/usr/local/mycat' >> /etc/profile echo 'export PATH=$PATH:$MYCAT_HOME/bin' >> /etc/profile source /etc/profile
5.2 MyCat 核心配置
MyCat 的核心配置文件位于$MYCAT_HOME/conf目录下,主要包括:
server.xml:配置 MyCat 服务、用户权限、端口等。schema.xml:配置逻辑库、逻辑表、数据节点和数据主机。rule.xml:配置分表规则。
5.2.1 配置server.xml
<user name="root">
<property name="password">Root@123</property>
<property name="schemas">TESTDB</property> <!-- 逻辑库名 -->
</user>
<user name="user">
<property name="password">User@123</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property> <!-- 只读用户 -->
</user>
5.2.2 配置schema.xml
以水平分表 为例,将user表按id取模拆分到主库和从库的两个数据库中:
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 逻辑表user,分表规则为mod-long -->
<table name="user" dataNode="dn1,dn2" rule="mod-long" />
</schema>
<!-- 数据节点,对应真实数据库 -->
<dataNode name="dn1" dataHost="localhost1" database="testdb1" />
<dataNode name="dn2" dataHost="localhost1" database="testdb2" />
<!-- 数据主机,对应MySQL实例 -->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 写节点:主库 -->
<writeHost host="hostM1" url="192.168.10.101:3306" user="root" password="Root@123">
<!-- 读节点:从库,实现读写分离 -->
<readHost host="hostS1" url="192.168.10.102:3306" user="root" password="Root@123" />
</writeHost>
</dataHost>
5.2.3 配置rule.xml
<tableRule name="mod-long">
<rule>
<columns>id</columns> <!-- 分表字段 -->
<algorithm>mod-long</algorithm> <!-- 分表算法 -->
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">2</property> <!-- 分表数量 -->
</function>
5.3 初始化分库环境
在 ** 主库(Mysql-server)** 上创建分库对应的真实数据库:
CREATE DATABASE testdb1;
CREATE DATABASE testdb2;
-- 在两个库中创建相同结构的user表
USE testdb1;
CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20));
USE testdb2;
CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20));
5.4 启动 MyCat 并验证
-
启动 MyCat 服务
mycat start -
连接 MyCat
mysql -uroot -pRoot@123 -h127.0.0.1 -P8066 # MyCat默认端口为8066 -
测试分库分表
USE TESTDB; INSERT INTO user (id, name) VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie'), (4, 'David'); -
验证数据分布
- 在主库查询
testdb1.user:id为 1、3 的数据。 - 在主库查询
testdb2.user:id为 2、4 的数据。 - 说明数据已按
id%2的规则成功拆分到两个库中。
- 在主库查询
-
测试读写分离
SELECT * FROM user; # 读请求会自动路由到从库 INSERT INTO user (id, name) VALUES (5, 'Eve'); # 写请求会路由到主库通过查看从库日志或
SHOW SLAVE STATUS,可验证读请求由从库处理,写请求由主库处理并同步到从库。
六、常见问题与解决方案
6.1 主从复制异常
-
Slave_IO_Running 为 No
- 原因:网络不通、主库账号密码错误、
MASTER_LOG_FILE或MASTER_LOG_POS配置错误。 - 解决:检查网络连通性,确认复制账号权限,重新执行
CHANGE MASTER TO。
- 原因:网络不通、主库账号密码错误、
-
Slave_SQL_Running 为 No
-
原因:从库执行 SQL 出错(如主键冲突、表不存在)。
-
解决:
STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; # 跳过1个错误事务 START SLAVE;或手动修复数据后重启复制。
-
6.2 MyCat 连接失败
-
无法连接 MyCat(8066 端口)
- 原因:防火墙未开放端口、MyCat 未启动、配置文件语法错误。
- 解决:检查防火墙规则,执行
mycat status查看状态,检查conf下 XML 文件语法。
-
分表查询无结果
- 原因:分库未创建、表结构不一致、分表规则配置错误。
- 解决:确认各分库表结构相同,检查
schema.xml和rule.xml配置。
七、总结与展望
本文详细讲解了 MySQL 主从复制与 MyCat 分库分表的核心原理与实战流程,通过搭建实验环境,实现了读写分离 与水平分表,有效解决了高并发与大数据量场景下的数据库性能瓶颈。
核心收获
- 掌握了 MySQL 主从复制的配置与故障排查方法。
- 理解了 MyCat 中间件的分库分表与读写分离机制。
- 具备了构建分布式数据库集群的实战能力。
未来展望
- 可进一步研究半同步复制、** 组复制(MGR)** 等高级复制技术,提升数据一致性。
- 结合Sharding-JDBC等其他分库分表中间件,对比不同方案的优缺点。
- 引入监控告警系统(如 Prometheus+Grafana),实现对数据库集群的可视化监控。