ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Windows 10 下安装启动 MyCAT:分库分表中间件实战入门

Windows 10 下安装启动 MyCAT:分库分表中间件实战入门

数据库在业务初期很听话,数据量一上来就开始闹脾气。查询慢、单表数据爆炸、主从同步搞不定,这些问题我猜不少同行都经历过。解决方向无非两个:换更强的机器,或者换个架构把数据拆开。前者是花钱,后者是花时间。如果你选择了后者,那 MyCAT 这个名字你早晚会碰到。MyCAT 是一个开源的分布式数据库中间件,这几年在数据库分库分表方案里占有一席之地。它对业务层伪装成一个 MySQL 实例,底层管理着真正存数据的 MySQL 节点,你要做的只是把原来指向 MySQL 的地址换成 MyCAT。这篇文章就围绕在 Windows 10 环境下安装和启动 MyCAT 来写,适合刚接触数据库中间件、想先在自己电脑上跑通一遍的开发者,也适合需要在 Windows 笔记本上临时搭一套分库分表验证环境的运维同学。纸上谈兵再多,不如先动起来。

1. 动手前先搞明白:MyCAT 到底干了什么活

1.1 一个"假装自己是数据库"的中间人

MyCAT 本质上是一个 Java 编写的服务进程,它对外监听一个 MySQL 协议的端口(默认 8066)。客户端连它的时候,感觉就像连了一个真正的 MySQL。你发的 SQL 语句、事务命令、字段查询,MyCAT 都能接住。接住之后,它会根据你配置好的逻辑规则,决定把这条 SQL 送到哪一台真实的 MySQL 上执行,再把结果汇总返回给你。

用生活里的话说,它就像一个前台接待。访客不需要知道公司的各个部门在哪,只要把需求告诉前台,前台自己判断该找谁、该转给哪个部门,最后把结果带回来。你的业务代码就是访客,后台各式各样的 MySQL 实例就是各部门,MyCAT 就是那个前台。

这个设计最大的意义在于:对应用层透明。原来只连一个 MySQL 的代码,几乎不用改,只要把数据库连接的 IP、端口换掉,就能连上一整套分布式数据库体系。不用在业务逻辑里塞一堆分库分表的路由判断,这是 MyCAT 被称为"中间件"而不是"客户端 SDK"的根本原因。

1.2 它还能顺手帮你做读写分离和故障切换

很多人以为 MyCAT 只能分库分表,其实读写分离也是它的重点场景。在 schema.xml 里给一个写库配上多个读库,MyCAT 会根据 SQL 的类型,把 SELECT 等读请求分发到读库,把写请求固定送到写库。这个能力很适合读多写少、又不想在代码里自己维护多数据源的项目。

故障切换同样体现在 dataHost 配置里。如果某台真实的 MySQL 节点挂了,MyCAT 可以通过心跳检测感知到,并且在配置允许的情况下把请求切换到另一个节点上。说句实在话,这种切换不会像商业数据库软件那样丝滑,但作为开源方案已经相当够用。

1.3 为什么值得专门在 Windows 10 上装一次

生产环境里 MyCAT 基本都是部署在 Linux 服务器上,因为稳定性和性能都更可控。但如果你只是学习、做本地实验、或者临时搭一个开发环境,Windows 10 完全够用。原因有三:

  • Windows 本机通常已经有了 MySQL 和常用的图形化数据库管理工具,改造链路短;
  • MyCAT 的安装包开箱即用,Java 程序在 Windows 和 Linux 上行为差异很小;
  • Windows 的桌面环境里排查问题更直观,看日志、查端口都方便。

不过在 Windows 上启动 MyCAT 会遇到几个 Linux 文档基本不会提的问题:脚本不是 .sh 而是 .bat,日志路径的分隔符从 / 变成 \,控制台输出的中文编码可能乱码,防火墙还会拦端口。这些细节我都会在后面的部分挨个说到。

2. 安装前的环境准备:避开 80% 的启动失败

很多人在 Windows 上装 MyCAT 失败,不是 MyCAT 本身的问题,而是环境没准备好。所以我强烈建议你先把下面这几项检查完再动手。

2.1 先确认 JDK 版本和 JAVA_HOME

