Skip to content

MyCat 从入门到实践全流程指南 ​

本指南将按照安装入门、基础功能测试、核心配置实践、垂直分库部署与验证、水平分表部署五大模块,针对 Linux(CentOS 7/8、Ubuntu 20.04+)和 Windows(Win10/11、Server 2019+)两大平台分别拆解操作步骤。全程以通俗易懂的表述、细致入微的操作指引完成全流程落地,所有操作均附带可直接复用的配置示例、验证命令和排错方案。

先搞懂一个概念:MyCat 是什么? MyCat 是一个开源的数据库中间件,它站在你的应用程序和 MySQL 数据库之间,充当"代理人"的角色。对应用程序来说,连接 MyCat 就像连接一台普通的 MySQL(默认端口 8066),但 MyCat 背后可以把数据分散存储到多台 MySQL 服务器上(分库分表),应用完全无感知。可以理解为:MyCat 是数据库世界的"前台接待",你只跟它打交道,它帮你把活儿分给后台一群 MySQL 去干。


模块1:MyCat 安装入门(分 Linux/Windows 版本) ​

1.1 前置环境准备(双平台通用要求) ​

MyCat 是用 Java 开发的,所以必须先装 JDK;MyCat 本身不存数据,数据最终落在 MySQL 里,所以必须有 MySQL。这两个环境没准备好,后面一切免谈。

1.1.1 JDK 环境(JDK 1.8 或 JDK 11) ​

版本要求:仅支持 JDK 1.8 或 JDK 11 这两个长期稳定版,禁止使用 JDK 17 及以上版本(高版本移除了 MyCat 依赖的部分内部 API,启动会直接报 ClassNotFoundException 或反射相关的错误)。

Linux 平台安装 JDK 1.8(以 CentOS 为例):

bash
# 方式一:yum 直接安装(推荐,省心)
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel

# Ubuntu/Debian 使用:
# apt update && apt install -y openjdk-8-jdk

# 查看 java 安装路径(下一步配置 JAVA_HOME 要用)
ls /usr/lib/jvm/
# 通常会看到类似 java-1.8.0-openjdk-1.8.0.392.b08-2.el7_9.x86_64 的目录

配置环境变量,编辑 /etc/profile:

bash
vim /etc/profile
# 在文件末尾追加以下内容(路径按你实际看到的 jvm 目录修改):
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.392.b08-2.el7_9.x86_64
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

# 保存后使配置立即生效
source /etc/profile

Windows 平台安装 JDK 1.8:

  1. 从 Oracle 官网或国内镜像下载 JDK 1.8 的 Windows x64 安装包(如 jdk-8u381-windows-x64.exe),双击一路"下一步"安装,记住安装路径(默认是 C:\Program Files\Java\jdk1.8.0_381)。
  2. 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」。
  3. 在系统变量中点击「新建」:变量名 JAVA_HOME,变量值 C:\Program Files\Java\jdk1.8.0_381(按实际路径填)。
  4. 找到系统变量 Path,点击「编辑」→「新建」,添加 %JAVA_HOME%\bin。
  5. 关闭所有已打开的 CMD 窗口(环境变量只对新开的窗口生效),重新打开 CMD 验证。

双平台验证方式(命令一致):

bash
java -version
# 正确输出示例:
# java version "1.8.0_381"
# Java(TM) SE Runtime Environment (build 1.8.0_381-b09)
# Java HotSpot(TM) 64-Bit Server VM (build 25.381-b09, mixed mode)

# Linux 下额外验证 JAVA_HOME
echo $JAVA_HOME
# Windows 下验证 JAVA_HOME
echo %JAVA_HOME%

常见坑:如果 java -version 输出了 17 或更高版本,说明系统里装了多个 JDK,需要调整 JAVA_HOME 和 Path 的顺序,把 JDK 1.8 的路径放到最前面。

1.1.2 MySQL 环境(MySQL 5.7 或 8.0) ​

  • 版本要求:MySQL 5.7 或 MySQL 8.0。注意:如果用 MySQL 8.0,其默认认证插件是 caching_sha2_password,老版本 MyCat 可能连不上,建议把 MyCat 用到的账号认证方式改成 mysql_native_password:
sql
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'mysql123';
FLUSH PRIVILEGES;
  • 提前准备物理库:为后续分片测试,提前创建至少 2 个物理数据库(可以是两台不同机器上的 MySQL,也可以是同一台机器上的两个库),分配好独立的端口、账号密码。
  • 开启远程访问:MyCat 需要通过网络连接这些 MySQL,必须确保 MySQL 允许远程连接:
sql
-- 登录每个 MySQL 节点执行
CREATE USER 'root'@'%' IDENTIFIED BY 'mysql123';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
  • 检查 MySQL 配置文件(Linux 为 /etc/my.cnf,Windows 为 my.ini),确认没有 bind-address = 127.0.0.1 这一行(有的话注释掉或改为 0.0.0.0),否则 MySQL 只监听本机,MyCat 连不上。

