MySQL 主从复制与 MyCat 分库分表实战详解

一、引言

在当今互联网高并发、大数据量的业务场景下,单一 MySQL 实例已无法满足性能与可用性需求。主从复制 实现了数据读写分离与高可用,MyCat 分库分表则突破了单表数据量的存储瓶颈,二者结合是构建大型分布式数据库系统的经典方案。

本文将从原理、环境搭建、实战配置到效果验证,完整讲解 MySQL 主从复制与 MyCat 分库分表的实现流程,帮助开发者快速掌握这一核心技术。


二、核心原理剖析

2.1 MySQL 主从复制原理

MySQL 主从复制(Master-Slave Replication)是基于 ** 二进制日志(Binary Log)** 实现的异步数据同步机制,核心流程如下:

  1. 主库(Master):当执行 INSERT/UPDATE/DELETE 等写操作时,会将数据变更记录到二进制日志(Binary Log)中。
  2. 从库(Slave) :通过 I/O 线程连接主库,请求获取指定位置之后的二进制日志,并写入本地中继日志(Relay Log)
  3. 从库(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 基础环境配置

  1. 关闭防火墙与 SELinux

    复制代码
    systemctl stop firewalld
    systemctl disable firewalld
    setenforce 0
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
  2. 配置主机名与 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
  3. 同步系统时间

    复制代码
    yum install -y ntpdate
    ntpdate cn.pool.ntp.org

四、MySQL 主从复制实战

4.1 安装 MySQL 5.7.36

在 ** 主库(Mysql-server)从库(Slave-server)** 上执行相同安装步骤:

  1. 下载并安装 MySQL YUM 源

    复制代码
    wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
    rpm -ivh mysql57-community-release-el7-11.noarch.rpm
  2. 安装 MySQL 服务

    复制代码
    yum install -y mysql-community-server
  3. 启动 MySQL 并设置开机自启

    复制代码
    systemctl start mysqld
    systemctl enable mysqld
  4. 获取初始密码并修改

    复制代码
    grep 'temporary password' /var/log/mysqld.log
    mysql -uroot -p
    ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@123';

4.2 配置主库(Master)

  1. 编辑 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天
  2. 重启 MySQL 服务

    复制代码
    systemctl restart mysqld
  3. 创建用于复制的账号

    复制代码
    GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.10.%' IDENTIFIED BY 'Repl@123';
    FLUSH PRIVILEGES;
  4. 查看主库状态

    复制代码
    SHOW MASTER STATUS;

    记录下File(如mysql-bin.000001)和Position(如154),后续从库配置需要用到。

4.3 配置从库(Slave)

  1. 编辑 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  # 设置从库为只读(可选,保证数据一致性)
  2. 重启 MySQL 服务

    复制代码
    systemctl restart mysqld
  3. 配置主从同步

    复制代码
    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结果
  4. 启动从库复制线程

    复制代码
    START SLAVE;
  5. 验证主从状态

    复制代码
    SHOW SLAVE STATUS\G

    Slave_IO_RunningSlave_SQL_Running均为Yes,则表示主从复制配置成功。

4.4 主从复制效果验证

  1. 在主库创建测试数据库和表

    复制代码
    CREATE DATABASE testdb;
    USE testdb;
    CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20));
    INSERT INTO user (name) VALUES ('Tom'), ('Jerry');
  2. 在从库查询验证

    复制代码
    USE testdb;
    SELECT * FROM user;

    若能查询到主库插入的数据,则说明主从复制生效。


五、MyCat 分库分表实战

5.1 安装 MyCat