MyCAT 是 Java 程序,没有 JDK 一切都白谈。推荐用 JDK 1.8(也就是 8u 系列),版本太新反而容易踩坑。我见过有人在 JDK 17 环境里启动 MyCAT 失败,最后换回 JDK 8 就好了。这不是说 MyCAT 不能跑在更高版本上,而是大部分网上的资料和部署案例都基于 JDK 8,为了少折腾,用主流版本最省心。

在命令行里验证:

java -version

能看到类似java version 1.8.0_xxx的输出就说明 JDK 已安装。接着检查环境变量:

echo %JAVA_HOME% where java

如果 JAVA_HOME 为空,按下面的方式补上:

  1. 右键"此电脑"→ 属性 → 高级系统设置 → 环境变量;
  2. 在系统变量里新建 JAVA_HOME,路径填 JDK 安装目录,比如 C:\Program Files\Java\jdk1.8.0_202;
  3. 在 Path 变量里追加 %JAVA_HOME%\bin;
  4. 重新打开一个 cmd 窗口再验证。

注意一个隐藏坑:有些机器装了多个 JDK,java -version输出了新版,但 MyCAT 的启动脚本可能用的是 JAVA_HOME 指向的旧版。所以 JAVA_HOME 路径一定要改到位。命令行工具里我习惯用where java看看实际被调用的那个 java 文件在哪个目录,方便定位问题。

2.2 把 MySQL 备好,并创建专用账号

MyCAT 本身不存数据,数据还是存在 MySQL 里。本地实验不需要多复杂的集群,一个 MySQL 5.7 或 8.0 实例就够了。建议在 MySQL 里建一个测试库,再创建一个专用账号。MySQL 8.0 的默认密码规则与 5.7 有区别,连接串配置时需要留意,建议给账号设置一个简单但符合规则的密码。

CREATE DATABASE testdb DEFAULT CHARACTER SET utf8mb4; CREATE USER 'mycat'@'localhost' IDENTIFIED BY '123456'; CREATE USER 'mycat'@'127.0.0.1' IDENTIFIED BY '123456'; CREATE USER 'mycat'@'%' IDENTIFIED BY '123456'; GRANT ALL PRIVILEGES ON testdb.* TO 'mycat'@'localhost'; GRANT ALL PRIVILEGES ON testdb.* TO 'mycat'@'127.0.0.1'; GRANT ALL PRIVILEGES ON testdb.* TO 'mycat'@'%'; FLUSH PRIVILEGES;

我特意多建了几个 host 选项的账号,是因为 MyCAT 在探测后端 MySQL 时,连接来源可能显示为 localhost、127.0.0.1 或本机真实 IP,只授权一个范围容易踩 "Host is not allowed" 的错。

2.3 下载 MyCAT 并理解它的目录结构

MyCAT 的发布包是一个压缩包,解压后根目录下有四个核心目录:

  • bin:存放启动脚本和 Windows 专用脚本,后续基本只跟它打交道;
  • conf:配置文件所在地,schema.xml、server.xml、rule.xml 都在这里;
  • lib:MyCAT 运行时依赖的 jar 包,正常不用动;
  • logs:启动日志和运行日志所在地,排错全靠它。

版本选择上,1.6 系列是最经典、资料最全的版本,很多教程都是基于 1.6 编写的。1.7 和后续版本也在演进,但对于学习场景,1.6 足够。下载后先检查一下压缩包的完整性,解压失败的情况也不是没见过。解压路径强烈建议用纯英文无空格的目录,比如 C:\tools\mycat,后面我会解释原因。

2.4 提前放开 8066 和 9066 两个端口

MyCAT 启动之后要监听两个端口:8066 是供业务连接的逻辑库端口,9066 是管理监控端口。Windows 防火墙一般会弹窗询问是否允许 Java 访问网络,别手滑点了取消。如果启动后发现连不上,优先检查防火墙有没有放行 java.exe,或者 8066/9066 有没有被别的进程占用。

端口占用检查命令:

netstat -ano | findstr "8066 9066"

看到 LISTENING 状态且 PID 对应的进程不是 MyCAT,就需要进一步处理。比如是其他程序占了端口,那就改 MyCAT 的 server.xml 里的端口配置,或者把占用的程序结束掉。