1.1.3 网络与端口准备 ​

MyCat 对外暴露两个端口,务必提前放行:

端口用途通俗解释
8066数据通信端口应用程序、MySQL 客户端连这个端口来执行 SQL,相当于 MyCat 的"业务窗口"
9066管理端口DBA 连这个端口来查看 MyCat 运行状态、执行管理命令,相当于"监控室"

Linux(CentOS 7/8 firewalld)放行端口:

bash
firewall-cmd --zone=public --add-port=8066/tcp --permanent
firewall-cmd --zone=public --add-port=9066/tcp --permanent
firewall-cmd --reload
# 验证
firewall-cmd --zone=public --list-ports

Ubuntu(ufw)放行端口:

bash
ufw allow 8066/tcp
ufw allow 9066/tcp
ufw reload

Windows 放行端口:「控制面板」→「Windows Defender 防火墙」→「高级设置」→「入站规则」→「新建规则」→ 选择「端口」→ TCP → 特定本地端口填 8066,9066 → 允许连接 → 全部勾选 → 命名为"MyCat 端口" → 完成。

同时确认各主机之间没有网络拦截策略(如安全组、公司内网 ACL),云服务器还要在控制台的安全组中放行 8066/9066。

1.2 Linux 平台安装步骤 ​

第 1 步:下载官方稳定版安装包

优先从官方 GitHub Releases 下载正式版,禁止使用第三方修改包(可能夹带私货或版本被魔改):

bash
# 进入临时下载目录
cd /opt

# 下载 MyCat 服务端安装包
wget https://github.com/MyCATApache/Mycat-Server/releases/download/2.0-stable/Mycat-server-2.0-stable.tar.gz

# 如果服务器无法访问 GitHub(国内常见问题),可先用本地下载再通过 scp 上传:
# scp Mycat-server-2.0-stable.tar.gz root@服务器IP:/opt/

第 2 步:解压安装包到标准路径

约定俗成把服务端软件装到 /usr/local/ 下,方便统一管理:

bash
tar -zxvf /opt/Mycat-server-2.0-stable.tar.gz -C /usr/local/

# 解压后会生成 /usr/local/mycat 目录,确认目录结构
ls /usr/local/mycat
# 正常应看到:bin  conf  lib  logs  version.txt

各目录含义:

目录作用
bin启动、停止脚本(mycat、startup.bat 等)
conf核心配置目录,schema.xml、server.xml、rule.xml 都在这里
libMyCat 运行依赖的 jar 包(含 MySQL JDBC 驱动)
logs日志目录,排错必看 wrapper.log 和 mycat.log

第 3 步:配置系统环境变量

bash
vim /etc/profile
# 在文件末尾追加:
export MYCAT_HOME=/usr/local/mycat
export PATH=$PATH:$MYCAT_HOME/bin

# 使配置生效
source /etc/profile

第 4 步:验证环境变量

bash
# 应输出 /usr/local/mycat
echo $MYCAT_HOME

# 直接输入 mycat 命令,应打印出命令帮助列表(start/stop/restart/status 等)
mycat

第 5 步:启动 MyCat 服务

