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 为例):
# 方式一: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:
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/profileWindows 平台安装 JDK 1.8:
- 从 Oracle 官网或国内镜像下载 JDK 1.8 的 Windows x64 安装包(如
jdk-8u381-windows-x64.exe),双击一路"下一步"安装,记住安装路径(默认是C:\Program Files\Java\jdk1.8.0_381)。 - 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」。
- 在系统变量中点击「新建」:变量名
JAVA_HOME,变量值C:\Program Files\Java\jdk1.8.0_381(按实际路径填)。 - 找到系统变量
Path,点击「编辑」→「新建」,添加%JAVA_HOME%\bin。 - 关闭所有已打开的 CMD 窗口(环境变量只对新开的窗口生效),重新打开 CMD 验证。
双平台验证方式(命令一致):
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:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'mysql123';
FLUSH PRIVILEGES;- 提前准备物理库:为后续分片测试,提前创建至少 2 个物理数据库(可以是两台不同机器上的 MySQL,也可以是同一台机器上的两个库),分配好独立的端口、账号密码。
- 开启远程访问:MyCat 需要通过网络连接这些 MySQL,必须确保 MySQL 允许远程连接:
-- 登录每个 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)放行端口:
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-portsUbuntu(ufw)放行端口:
ufw allow 8066/tcp
ufw allow 9066/tcp
ufw reloadWindows 放行端口:「控制面板」→「Windows Defender 防火墙」→「高级设置」→「入站规则」→「新建规则」→ 选择「端口」→ TCP → 特定本地端口填 8066,9066 → 允许连接 → 全部勾选 → 命名为"MyCat 端口" → 完成。
同时确认各主机之间没有网络拦截策略(如安全组、公司内网 ACL),云服务器还要在控制台的安全组中放行 8066/9066。
1.2 Linux 平台安装步骤
第 1 步:下载官方稳定版安装包
优先从官方 GitHub Releases 下载正式版,禁止使用第三方修改包(可能夹带私货或版本被魔改):
# 进入临时下载目录
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/ 下,方便统一管理:
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 都在这里 |
lib | MyCat 运行依赖的 jar 包(含 MySQL JDBC 驱动) |
logs | 日志目录,排错必看 wrapper.log 和 mycat.log |
第 3 步:配置系统环境变量
vim /etc/profile
# 在文件末尾追加:
export MYCAT_HOME=/usr/local/mycat
export PATH=$PATH:$MYCAT_HOME/bin
# 使配置生效
source /etc/profile第 4 步:验证环境变量
# 应输出 /usr/local/mycat
echo $MYCAT_HOME
# 直接输入 mycat 命令,应打印出命令帮助列表(start/stop/restart/status 等)
mycat第 5 步:启动 MyCat 服务
# 给 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 步:设置开机自启
# 编辑开机自启脚本
vim /etc/rc.local
# 在文件末尾添加一行:
/usr/local/mycat/bin/mycat start
# 赋予执行权限(CentOS 7/8 默认 rc.local 没有执行权限)
chmod +x /etc/rc.d/rc.local1.3 Windows 平台安装步骤
第 1 步:下载 Windows 版安装包
从 MyCat 官方 GitHub 发布页下载 Mycat-server-2.0-stable.zip 压缩包,解压到非中文路径,例如 D:\dev\mycat。
血泪教训:绝对不要放在
桌面、新建文件夹这类带中文或空格的路径下。MyCat 启动脚本解析路径时对中文兼容性差,会出现各种莫名其妙的文件读取异常,而且报错信息根本看不出是路径问题。
第 2 步:配置系统环境变量
- 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」。
- 在系统变量区域点击「新建」:变量名
MYCAT_HOME,变量值D:\dev\mycat(你的实际解压根目录)。 - 双击系统变量
Path,点击「新建」,添加%MYCAT_HOME%\bin。 - 一路点「确定」保存,重启 CMD 窗口使配置生效。
第 3 步:验证环境变量
新开 CMD 窗口执行:
echo %MYCAT_HOME%
:: 应输出 D:\dev\mycat
mycat
:: 应打印 MyCat 命令帮助列表第 4 步:启动 MyCat 服务
- 进入
D:\dev\mycat\bin目录,双击startup.bat启动服务。启动成功后会弹出一个持续运行的 CMD 窗口,滚动显示 MyCat 的启动日志,这个窗口不能关,关了服务就停了。 - 如果出现闪退(窗口一闪而过),不要慌,打开 CMD 进入 bin 目录,用前台模式启动查看报错:
cd /d D:\dev\mycat\bin
mycat consoleconsole 模式会把所有启动日志直接打印在当前窗口,报错一目了然。闪退的常见原因:JDK 版本不对、JAVA_HOME 没配、路径含中文、8066 端口被占用。
第 5 步:设置开机自启
- 在
D:\dev\mycat\bin\startup.bat上右键 →「创建快捷方式」。 - 按
Win + R,输入shell:startup回车,自动打开 Windows 的「启动」文件夹。 - 把刚才的快捷方式拖进这个文件夹,之后每次开机登录系统就会自动拉起 MyCat。
模块2:MyCat 基础功能测试(分 Linux/Windows 版本)
安装完成后必须先做基础连通性测试,验证 MyCat 核心功能正常,才能进入后续配置环节。测试顺序:先看日志 → 测本地 8066 → 测本地 9066 → 测远程连接,一步通过再进行下一步。
2.1 Linux 平台基础测试步骤
第 1 步:查看启动日志排错
# 服务启动异常时,第一时间看 wrapper.log(记录了 JVM 启动全过程)
tail -100 /usr/local/mycat/logs/wrapper.log
# mycat.log 记录的是 MyCat 运行时日志(SQL 路由、连接池等)
tail -100 /usr/local/mycat/logs/mycat.log常见错误速查表:
| 报错关键字 | 原因 | 解决办法 |
|---|---|---|
UnsupportedClassVersionError | JDK 版本不兼容(用了 JDK 17+) | 切换到 JDK 1.8/11 并修正 JAVA_HOME |
Address already in use | 8066/9066 端口被占用 | netstat -tlnp | grep 8066 找到占用进程并 kill,或改 server.xml 换端口 |
XML Parse Exception | 配置文件语法错误(标签没闭合等) | 按报错行号检查 conf 下 XML 文件 |
Connection refused(连接物理库时) | 物理 MySQL 没启动或不允许远程连接 | 检查 MySQL 状态、bind-address、账号权限 |
第 2 步:本地连通性测试(数据端口 8066)
# 用标准 mysql 客户端连接 MyCat,就像连普通 MySQL 一样
mysql -uroot -p123456 -h127.0.0.1 -P8066默认账号 root,默认密码 123456(这个账号定义在 server.xml 里,后面会讲)。成功后会看到熟悉的 MySQL 命令行提示符 mysql>,说明数据端口正常。
-- 进去后可以执行一条简单 SQL 验证
show databases;
-- 会看到 schema.xml 中定义的逻辑库(默认安装通常有 TESTDB)注意:如果你机器上 mysql 客户端是 8.0 版本,连接时可能报认证插件错误,加上
--default-auth=mysql_native_password参数再试。
第 3 步:管理端口测试(9066)
mysql -uroot -p123456 -h127.0.0.1 -P9066进入后执行 MyCat 特有的管理命令(以 @@ 开头,这是管理端口的标志):
-- 查看 MyCat 整体运行状态:版本、线程数、内存占用、启动时间等
show @@server;
-- 其他常用管理命令:
show @@datasource; -- 查看各物理数据源连接状态
show @@help; -- 列出所有支持的管理命令
reload @@config; -- 不重启热加载配置(生产慎用)能输出正常的运行参数,说明管理端口正常。
第 4 步:远程连通性测试
从另一台同网段主机执行:
mysql -uroot -p123456 -h192.168.1.100 -P8066(把 192.168.1.100 换成 MyCat 主机的实际 IP)。若连接失败,按以下顺序排查:
ping 192.168.1.100是否通 → 不通则是网络层问题;telnet 192.168.1.100 8066是否通 → 不通则检查防火墙 8066 是否放行;- 在 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,执行以下命令找出"占坑"的进程:
:: 查看 8066 端口被哪个进程占用(最后一列是 PID)
netstat -ano | findstr "8066"
:: 根据 PID 查看是什么程序
tasklist | findstr "进程PID"
:: 确认是无用程序后可结束它
taskkill /PID 进程PID /F第 2 步:本地连通性测试
打开 CMD(前提是本机装了 MySQL 客户端,且 mysql.exe 已加入 Path):
mysql -uroot -p123456 -h127.0.0.1 -P8066成功进入 MySQL 命令行即说明数据端口正常。
第 3 步:管理端口测试
mysql -uroot -p123456 -h127.0.0.1 -P9066进入后执行 show @@server;,输出正常运行参数即说明管理端口可用。
第 4 步:远程连通性测试
关闭 Windows 防火墙,或按模块 1.1.3 的方法新建入站规则放行 8066/9066 端口,然后从局域网内其他主机执行:
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 平台:
# 进入配置目录
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.logWindows 平台:
- 打开
D:\dev\mycat\conf\目录,右键配置文件 → 用 VS Code 或 Notepad++ 打开(不推荐记事本,容易引入 BOM 头导致 XML 解析失败)。 - 修改保存后,在 CMD 执行
mycat restart重启服务。 - 查看
%MYCAT_HOME%\logs\wrapper.log确认无报错。
3.2 schema.xml 结构速览
这是最重要的配置文件,先建立整体认知,后面模块 4、5 会给出完整实例。它的结构是四层嵌套,自顶向下:
schema(逻辑库)
└── table(逻辑表,可指定分片规则 rule)
└── dataNode(数据节点:逻辑概念 = 某台机器上的某个库)
└── dataHost(物理主机:MySQL 实例的 IP、端口、账号密码)一个最小可用骨架:
<?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 端口的账号:
<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 | 端口 | 数据库 | 账号 | 密码 |
|---|---|---|---|---|---|
| 节点1 | 192.168.1.10 | 3306 | db_order | root | mysql123 |
| 节点2 | 192.168.1.11 | 3306 | db_user | root | mysql123 |
在两个节点上分别执行初始化:
-- 节点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 主机上先验证到两个节点的网络连通性:
# 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
cd /usr/local/mycat/conf/
cp schema.xml schema.xml.bak
vim schema.xml写入如下完整配置(垂直分库场景不需要 rule.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,添加访问用户
vim /usr/local/mycat/conf/server.xml确保存在这样一个用户(schemas 改成我们的逻辑库 myshop):
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">myshop</property>
</user>第 3 步:重启 MyCat 并确认配置加载成功
mycat restart
# 紧盯日志,出现 successfully 且无 ERROR 才算成功
tail -f /usr/local/mycat/logs/wrapper.log如果日志报 XML 解析错误,按提示的行号回去检查 schema.xml(最常见的是标签没闭合、属性少了引号)。
第 4 步:连接 MyCat 创建测试表
mysql -uroot -p123456 -h127.0.0.1 -P8066-- 进入逻辑库
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 步:验证分库结果(关键一步)
分别登录两个物理节点确认表落在了正确的位置:
# 登录节点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 端口):
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;再到物理节点上反向确认数据确实写对了地方:
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 步:重启服务
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 路由对分片表支持不完善,最稳妥的方式就是先建好):
-- 节点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,配置逻辑表与分片规则
vim /usr/local/mycat/conf/schema.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>(算法的具体实现和参数)。
vim /usr/local/mycat/conf/rule.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)。即:
| id | id % 2 | 落点 |
|---|---|---|
| 1 | 1 | dn2(db02) |
| 2 | 0 | dn1(db01) |
第 3 步:重启并确认配置加载
mycat restart
tail -f /usr/local/mycat/logs/wrapper.log
# 无 ERROR,看到 schema 加载成功即可第 4 步:水平分表插入测试
mysql -uroot -p123456 -h127.0.0.1 -P8066use 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 步:验证分片结果
分别登录两个物理节点查看数据分布:
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 连接:
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 步:重启服务
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 version | JDK 版本不符 | 切换 JDK 1.8/11,修正 JAVA_HOME |
8066 能连但 SQL 报 Can't find table | 表未在 schema.xml 声明 | 在对应 schema 下添加 <table> 配置 |
插入分片表报 can't find datanode | rule.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 从安装入门、基础测试、核心配置,到垂直分库与水平分表两大核心场景的完整实践流程全部完成。建议学习路径:先在单机用两个库模拟两个节点跑通全流程,再扩展到真实多机环境。