2.5 启动前快速自检清单

每次启动前,我习惯按下面这个清单过一遍,能省下不少来回排查的时间:

  1. 命令行执行 java -version,确认 JDK 8 已配置;
  2. 命令行连接本机 MySQL,确认 3306 端口通、库存在、账号能登录;
  3. 确认 mycat 解压目录无中文、无空格;
  4. 确认 8066 和 9066 端口没有被其他程序占用;
  5. 确认 conf 目录里三个 XML 文件格式正常,尤其是 schema.xml 的标签闭合。

这套自检流程只要走完,启动失败的概率会明显下降。后面遇到问题,也基本能确定问题出在 MyCAT 自身配置,而不是外部环境。

3. 核心配置解析:跑起来之前必须改的几个地方

MyCAT 的所有行为都由 conf 目录下的 XML 文件控制。我给新手的建议是:先学会三件套(server.xml、schema.xml、rule.xml)分别管什么,再动手改。改错了文件导致的启动失败,占了问题排查里相当大的比例。

3.1 三个配置文件的分工

  • server.xml:MyCAT 自身的服务参数,包括逻辑库登录用户、端口、线程池大小等;
  • schema.xml:MyCAT 核心中的核心,描述逻辑库、逻辑表、数据节点、数据主机之间的关系;
  • rule.xml:定义分片规则,比如按什么字段、用什么函数把数据拆分到不同节点。

我平时调试时有个习惯:先把 schema.xml 配到只连一个后端 MySQL 的最小形态,确认能起能连,再往上逐步加表、加分片规则。这样每一步都有明确验证点,不会一上来就是一片报错。

3.2 server.xml 里的用户和端口

server.xml 默认带了一个 root 用户,密码是 123456,对应的逻辑库是 TESTDB。实验阶段直接用默认用户即可,但生产环境必须改掉。关键配置长这样:

<user name="root"> <property name="password">123456</property> <property name="schemas">TESTDB</property> </user>

除了登录用户,server.xml 里还定义了服务端口和管理端口。默认配置是 8066 和 9066,一般不需要改,除非端口被占用了。

理解一下为什么要有"逻辑用户"这一层:业务代码连接 MyCAT 时输入的账号密码,和真正连接后端 MySQL 的账号密码是两回事。MyCAT 会用自己的逻辑用户体系校验客户端身份,再用后端配置的 MySQL 账号去访问真实数据库。这样做的好处是应用层完全感知不到后端的真实账号,安全性更好。

3.3 schema.xml 的最小可运行配置

schema.xml 是让我绕了最多远路的一个文件。第一次配的时候我总想着把所有参数都搞明白,结果越看越糊涂。实际上最小可运行配置就是三层嵌套:schema 到 dataNode 到 dataHost。

下面这个配置可以作为一个最小参考,本地单机场景够用:

<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100"> <table name="travelrecord" dataNode="dn1" /> </schema> <dataNode name="dn1" dataHost="host1" database="testdb" /> <dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="127.0.0.1:3306" user="mycat" password="123456"> <readHost host="hostS1" url="127.0.0.1:3306" user="mycat" password="123456" weight="1" /> </writeHost> </dataHost>

逐个拆开说:

  • schema 标签里定义的是逻辑库名 TESTDB,它就是客户端连上后看到的那个数据库;
  • table 标签声明逻辑表 travelrecord 落在哪个数据节点 dn1,一个库里可以声明多张表;
  • dataNode 把逻辑节点 dn1 映射到 dataHost host1 上,同时指定真实数据库名 testdb;
  • dataHost 是真正连接后端 MySQL 的地方,url 指向 127.0.0.1:3306,user/password 就是 2.2 节创建的 mycat 账号密码。

heartbeat 里的 select user() 是 MyCAT 用来做节点存活检测的语句,保持默认即可。readHost 在只有一个库的实验环境里可写可不写,写上能顺便体验一把读写分离逻辑。

还有一个容易忽略的点:dbDriver 字段可以写 native 也可以写 jdbc。native 走 MyCAT 自带驱动,jdbc 走 JDBC 驱动,普通实验环境用 jdbc 更通用,遇到连接问题也好排查。