bash
# 给 bin 目录下脚本加执行权限(解压后可能没有执行权限,必做)
chmod +x /usr/local/mycat/bin/*

# 后台启动
mycat start

# 查看运行状态,出现 MyCAT is running 即启动成功
mycat status

# 查看实时启动日志(排错必备),Ctrl+C 退出查看
tail -f /usr/local/mycat/logs/wrapper.log

注意:默认安装包中 lib 目录可能不含 MySQL 8.0 的 JDBC 驱动。如果物理库是 MySQL 8.0,需自行下载 mysql-connector-java-8.0.xx.jar 放入 /usr/local/mycat/lib/,并删除旧版 5.x 驱动,然后重启。

第 6 步:设置开机自启

bash
# 编辑开机自启脚本
vim /etc/rc.local
# 在文件末尾添加一行:
/usr/local/mycat/bin/mycat start

# 赋予执行权限(CentOS 7/8 默认 rc.local 没有执行权限)
chmod +x /etc/rc.d/rc.local

1.3 Windows 平台安装步骤 ​

第 1 步:下载 Windows 版安装包

从 MyCat 官方 GitHub 发布页下载 Mycat-server-2.0-stable.zip 压缩包,解压到非中文路径,例如 D:\dev\mycat。

血泪教训:绝对不要放在 桌面、新建文件夹 这类带中文或空格的路径下。MyCat 启动脚本解析路径时对中文兼容性差,会出现各种莫名其妙的文件读取异常,而且报错信息根本看不出是路径问题。

第 2 步:配置系统环境变量

  1. 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」。
  2. 在系统变量区域点击「新建」:变量名 MYCAT_HOME,变量值 D:\dev\mycat(你的实际解压根目录)。
  3. 双击系统变量 Path,点击「新建」,添加 %MYCAT_HOME%\bin。
  4. 一路点「确定」保存,重启 CMD 窗口使配置生效。

第 3 步:验证环境变量

新开 CMD 窗口执行:

bat
echo %MYCAT_HOME%
:: 应输出 D:\dev\mycat

mycat
:: 应打印 MyCat 命令帮助列表

第 4 步:启动 MyCat 服务

  • 进入 D:\dev\mycat\bin 目录,双击 startup.bat 启动服务。启动成功后会弹出一个持续运行的 CMD 窗口,滚动显示 MyCat 的启动日志,这个窗口不能关,关了服务就停了。
  • 如果出现闪退(窗口一闪而过),不要慌,打开 CMD 进入 bin 目录,用前台模式启动查看报错:
bat
cd /d D:\dev\mycat\bin
mycat console

console 模式会把所有启动日志直接打印在当前窗口,报错一目了然。闪退的常见原因:JDK 版本不对、JAVA_HOME 没配、路径含中文、8066 端口被占用。

第 5 步:设置开机自启

  1. 在 D:\dev\mycat\bin\startup.bat 上右键 →「创建快捷方式」。
  2. 按 Win + R,输入 shell:startup 回车,自动打开 Windows 的「启动」文件夹。
  3. 把刚才的快捷方式拖进这个文件夹,之后每次开机登录系统就会自动拉起 MyCat。

模块2:MyCat 基础功能测试(分 Linux/Windows 版本) ​

安装完成后必须先做基础连通性测试,验证 MyCat 核心功能正常,才能进入后续配置环节。测试顺序:先看日志 → 测本地 8066 → 测本地 9066 → 测远程连接,一步通过再进行下一步。

2.1 Linux 平台基础测试步骤 ​

第 1 步:查看启动日志排错

bash
# 服务启动异常时,第一时间看 wrapper.log(记录了 JVM 启动全过程)
tail -100 /usr/local/mycat/logs/wrapper.log

# mycat.log 记录的是 MyCat 运行时日志(SQL 路由、连接池等)
tail -100 /usr/local/mycat/logs/mycat.log

常见错误速查表:

报错关键字原因解决办法
UnsupportedClassVersionErrorJDK 版本不兼容(用了 JDK 17+)切换到 JDK 1.8/11 并修正 JAVA_HOME
Address already in use8066/9066 端口被占用netstat -tlnp | grep 8066 找到占用进程并 kill,或改 server.xml 换端口
XML Parse Exception配置文件语法错误(标签没闭合等)按报错行号检查 conf 下 XML 文件
Connection refused(连接物理库时)物理 MySQL 没启动或不允许远程连接检查 MySQL 状态、bind-address、账号权限

第 2 步:本地连通性测试(数据端口 8066)

bash
# 用标准 mysql 客户端连接 MyCat,就像连普通 MySQL 一样
mysql -uroot -p123456 -h127.0.0.1 -P8066

默认账号 root,默认密码 123456(这个账号定义在 server.xml 里,后面会讲)。成功后会看到熟悉的 MySQL 命令行提示符 mysql>,说明数据端口正常。

sql
-- 进去后可以执行一条简单 SQL 验证
show databases;
-- 会看到 schema.xml 中定义的逻辑库(默认安装通常有 TESTDB)

注意:如果你机器上 mysql 客户端是 8.0 版本,连接时可能报认证插件错误,加上 --default-auth=mysql_native_password 参数再试。

第 3 步:管理端口测试(9066)

bash
mysql -uroot -p123456 -h127.0.0.1 -P9066

进入后执行 MyCat 特有的管理命令(以 @@ 开头,这是管理端口的标志):

sql
-- 查看 MyCat 整体运行状态:版本、线程数、内存占用、启动时间等
show @@server;

-- 其他常用管理命令:
show @@datasource;   -- 查看各物理数据源连接状态
show @@help;         -- 列出所有支持的管理命令
reload @@config;     -- 不重启热加载配置(生产慎用)

能输出正常的运行参数,说明管理端口正常。

第 4 步:远程连通性测试

从另一台同网段主机执行:

bash
mysql -uroot -p123456 -h192.168.1.100 -P8066

(把 192.168.1.100 换成 MyCat 主机的实际 IP)。若连接失败,按以下顺序排查:

  1. ping 192.168.1.100 是否通 → 不通则是网络层问题;
  2. telnet 192.168.1.100 8066 是否通 → 不通则检查防火墙 8066 是否放行;
  3. 在 MyCat 主机上 netstat -tlnp | grep 8066 → 确认 MyCat 监听在 0.0.0.0:8066 而不是 127.0.0.1:8066。

2.2 Windows 平台基础测试步骤 ​

第 1 步:查看启动日志排错

启动闪退或异常时,用记事本/VS Code 打开 %MYCAT_HOME%\logs\wrapper.log 查看错误日志。常见问题:

  • JDK 环境变量未配置:日志中出现 'java' 不是内部或外部命令 → 回模块 1 检查 JAVA_HOME;
  • 路径含中文字符:日志中出现乱码路径 + FileNotFoundException → 把 MyCat 移到纯英文路径;
  • 端口被占用:日志中出现 BindException: Address already in use,执行以下命令找出"占坑"的进程:
bat
:: 查看 8066 端口被哪个进程占用(最后一列是 PID)
netstat -ano | findstr "8066"

:: 根据 PID 查看是什么程序
tasklist | findstr "进程PID"

:: 确认是无用程序后可结束它
taskkill /PID 进程PID /F

第 2 步:本地连通性测试

打开 CMD(前提是本机装了 MySQL 客户端,且 mysql.exe 已加入 Path):

bat
mysql -uroot -p123456 -h127.0.0.1 -P8066

成功进入 MySQL 命令行即说明数据端口正常。

第 3 步:管理端口测试

bat
mysql -uroot -p123456 -h127.0.0.1 -P9066

进入后执行 show @@server;,输出正常运行参数即说明管理端口可用。

第 4 步:远程连通性测试

关闭 Windows 防火墙,或按模块 1.1.3 的方法新建入站规则放行 8066/9066 端口,然后从局域网内其他主机执行:

bat
mysql -uroot -p123456 -h192.168.1.100 -P8066

能连上即全流程打通。


模块3:MyCat 核心配置详解(双平台通用配置逻辑,分平台操作路径) ​

MyCat 有三个核心配置文件,全部位于 conf 目录下:

配置文件作用通俗解释
schema.xml定义逻辑库、逻辑表、分片规则、数据节点、物理数据源MyCat 的"架构图":数据放在哪、怎么分
server.xml定义用户账号、权限、系统级参数MyCat 的"门卫室":谁能进、能干什么
rule.xml定义具体的分片算法(取模、范围、哈希等)MyCat 的"分流规则手册"

配置文件路径随平台不同:

  • Linux:/usr/local/mycat/conf/(即 $MYCAT_HOME/conf/)
  • Windows:D:\dev\mycat\conf\(即 %MYCAT_HOME%\conf\)

配置逻辑和文件内容在两个平台完全一致,只是编辑和重启方式不同。

3.1 核心配置操作步骤(分平台) ​

Linux 平台:

bash
# 进入配置目录
cd /usr/local/mycat/conf/

# 修改前先备份!这是一个值得养成的习惯
cp schema.xml schema.xml.bak.$(date +%Y%m%d)

# 使用 vim 编辑(不熟悉 vim 可用 nano,更友好)
vim schema.xml
# nano schema.xml

# 修改完成后重启使配置生效
mycat restart

# 重启后立刻看日志确认配置加载无报错
tail -50 /usr/local/mycat/logs/wrapper.log

Windows 平台:

  1. 打开 D:\dev\mycat\conf\ 目录,右键配置文件 → 用 VS Code 或 Notepad++ 打开(不推荐记事本,容易引入 BOM 头导致 XML 解析失败)。
  2. 修改保存后,在 CMD 执行 mycat restart 重启服务。
  3. 查看 %MYCAT_HOME%\logs\wrapper.log 确认无报错。

3.2 schema.xml 结构速览 ​

这是最重要的配置文件,先建立整体认知,后面模块 4、5 会给出完整实例。它的结构是四层嵌套,自顶向下:

schema(逻辑库)
 └── table(逻辑表,可指定分片规则 rule)
      └── dataNode(数据节点:逻辑概念 = 某台机器上的某个库)
           └── dataHost(物理主机:MySQL 实例的 IP、端口、账号密码)

一个最小可用骨架:

xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <!-- 逻辑库:应用看到的是这个库 -->
    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
        <!-- 逻辑表:dataNode 指向下面定义的数据节点 -->
        <table name="t_order" dataNode="dn1" />
    </schema>

    <!-- 数据节点:dn1 = localhost1 这台主机上的 db1 库 -->
    <dataNode name="dn1" dataHost="localhost1" database="db1" />

    <!-- 物理主机:真实的 MySQL 连接信息 -->
    <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
              writeType="0" dbType="mysql" dbDriver="native"
              switchType="1" slaveThreshold="100">
        <!-- 心跳检测语句:MyCat 定期用它探活后端 MySQL -->
        <heartbeat>select user()</heartbeat>
        <!-- 写节点(真实的 MySQL 地址账号) -->
        <writeHost host="hostM1" url="192.168.1.10:3306"
                   user="root" password="mysql123" />
    </dataHost>

</mycat:schema>

关键参数解释:

  • checkSQLschema="false":允许 SQL 中不带库名前缀,建议 false;
  • sqlMaxLimit="100":没写 limit 的查询自动追加 limit 100,防止全表拉爆内存;
  • balance:读写分离负载策略(0=不分离,1=读走从库,本指南用 0);
  • dbDriver="native":使用 MyCat 原生协议驱动,配合 lib 里的 JDBC jar 工作;
  • <heartbeat>:MyCat 每隔一段时间执行这条 SQL 判断后端 MySQL 是否存活,探测失败会把节点标记为不可用。

3.3 server.xml 结构速览 ​

主要关注 <user> 标签,它定义了能连接 MyCat 8066 端口的账号:

xml
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
        <!-- 系统参数区,默认即可。常用的有:
             字符集 utf8mb4、默认端口 8066、管理端口 9066 -->
        <property name="charset">utf8mb4</property>
    </system>

    <!-- 定义一个可登录 MyCat 的用户 -->
    <user name="root" defaultAccount="true">
        <property name="password">123456</property>
        <!-- 该用户可访问的逻辑库列表,多个用逗号分隔 -->
        <property name="schemas">TESTDB</property>
    </user>

    <!-- 只读用户示例:只能 select,不能写 -->
    <user name="readonly">
        <property name="password">readonly123</property>
        <property name="schemas">TESTDB</property>
        <property name="readOnly">true</property>
    </user>
</mycat:server>

划重点:连接 MyCat 用的账号密码是 server.xml 里定义的(如 root/123456),不是物理 MySQL 的账号密码;物理 MySQL 的账号密码写在 schema.xml 的 <writeHost> 里,是 MyCat 自己内部去连 MySQL 用的。两套账号不要混淆。


模块4:MyCat 垂直分库实践(含部署 + 测试验证,分 Linux/Windows 版本) ​

4.0 先理解:什么是垂直分库? ​

垂直分库 = 按业务拆分。 一个系统里,订单相关的表放一台 MySQL,用户相关的表放另一台 MySQL,各管各的。就像一个大商场分成了"服装区"和"餐饮区",MyCat 是商场总服务台,你问它任何问题,它把你指引到正确的分区。

应用
  │ (连接 8066)
  ▼
MyCat(逻辑库 myshop)
  ├── t_order、t_order_item ──► 节点1: db_order (192.168.1.10)
  └── t_user、t_user_addr  ──► 节点2: db_user  (192.168.1.11)

优点:业务解耦、单个库压力下降;代价:跨库的 JOIN 和分布式事务受限(订单表不能直接 JOIN 用户表,需要在应用层处理)。

4.1 前置准备(双平台通用) ​

准备两个物理 MySQL 实例(也可退化为同一实例下的两个库,测试足够):

节点IP端口数据库账号密码
节点1192.168.1.103306db_orderrootmysql123
节点2192.168.1.113306db_userrootmysql123

在两个节点上分别执行初始化:

sql
-- 节点1 (192.168.1.10) 上执行:
CREATE DATABASE IF NOT EXISTS db_order DEFAULT CHARACTER SET utf8mb4;

-- 节点2 (192.168.1.11) 上执行:
CREATE DATABASE IF NOT EXISTS db_user DEFAULT CHARACTER SET utf8mb4;

-- 两个节点都要确保 MyCat 主机可以远程访问(参考模块 1.1.2)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'mysql123';
FLUSH PRIVILEGES;

在 MyCat 主机上先验证到两个节点的网络连通性:

bash
# Linux
mysql -uroot -pmysql123 -h192.168.1.10 -P3306 -e "select 1;"
mysql -uroot -pmysql123 -h192.168.1.11 -P3306 -e "select 1;"

# Windows CMD 同理
mysql -uroot -pmysql123 -h192.168.1.10 -P3306 -e "select 1;"

两条都返回 1 才可以继续,否则先解决网络/权限问题。

4.2 Linux 平台垂直分库部署 + 测试步骤 ​

第 1 步:编辑 schema.xml

bash
cd /usr/local/mycat/conf/
cp schema.xml schema.xml.bak
vim schema.xml

写入如下完整配置(垂直分库场景不需要 rule.xml,因为每张表整体放一个节点,没有"拆分规则"):

xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <!-- 逻辑库 myshop:应用连接后看到的就是这个库 -->
    <schema name="myshop" checkSQLschema="false" sqlMaxLimit="100">
        <!-- 订单表整体放在 dn_order 节点 -->
        <table name="t_order" dataNode="dn_order" />
        <!-- 用户表整体放在 dn_user 节点 -->
        <table name="t_user" dataNode="dn_user" />
    </schema>

    <!-- 数据节点定义 -->
    <dataNode name="dn_order" dataHost="host_order" database="db_order" />
    <dataNode name="dn_user"  dataHost="host_user"  database="db_user" />

    <!-- 物理主机1:订单库所在机器 -->
    <dataHost name="host_order" maxCon="1000" minCon="10" balance="0"
              writeType="0" dbType="mysql" dbDriver="native"
              switchType="1" slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="orderM1" url="192.168.1.10:3306"
                   user="root" password="mysql123" />
    </dataHost>

    <!-- 物理主机2:用户库所在机器 -->
    <dataHost name="host_user" maxCon="1000" minCon="10" balance="0"
              writeType="0" dbType="mysql" dbDriver="native"
              switchType="1" slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="userM1" url="192.168.1.11:3306"
                   user="root" password="mysql123" />
    </dataHost>

</mycat:schema>

vim 小技巧:如果原文件里有大段注释和默认配置,可先按 gg 跳到行首,再按 dG 清空全文,然后按 i 进入插入模式粘贴上面的内容,最后按 Esc 输入 :wq 保存退出。

第 2 步:编辑 server.xml,添加访问用户

bash
vim /usr/local/mycat/conf/server.xml

确保存在这样一个用户(schemas 改成我们的逻辑库 myshop):

xml
<user name="root" defaultAccount="true">
    <property name="password">123456</property>
    <property name="schemas">myshop</property>
</user>

第 3 步:重启 MyCat 并确认配置加载成功

bash
mycat restart

# 紧盯日志,出现 successfully 且无 ERROR 才算成功
tail -f /usr/local/mycat/logs/wrapper.log

如果日志报 XML 解析错误,按提示的行号回去检查 schema.xml(最常见的是标签没闭合、属性少了引号)。

第 4 步:连接 MyCat 创建测试表

bash
mysql -uroot -p123456 -h127.0.0.1 -P8066
sql
-- 进入逻辑库
use myshop;

-- 建订单表:MyCat 会把这条 DDL 路由到 dn_order(192.168.1.10 的 db_order)
CREATE TABLE t_order(
    id INT PRIMARY KEY,
    order_sn VARCHAR(64)
);

-- 建用户表:路由到 dn_user(192.168.1.11 的 db_user)
CREATE TABLE t_user(
    id INT PRIMARY KEY,
    username VARCHAR(64)
);

-- 在 MyCat 视角下查看,两张表都"在" myshop 里
show tables;

第 5 步:验证分库结果(关键一步)

分别登录两个物理节点确认表落在了正确的位置:

bash
# 登录节点1查看:应该能看到 t_order
mysql -uroot -pmysql123 -h192.168.1.10 -e "show tables in db_order;"
# 输出:t_order

# 登录节点2查看:应该能看到 t_user
mysql -uroot -pmysql123 -h192.168.1.11 -e "show tables in db_user;"
# 输出:t_user

两边各只有属于自己的那张表,说明垂直分库生效。

第 6 步:业务读写测试

回到 MyCat 连接(8066 端口):

sql
use myshop;

-- 插入数据:MyCat 根据表名自动路由
INSERT INTO t_order(id, order_sn) VALUES (1, 'SN20260905001'), (2, 'SN20260905002');
INSERT INTO t_user(id, username) VALUES (1001, 'zhangsan'), (1002, 'lisi');

-- 查询验证
SELECT * FROM t_order;
SELECT * FROM t_user;

再到物理节点上反向确认数据确实写对了地方:

bash
mysql -uroot -pmysql123 -h192.168.1.10 -e "select * from db_order.t_order;"
mysql -uroot -pmysql123 -h192.168.1.11 -e "select * from db_user.t_user;"

数据各归其位、读写无异常,垂直分库实践完成。

4.3 Windows 平台垂直分库部署 + 测试步骤 ​

第 1 步:编辑配置文件

进入 D:\dev\mycat\conf\,用 VS Code 打开 schema.xml 和 server.xml,写入与 4.2 节完全一致的配置内容(配置本身与平台无关)。保存时注意编码选择 UTF-8(无 BOM)。

唯一的注意点:确认两个物理节点 IP(192.168.1.10 / 192.168.1.11)在 Windows 主机的网络下可以连通,先用 ping 和 mysql 客户端测一遍。

第 2 步:重启服务

bat
cd /d D:\dev\mycat\bin
mycat restart

查看 %MYCAT_HOME%\logs\wrapper.log 确认配置加载无 ERROR。

第 3 步:执行与 Linux 完全一致的测试

用 mysql 客户端连接 127.0.0.1:8066,依次执行 4.2 节第 4~6 步的建表、插入、查询 SQL,再分别登录两个物理节点验证表和数据都落位正确。全部通过即说明 Windows 平台垂直分库部署成功。


模块5:MyCat 水平分表实践(分 Linux/Windows 版本) ​

5.0 先理解:什么是水平分表? ​

水平分表 = 同一张表按行拆。 一张 t_order 表数据量到了几千万行,单库扛不住了,就把它按某种规则(如 id 取模)拆成多份,分散到多个节点上。每个节点上的表结构一模一样,只是存的行不同。就像一个班级 50 人分成两组,每组花名册格式相同,各记一半人的名字。

应用 INSERT t_order(id=1) ──┐
应用 INSERT t_order(id=2) ──┤
                            ▼
                    MyCat(计算 id % 2)
                       ├── 余数1 ──► 节点1 db01.t_order(存 id=1)
                       └── 余数0 ──► 节点2 db02.t_order(存 id=2)

查询 SELECT * FROM t_order 时,MyCat 会同时问所有节点要数据,然后把结果合并后返回给你,你看到的好像还是一张完整的表——这就是 MyCat 的"结果聚合"能力。

5.1 前置准备(双平台通用) ​

准备两个物理 MySQL 节点。注意:与垂直分库不同,水平分表要求提前在每个节点上手动建好表结构(MyCat 1.x 的 DDL 路由对分片表支持不完善,最稳妥的方式就是先建好):

sql
-- 节点1 (192.168.1.10) 执行:
CREATE DATABASE IF NOT EXISTS db01 DEFAULT CHARACTER SET utf8mb4;
USE db01;
CREATE TABLE t_order(
    id BIGINT PRIMARY KEY,
    order_sn VARCHAR(64),
    amount DECIMAL(10,2)
);

-- 节点2 (192.168.1.11) 执行:
CREATE DATABASE IF NOT EXISTS db02 DEFAULT CHARACTER SET utf8mb4;
USE db02;
CREATE TABLE t_order(
    id BIGINT PRIMARY KEY,
    order_sn VARCHAR(64),
    amount DECIMAL(10,2)
);

两个节点的 t_order 结构必须完全一致,否则查询聚合时会报列不匹配的错。

5.2 Linux 平台水平分表部署步骤 ​

第 1 步:编辑 schema.xml,配置逻辑表与分片规则

bash
vim /usr/local/mycat/conf/schema.xml
xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <schema name="myshop" checkSQLschema="false" sqlMaxLimit="100">
        <!--
            t_order 是分片表:
            dataNode 列出所有承载节点(逗号分隔)
            rule="mod-long" 指定分片规则名(规则定义在 rule.xml)
        -->
        <table name="t_order" dataNode="dn1,dn2" rule="mod-long" />
    </schema>

    <!-- 两个数据节点 -->
    <dataNode name="dn1" dataHost="host1" database="db01" />
    <dataNode name="dn2" dataHost="host2" database="db02" />

    <!-- 物理节点1 -->
    <dataHost name="host1" maxCon="1000" minCon="10" balance="0"
              writeType="0" dbType="mysql" dbDriver="native"
              switchType="1" slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="nodeM1" url="192.168.1.10:3306"
                   user="root" password="mysql123" />
    </dataHost>

    <!-- 物理节点2 -->
    <dataHost name="host2" maxCon="1000" minCon="10" balance="0"
              writeType="0" dbType="mysql" dbDriver="native"
              switchType="1" slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <writeHost host="nodeM2" url="192.168.1.11:3306"
                   user="root" password="mysql123" />
    </dataHost>

</mycat:schema>

第 2 步:编辑 rule.xml,确认分片算法

rule.xml 里每条规则由两部分组成:<tableRule>(声明规则名、分片列、算法)和 <function>(算法的具体实现和参数)。

bash
vim /usr/local/mycat/conf/rule.xml

确认(或添加)如下配置:

xml
<!-- 规则声明:名字叫 mod-long,按 id 列分片,使用 mod-long 算法 -->
<tableRule name="mod-long">
    <rule>
        <columns>id</columns>
        <algorithm>mod-long</algorithm>
    </rule>
</tableRule>

<!-- 算法实现:对 id 做取模运算,模数 = 节点数量 -->
<function name="mod-long"
          class="io.mycat.route.function.PartitionByMod">
    <!-- 分片数量,必须和 dataNode 的实际节点数一致!我们是 dn1,dn2 两个节点,所以是 2 -->
    <property name="count">2</property>
</function>

最容易踩的坑:count 的值必须与该表 dataNode 的节点个数严格一致。比如 count 写 3 但只配了 2 个节点,余数为 2 的数据将无处安放,插入直接报错。

取模路由逻辑(帮助理解数据会去哪):插入 id=1 时,1 % 2 = 1 → 去 dn1;插入 id=2 时,2 % 2 = 0 → 余数 0 去第一个节点 dn1?—— 注意 MyCat 的 PartitionByMod 实现是 id % count 的结果直接作为节点下标(0 对应 dn1,1 对应 dn2)。即:

idid % 2落点
11dn2(db02)
20dn1(db01)

第 3 步:重启并确认配置加载

bash
mycat restart
tail -f /usr/local/mycat/logs/wrapper.log
# 无 ERROR,看到 schema 加载成功即可

第 4 步:水平分表插入测试

bash
mysql -uroot -p123456 -h127.0.0.1 -P8066
sql
use myshop;

-- 插入两条测试数据,按取模规则会分别落到不同节点
INSERT INTO t_order(id, order_sn, amount) VALUES (1, 'SN001', 99.50);
INSERT INTO t_order(id, order_sn, amount) VALUES (2, 'SN002', 188.00);

-- 多插几组观察规律
INSERT INTO t_order(id, order_sn, amount) VALUES (3, 'SN003', 20.00);
INSERT INTO t_order(id, order_sn, amount) VALUES (4, 'SN004', 66.66);

第 5 步:验证分片结果

分别登录两个物理节点查看数据分布:

bash
mysql -uroot -pmysql123 -h192.168.1.10 -e "select * from db01.t_order;"
# 预期:id 为偶数的行(2, 4),即 id%2=0 的数据

mysql -uroot -pmysql123 -h192.168.1.11 -e "select * from db02.t_order;"
# 预期:id 为奇数的行(1, 3),即 id%2=1 的数据

数据按取模规则各就各位,说明分片路由生效。

第 6 步:全表查询与聚合测试(MyCat 的"魔法时刻")

回到 MyCat 连接:

sql
use myshop;

-- 全表查询:MyCat 自动向两个节点发起查询并合并结果
SELECT * FROM t_order;
-- 应返回全部 4 条数据(顺序可能和插入顺序不同,属正常现象)

-- 带分片键的条件查询:MyCat 能算出 id=1 只可能在 dn2,直接路由,不打扰 dn1
SELECT * FROM t_order WHERE id = 1;

-- 非分片键条件查询:MyCat 会广播到所有节点再合并(性能较差,生产环境避免)
SELECT * FROM t_order WHERE order_sn = 'SN003';

-- 聚合函数测试
SELECT COUNT(*) FROM t_order;      -- 预期 4(两个节点 count 结果相加)
SELECT SUM(amount) FROM t_order;   -- MyCat 自动把各节点结果聚合

生产建议:查询条件尽量带上分片键(本例是 id),MyCat 才能精准路由到单个节点;不带分片键的查询会广播到所有节点,节点越多性能越差。

5.3 Windows 平台水平分表部署步骤 ​

第 1 步:编辑配置文件

用 VS Code 打开 D:\dev\mycat\conf\schema.xml 和 rule.xml,写入与 5.2 节完全一致的内容,保存为 UTF-8 无 BOM 编码。先确认 Windows 主机到两个物理节点(192.168.1.10 / 192.168.1.11)的网络连通性。

第 2 步:重启服务

bat
cd /d D:\dev\mycat\bin
mycat restart

查看 wrapper.log 确认配置加载正常。

第 3 步:执行相同测试

连接 127.0.0.1:8066,执行 5.2 节第 4~6 步的全部 SQL:

  • 插入 id=1、2、3、4 的测试数据;
  • 登录两个物理节点确认奇偶 id 分别落在 db01 / db02;
  • 在 MyCat 中执行全表查询、条件查询、聚合查询,验证结果完整、无数据丢失、无查询异常。

全部通过,水平分表实践完成。


附录:常见问题速查(FAQ) ​

问题现象可能原因解决方案
启动报 Unsupported major.minor versionJDK 版本不符切换 JDK 1.8/11,修正 JAVA_HOME
8066 能连但 SQL 报 Can't find table表未在 schema.xml 声明在对应 schema 下添加 <table> 配置
插入分片表报 can't find datanoderule.xml 中 count 与节点数不符修改 count 使之等于 dataNode 节点数
连物理库报 Access denied物理 MySQL 账号无远程权限执行 GRANT ... TO 'root'@'%' 授权
MySQL 8.0 物理库连不上认证插件不兼容 / JDBC 驱动过旧账号改为 mysql_native_password;替换 lib 下驱动为 8.0 版本
查分片表结果缺数据某个节点心跳失败被摘除管理端口执行 show @@datasource 检查节点状态
配置改了不生效没重启或 XML 语法错导致加载失败mycat restart 并检查 wrapper.log
Windows 启动闪退路径含中文 / JDK 未配置移纯英文路径;用 mycat console 看具体报错
中文插入乱码字符集不统一server.xml 设 charset=utf8mb4,物理库也建为 utf8mb4

至此,MyCat 从安装入门、基础测试、核心配置,到垂直分库与水平分表两大核心场景的完整实践流程全部完成。建议学习路径:先在单机用两个库模拟两个节点跑通全流程,再扩展到真实多机环境。