Mycat-server节点上执行安装步骤:

  1. 安装 JDK 8

    复制代码
    yum install -y java-1.8.0-openjdk-devel
  2. 下载并解压 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/
  3. 配置环境变量

    复制代码
    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 并验证

  1. 启动 MyCat 服务

    复制代码
    mycat start
  2. 连接 MyCat

    复制代码
    mysql -uroot -pRoot@123 -h127.0.0.1 -P8066  # MyCat默认端口为8066
  3. 测试分库分表

    复制代码
    USE TESTDB;
    INSERT INTO user (id, name) VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie'), (4, 'David');
  4. 验证数据分布

    • 在主库查询testdb1.userid为 1、3 的数据。
    • 在主库查询testdb2.userid为 2、4 的数据。
    • 说明数据已按id%2的规则成功拆分到两个库中。
  5. 测试读写分离

    复制代码
    SELECT * FROM user;  # 读请求会自动路由到从库
    INSERT INTO user (id, name) VALUES (5, 'Eve');  # 写请求会路由到主库

    通过查看从库日志或SHOW SLAVE STATUS,可验证读请求由从库处理,写请求由主库处理并同步到从库。


六、常见问题与解决方案

6.1 主从复制异常

  1. Slave_IO_Running 为 No

    • 原因:网络不通、主库账号密码错误、MASTER_LOG_FILEMASTER_LOG_POS配置错误。
    • 解决:检查网络连通性,确认复制账号权限,重新执行CHANGE MASTER TO
  2. Slave_SQL_Running 为 No

    • 原因:从库执行 SQL 出错(如主键冲突、表不存在)。

    • 解决:

      复制代码
      STOP SLAVE;
      SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;  # 跳过1个错误事务
      START SLAVE;

      或手动修复数据后重启复制。

6.2 MyCat 连接失败

  1. 无法连接 MyCat(8066 端口)

    • 原因:防火墙未开放端口、MyCat 未启动、配置文件语法错误。
    • 解决:检查防火墙规则,执行mycat status查看状态,检查conf下 XML 文件语法。
  2. 分表查询无结果

    • 原因:分库未创建、表结构不一致、分表规则配置错误。
    • 解决:确认各分库表结构相同,检查schema.xmlrule.xml配置。

七、总结与展望

本文详细讲解了 MySQL 主从复制与 MyCat 分库分表的核心原理与实战流程,通过搭建实验环境,实现了读写分离水平分表,有效解决了高并发与大数据量场景下的数据库性能瓶颈。

核心收获

  • 掌握了 MySQL 主从复制的配置与故障排查方法。
  • 理解了 MyCat 中间件的分库分表与读写分离机制。
  • 具备了构建分布式数据库集群的实战能力。

未来展望

  • 可进一步研究半同步复制、** 组复制(MGR)** 等高级复制技术,提升数据一致性。
  • 结合Sharding-JDBC等其他分库分表中间件,对比不同方案的优缺点。
  • 引入监控告警系统(如 Prometheus+Grafana),实现对数据库集群的可视化监控。
相关推荐
eRTE XFUN2 小时前
Redis 设置密码(配置文件、docker容器、命令行3种场景)
数据库·redis·docker
Lhan.zzZ2 小时前
Qt开发踩坑:QList越界问题导致程序崩溃
数据库·c++·qt
8Qi82 小时前
Redis哨兵模式(Sentinel)深度解析
java·数据库·redis·分布式·缓存·sentinel
数据库小组2 小时前
从业务库到实时分析库,NineData 构建 MySQL 到 SelectDB 同步链路
数据库·mysql·数据库管理工具·数据同步·ninedata·数据库迁移·selectdb
CDN3602 小时前
CDN HTTPS 证书配置失败?SSL 部署与域名绑定常见问题
数据库·https·ssl
Chengbei112 小时前
一次比较简单的360加固APP脱壳渗透
网络·数据库·web安全·网络安全·系统安全·网络攻击模型·安全架构
寒秋花开曾相惜2 小时前
(学习笔记)3.9 异质的数据结构(3.9.1 结构)
c语言·网络·数据结构·数据库·笔记·学习
mcooiedo3 小时前
mybatisPlus打印sql配置
数据库·sql
wudl55663 小时前
MySQL 8.0.42 Docker 开发部署手册
数据库·mysql·docker