3.4 rule.xml 先别急,跑通以后再研究

rule.xml 不是启动 MyCAT 的必需项。只要你没有在 schema.xml 里给表配置具体的分片规则,MyCAT 启动时就不会去解析 rule.xml 中关于该表的具体算法。但如果某张逻辑表被声明了分片规则,rule.xml 又没写好,启动时很可能报"没有找到对应数据节点"之类的错误。

所以我给新手的路径是:先不做分片,所有表都放一个 dataNode 上,等 MyCAT 起来了、客户端能连上了,再回到 rule.xml 里配置分片函数和分片列。这样即便后面加分片出错,你也能明确问题出在分片配置上,而不是先前的大环境。

另外,schema.xml 的 balance 和 writeType 参数值得多说一句。balance=0 表示不启用读写分离,所有请求都走写库;balance=1 表示读请求在多个读库之间轮询。writeType=0 表示所有写操作都发给第一个写库。理解这几个参数的组合,比死记配置更重要。

4. 启动实战:从 cmd 窗口到客户端连接

环境备好了、配置改好了,接下来就到最让人心跳加速的启动环节。这一节我尽量把每一步的命令、验证方法和可能看到的现象都写出来。

4.1 用 startup_nowrap.bat 而不是直接双击 startup.bat

MyCAT 解压后的 bin 目录下至少有两个 bat 文件:startup.bat 和 startup_nowrap.bat。两者有什么区别?

  • startup.bat 会开启一个新窗口并把日志实时打印到前台;
  • startup_nowrap.bat 不在新窗口运行,日志直接输出到当前控制台,体验更像 Linux 的 nohup。

在实际的 Windows 10 环境下,我推荐用 startup_nowrap.bat。原因很实际:startup.bat 弹出的新窗口会占用一个独立的 cmd 会话,关闭该窗口等于把服务一起停掉,而且乱码问题也更常见。用 startup_nowrap.bat 启动后,当前命令行窗口可以继续留在前台观察输出,日志文件也会同步写入 logs 目录。

启动方式:

cd C:\tools\mycat\bin startup_nowrap.bat

如果启动成功,你会在控制台看到类似 "Server startup successfully" 的字样。看到它基本就说明 MyCAT 的核心服务已经起来了。注意启动脚本本身不会自己结束,它会在前台挂着,窗口不要直接叉掉,建议等验证完再通过 Ctrl+C 或脚本停止服务。

4.2 日志文件怎么看

MyCAT 的日志目录是 logs。最核心的文件是 mycat.log 和 wrapper.log。

  • wrapper.log:记录 JVM 启停相关日志,如果 Java 环境有问题,会在这里暴露;
  • mycat.log:记录 MyCAT 的业务日志,配置加载、连接池初始化、SQL 路由信息都在这里。

在 Windows 下查看实时日志,我常用 PowerShell 的 Get-Content -Wait:

Get-Content C:\tools\mycat\logs\mycat.log -Wait

如果你更习惯带尾巴的命令,也可以安装 Git Bash 或使用 Windows Terminal 里的 tail 思路,总之能看到自动追加的内容就行。排查问题时会发现,mycat.log 里最后一部分通常是错误根源,不要被前面一大堆 INFO 刷屏干扰。

4.3 用真实客户端连一次

MyCAT 启动成功后,别急着关黑窗口,先拿一个 MySQL 客户端连上去试试。我用的就是命令行自带的 mysql:

mysql -h127.0.0.1 -P8066 -uroot -p123456

能进到提示符后,先看有哪些逻辑库:

show databases;

正常情况下能看到 TESTDB。接着切进去建一张表:

use TESTDB; create table demo (id int primary key, name varchar(50)); insert into demo values (1, 'hello'); select * from demo;

如果这些操作都成功,说明你的 SQL 已经经过了 MyCAT 的完整链路:客户端 → MyCAT 逻辑库 → 后端 MySQL → 结果返回。这也是我认为"启动成功"的真正标准——不是进程在跑,而是链路通畅。想顺手体验管理端口的话,用 9066 端口连接再执行 show @@help,能看到一堆管理和监控命令。

5. 安装启动常见问题:把你能踩的坑预演一遍

这一部分我根据自己实操中碰到的现象,整理了一份问题速查表。MyCAT 在 Windows 上的常见坑高度集中,看到类似现象直接按表操作,能省很多时间。

5.1 问题速查表

现象可能原因处理办法
cmd 提示 java 不是内部或外部命令JAVA_HOME 未配置或 Path 未包含 bin重新配置环境变量后重开 cmd
启动后马上退出,无任何提示端口被占用或日志目录无写权限netstat 查端口,或检查 logs 目录
控制台输出乱码Windows 默认编码与 UTF-8 冲突用 startup_nowrap.bat,或先执行 chcp 65001
启动显示成功但 8066 连不上防火墙拦截放行 java.exe 或相应端口
客户端看不到 TESTDBschema.xml 未正确加载检查 XML 语法和 server.xml 中 schemas 值
日志报连接 MySQL 失败后端 MySQL 授权不对或未启动用 mysql 命令行验证 3306 连接
日志报 Unknown database后端库名不存在在 MySQL 里创建 database 并核对名称
配置修改后不生效没有重启 MyCAT停止进程后重新执行启动脚本

5.2 看一眼日志,定位效率翻倍

遇到问题先看 logs/mycat.log。如果里面有大段 java.sql.SQLException 或者 IOException,方向基本就是后端连接或网络问题;如果出现 "can't get connection" 之类,重点查 MySQL 用户权限和 host 授权;如果是 cvc-elt 之类的 XML 解析报错,多半是配置文件格式问题。

一个容易被忽略的细节是,Windows 资源管理器里直接双击 bat 可能会闪退,导致你什么信息都看不到。这时候不要慌,打开 cmd 手动切到 bin 目录再执行,让报错信息有时间停留在屏幕上。用这种方式,90% 的闪退问题都能从控制台里找到答案。

5.3 三个额外的 Windows 环境提醒

第一,杀毒软件可能拦截 bat 脚本或 jar 包加载。我在一台装了很多安全软件的工作机上遇到过启动脚本被直接隔离的情况,解压后先把 mycat 目录加入白名单或者临时关闭实时防护,等启动成功再恢复。

第二,不要用中文路径或带空格的路径解压 MyCAT。这个坑在旧版本里尤其明显,路径里的中文或空格可能引发 JVM 找不到类或配置文件读取失败。最稳的办法是解压到类似 C:\tools\mycat 这种纯英文目录。

第三,MySQL 8.0 的默认认证插件是 caching_sha2_password,MyCAT 的早期 JDBC 驱动未必支持。如果后端 MySQL 是 8.0,连接失败时创建一个使用 mysql_native_password 插件的用户往往会直接解决:

CREATE USER 'mycat'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; GRANT ALL PRIVILEGES ON testdb.* TO 'mycat'@'localhost'; FLUSH PRIVILEGES;

这个办法我用得最多,也算是一个最常见的隐性坑。

5.4 修改配置后正确重启

修改 server.xml 或 schema.xml 之后,MyCAT 必须重启才能生效。但直接关窗口再双击脚本这种操作有时候会留下半死不活的进程,导致新实例起不来。我建议用下面的顺序:

  1. 在启动窗口按 Ctrl+C 停掉前台进程;
  2. 命令行用wmic process where "commandline like '%mycat%'" get processid,commandline检查有没有残留的 Java 进程;
  3. 杀掉残留进程后再执行 startup_nowrap.bat;
  4. 启动后立刻看日志确认没有端口冲突。

这套操作虽然比单纯双击麻烦,但能避免很多"改了配置但没生效"的假象。Windows 下进程管理不像 Linux 的 ps 那么直观,养成检查残留进程的习惯很有必要。

从我自己折腾的过程来看,MyCAT 在 Windows 10 上跑起来不算难,难的是很多人一开始对着配置文档无从下手。上面这套流程完全是我实际安装时用过的路径,从环境检查到最小配置再到启动验证,每一步都有明确的命令和预期结果。如果你只想快速验证 MyCAT 的效果,建议直接跳到第 2 节把 JDK 和 MySQL 准备好,然后照着第 3 节的 schema.xml 改一遍,基本十分钟内能看到 "startup successfully"。等这步通了,再慢慢去研究分片规则,那才是真正有意思的部分。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进