简介:Mycat2基础安装包是一份数据库中间件的跨平台部署资源包,面向需要在服务器或本地环境快速搭建Mycat2实例的开发者与运维人员,适用于解决高并发、数据分片及读写分离等场景下的数据库扩展问题。压缩包共包含51个文件,总体积约1.2MB,涵盖SQL初始化脚本、schema.xml/server.json等核心配置模板、不同操作系统下的运行库(如so/dll/jnilib)以及启动脚本与守护进程文件,可支持Windows、Linux、macOS、Solaris等平台的基础运行。已有1056人学习下载。通过该安装包,用户可获得完整的Mycat2目录结构、默认分片规则与数据源配置参考,并根据实际业务修改schema和路由策略后,在本地快速搭建起一个可用的分布式数据库访问层,为后续学习数据分片、读写分离和SQL路由机制提供落地环境。
1. mycat2 基础安装包:装好不算数,跑通主从才算数
如果你拿到 Mycat2 基础安装包,解压完立刻敲bin/mycat start,然后看到进程活着就以为万事大吉——那你大概率会在几分钟后收到一条ERROR 1045 (28000): Access denied。这个包很小,解压后几十兆,但它不包含 JDK、不包含你的 MySQL 连接串,也没有一个能直接连的逻辑库等着你。它给到的是中间件本体和一套模板配置,真正决定它能不能在你机器上跑起来的,是装之前的三件事:JDK 版本选没选对、MySQL 账号能不能连、配置文件里的数据源填没填对。
这篇文章就把这三件事拆开讲。先交代 MyCat2 和 MyCat1 在配置体系上的差别,再完整走一遍解压、启停、systemd 托管的流程,然后把mycat.yml、db.json里决定运行效果的关键字段逐个过一遍,最后列几个安装阶段最容易踩的坑。适合的对象很明确:手上已经有一套 MySQL 主从、想在应用层做读写分离或分片、并且不想去啃源码的部署工程师。目标只有一个——让这台机器上的 MyCat2 从“装上了”变成“能用了”。
2. 装之前先搞清三件事:JDK 版本、配置体系与 MySQL 主从
2.1 MyCat2 与 MyCat1 不是小升级,配置体系整个重写了
很多人会拿 MyCat1 的经验去套 MyCat2,结果第一步就卡住:找不到server.xml和schema.xml。这两个文件是 MyCat1 时代的核心配置,MyCat2 把它们整个换掉了,改成了mycat.yml(运行参数)加db.json(数据源与逻辑库)的组合。
这意味着网上大量 MyCat1 的教程对你现在这个包基本没有参考价值。如果你照着旧教程去找 XML 文件,花半小时也找不到,因为 MyCat2 压根不读 XML。我见过不止一个人在这上面耗了一下午,最后才发现自己看的是五年前的方案。所以装这套基础安装包之前,先把脑子切到新体系:mycat.yml管进程,db.json管数据,两件事分开记。
还有一个容易被忽略的点:MyCat2 的配置里引入了 “Proxy” 的概念,逻辑库不再直接绑物理库,而是绑数据源或集群。刚上手会觉得多了一层,实际用起来反而清楚——读写分离时写库和读库挂在同一个集群下面,逻辑库只需要面对这个集群。
2.2 JDK 版本为什么是个硬门槛
MyCat2 是 Java 写的,跑它必须先有一个可用的 JDK,而且版本不能太新。官方基线是 JDK 8,我自己用的一直是 8u191 之后的版本。如果你机器上只有 JDK 17 或 21,直接启动大概率会报java.lang.reflect.InaccessibleObjectException——原因是 JDK 9 之后模块化把反射访问的口子收紧,中间件里一些自省逻辑没跟上。
有解决办法,JVM 参数里加--add-opens就能放行,但没必要让一台要跑生产中间件的机器为了将就上个 JDK 17。我的建议是单独装一个 JDK 8,放在/usr/local/java/jdk8,启动 MyCat2 时用JAVA_HOME指过去,和其他 Java 应用互不干扰。
判断当前环境里有没有 JDK、是什么版本,直接执行java -version就能看到。如果机器上同时装了多个 JDK,就需要在启动脚本或者 systemd 单元里明确指定JAVA_HOME,这一步在后面的部署章节会展开写。
2.3 MySQL 主从必须先搭好,MyCat2 不负责同步数据
MyCat2 只做路由和转发,不负责把主库的 Binlog 拉到从库。也就是说,读写分离能不能生效,前提是你自己已经把 MySQL 主从复制打通了。常规做法是主库开启 Binlog,从库配置CHANGE REPLICATION SOURCE TO指向主库,等SHOW REPLICA STATUS里两个关键线程都变成YES之后,再把主从两个物理库的连接信息填进 MyCat2。
这一步跳过的话会出现一个很迷惑的现象:主库写了数据,从库没有,通过 MyCat 查询时一会儿有数据一会儿没有。很多人以为是 MyCat2 的负载均衡出了问题,其实根子在 MySQL 主从根本没同步。装 MyCat2 前,顺手在主库执行一条插入语句,去从库确认能看到同一条数据,这个前置检查不花五分钟,能省掉后面一整天的排查时间。
2.4 先想清楚单机跑还是双机跑
MyCat2 支持单机local模式和集群模式,基础安装包默认配置是单机。学习和中小项目先跑通单机就够了,等真正需要高可用时再考虑集群。我见过不少人一上来就照着文档配集群,配置复杂度翻了两倍,连最基本的路由都没验证过,出了问题根本不知道是单机的问题还是集群的问题。
3. 把安装包变成可用服务:解压、启动脚本、systemd 托管
3.1 规划安装路径并确认 JDK 可用
我习惯把中间件统一放在/opt下,通过软链接提供稳定的访问路径。这套包解压后目录名通常带版本号,为了方便后续升级,我会再建一个不带版本号的软链接。先确认 JDK 环境,再规划目录:
java -version # 确认输出里有 1.8 字样,例如: # openjdk version "1.8.0_191" mkdir -p /opt/mycat tar -xzf mycat2-xxxx-linux.tar.gz -C /opt/mycat解压完成后,在/opt/mycat下应该能看到bin、conf、logs、lib这几个目录。先不急着启动,检查一下目录属主。用 root 直接跑中间件不是个好习惯,出了问题不好定位权限归属,我一般会建一个专用的系统用户:
useradd -r -s /sbin/nologin mycat chown -R mycat:mycat /opt/mycat这一步的意义是让 MyCat 进程以独立用户运行。后续如果用 systemd 托管,User=mycat配合权限控制,比一把梭 root 要稳得多。
3.2 配置 MYCAT_HOME 环境变量
启动脚本需要找到安装目录,所以环境变量要提前设好。在/etc/profile.d/下面新建一个脚本,保证任何登录会话都能生效:
cat > /etc/profile.d/mycat.sh <<'EOF' export MYCAT_HOME=/opt/mycat export PATH=$MYCAT_HOME/bin:$PATH EOF source /etc/profile.d/mycat.sh这里有一点要注意:MYCAT_HOME指向的必须是实际解压出来的目录。如果你用软链接,要确认脚本能正确解析,否则启动时找不到lib下的依赖包会直接报 class not found。我见过有人把MYCAT_HOME配成/usr/local/mycat,但软链接失效后日志里一堆ClassNotFoundException,其实不是包的问题,是路径没指对。
3.3 前台启动验证,避免一上来就后台跑
第一次启动我不建议直接用bin/mycat start丢到后台,因为你不知道它会不会秒退。更稳的办法是先前台跑一下:
cd /opt/mycat bin/mycat console通过console方式启动后,日志会直接打到终端,能看到启动过程中有没有异常。正常启动到一半会看到Server started successfully之类的字样,此时不要关终端,另开一个窗口验证端口和进程。
如果前台启动正常,再切回后台模式,然后马上查看进程和日志:
bin/mycat start ps aux | grep mycat tail -f /opt/mycat/logs/mycat.log启动后不要只盯着ps那一行,日志才是真正的判断依据。logs目录下通常有wrapper.log和mycat.log,前者记录 JVM 启动过程,后者记录运行时的路由与错误信息。凡是启动时报错,先打开这两个文件看堆栈尾部,八成问题就写在最后二十行。
3.4 用 systemd 托管,重启不再靠手敲
既然已经用后台模式验证能跑,就顺手把它托管给 systemd,省得以后每次机器重启都要手动拉起来。在/etc/systemd/system/mycat.service写一个单元文件:
[Unit] Description=MyCat2 Database Proxy After=network.target mysqld.service [Service] Type=forking User=mycat Group=mycat Environment=JAVA_HOME=/usr/local/java/jdk8 Environment=MYCAT_HOME=/opt/mycat ExecStart=/opt/mycat/bin/mycat start ExecStop=/opt/mycat/bin/mycat stop ExecReload=/opt/mycat/bin/mycat restart PIDFile=/opt/mycat/logs/mycat.pid Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target写完后执行:
systemctl daemon-reload systemctl enable mycat systemctl start mycat systemctl status mycatType=forking是因为启动脚本会 fork 出一个常驻 JVM 进程,配合PIDFile让 systemd 知道该盯哪个进程。JAVA_HOME和MYCAT_HOME写进单元文件而不是依赖系统全局变量,可以避免环境差异,这是我从踩坑里学来的习惯。
4. 两个配置文件决定运行效果:mycat.yml 与 db.json 逐字段说明
4.1 mycat.yml:进程端口、运行模式与内存
这套包解压后,conf目录下的mycat.yml是进程的第一道配置。核心关注三块:运行模式、端口监听、内存设置。
运行模式默认是local,也就是单机模式。端口方面,默认的数据端口是 8066,管理端口是 9066。第一次装完我会先检查这两个端口有没有被占用:
ss -lntp | grep -E '8066|9066'如果端口被别的进程占用了,需要在mycat.yml的端口配置段改掉。内存配置在模板里通常有对应的段落,根据自己的机器规格调整,比如 4G 内存的机器给到 2G 堆就够了,别贪大,JVM 堆太大反而容易触发长时间 GC 导致路由延迟抖动。
这部分配置的修改原则是:每次只改一处,改完重启看日志。不要一次性把端口、内存、字符集全改了再启动,出了问题你根本不知道是哪一行改坏的。
4.2 db.json:数据源、集群、逻辑库三层结构
db.json是这套配置里最核心的文件,它决定了 MyCat2 连哪些 MySQL、怎么路由。在 MySQL 主从已经打通的前提下,一个最小可用的db.json长这样:
{ "dataSource": { "master": { "url": "jdbc:mysql://192.168.1.10:3306/demo", "user": "mycat", "password": "your_password", "maxCon": 20, "minCon": 5, "connectionTimeout": 3000, "idleTimeout": 60000 }, "slave": { "url": "jdbc:mysql://192.168.1.11:3306/demo", "user": "mycat", "password": "your_password", "maxCon": 20, "minCon": 5, "connectionTimeout": 3000, "idleTimeout": 60000 } }, "clusters": { "rwCluster": { "masters": ["master"], "reads": ["slave"] } }, "schemas": { "demo": { "normalProxies": { "demo": { "cluster": "rwCluster" } } } } }结构分三层,我习惯从底往上读:
dataSource定义物理连接。url里要写完整 JDBC 地址,user和password是 MySQL 里专门给 MyCat 建的账号,maxCon/minCon控制连接池大小。
clusters把多个数据源组合成一个读写集群。masters数组里放主库数据源名,reads数组里放从库数据源名。MyCat2 会根据这条配置把读请求分发到reads里指定的从库。
schemas定义逻辑库。normalProxies里的cluster字段把逻辑库绑定到上面的rwCluster,这样应用连接时只需要面对逻辑库名demo,不需要知道背后是哪台 MySQL。
| 参数 | 含义 | 建议值 |
|---|---|---|
url | JDBC 连接串,包含主机、端口、库名 | 按实际 MySQL 地址填写 |
user | MySQL 账号 | 单独建一个,别用 root |
password | 账号密码 | 避免特殊字符,解析 JSON 时容易出错 |
maxCon | 连接池最大连接数 | 20 起步,压测后再调 |
minCon | 连接池最小连接数 | 5,保持心跳连接 |
connectionTimeout | 获取连接超时毫秒数 | 3000 |
idleTimeout | 空闲连接回收毫秒数 | 60000 |
4.3 逻辑库与物理库映射:为什么 show databases 是空的
很多人配置完重启,用客户端连上 8066 端口,执行show databases;发现是空的,立刻以为装坏了。先说结论:八成不是装坏了,是db.json里schemas没配对。
schemas里的逻辑库名是 MyCat 暴露给客户端的名字,它必须通过normalProxies或shardingProxies绑定到具体的集群或者数据源。如果只写了逻辑库名,没有绑定任何cluster,那这个逻辑库就是一个空壳,show databases当然看不到。
反过来也会遇到一个问题:逻辑库里能看到,但use demo;进去后执行show tables;是空的。这种情况通常是物理库demo里真的没有表,或者 MyCat 配置的逻辑库名和 MySQL 物理库名不一致。先到 MySQL 直接看看物理库有没有表,别在 MyCat 这边瞎找。
4.4 改完配置,reload 还是重启?
MyCat2 支持一部分配置热加载,但db.json里的数据源和集群定义,我建议改完直接重启,不要赌reload的行为。这是我实际踩过的坑:改完db.json执行 reload,表面上看配置加载了,但连接池里的旧连接依然指向老地址,业务流量一过来就报错。从那以后凡是涉及数据源地址、账号密码、集群结构的修改,一律走完整重启:
systemctl restart mycat tail -f /opt/mycat/logs/mycat.log等日志里不再出现ERROR,再用客户端连一遍验证,确认show databases能列出配置的逻辑库,这一步就算过了。
5. 安装阶段常翻车的五个坑:现象、原因与解决方案
这一章是安装现场的真实记录,不是从文档里搬来的理论。每一个坑都有人踩过,而且症状都很迷惑,先看现象再给原因,最后说怎么解。
坑一:Windows 下改过启动脚本,传到 Linux 报bad interpreter
现象:把整个安装包在 Windows 解压,或者用记事本编辑过bin/mycat文件,再传到 Linux 上执行bin/mycat start,报错bad interpreter: /bin/sh^M: no such file or directory。
原因:Windows 的换行符是\r\n,Linux 只认\n。脚本第一行的#!/bin/sh后面跟了一个\r,系统把\n前的\r也当作路径的一部分,自然找不到解释器。这是 Windows 与 Linux 文本文件最经典的冲突。
解决:在 Linux 上执行一次全目录换行符清洗:
find /opt/mycat -type f | xargs sed -i 's/\r$//'从那以后我再也不在 Windows 下编辑任何要部署到 Linux 的脚本文件。实在要编辑,用vim打开后先执行:set ff=unix再保存,能省掉这一整类问题。
坑二:JDK 17/21 启动时报反射异常
现象:确认 JDK 版本高于 8 的机器上,启动后logs/wrapper.log里出现java.lang.reflect.InaccessibleObjectException,进程秒退。
原因:JDK 9 之后的模块系统默认不允许跨模块反射访问,MyCat2 的一些内部机制没有适配新版 JDK 的模块边界。这不是安装包坏了,是运行环境不匹配。
解决:最省事的办法是装一个 JDK 8,把JAVA_HOME指向它再启动。硬要用新 JDK 就得在启动参数里补--add-opens,但没必要为了它去折腾新 JDK 的模块开关。
坑三:MySQL 8 默认认证插件导致Access denied
现象:MySQL 账号密码明明正确,但 MyCat2 连过去报Access denied for user 'mycat'@'...'。
原因:MySQL 8 默认的认证插件是caching_sha2_password,不是老版本的mysql_native_password。MyCat2 自带的驱动对旧插件兼容更好,新插件在部分驱动版本下会鉴权失败。
解决:建账号时显式指定老插件:
CREATE USER 'mycat'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; GRANT ALL ON demo.* TO 'mycat'@'%';如果你不想让 MyCat 连 root 账号,这一步就得在建账号时做,并且注意账号的 host 范围要覆盖应用和 MyCat 的访问来源。
坑四:修改配置后执行 reload,配置被还原
现象:用管理端或命令执行了 reload,然后发现刚才手动改的db.json内容不见了,恢复成修改前的状态,一脸懵。
原因:reload 动作在某些版本里会触发配置文件的重新加载,加载逻辑依赖模板和内部状态,并不等价于保存。改的配置文件如果语法不完整,加载失败后老配置并不会回读,但界面表现像是“还原”了。
解决:改配置文件之前先备份一份,改完做一次 JSON 语法校验,然后直接重启进程而不是依赖 reload。我一般会先快速校验一下 JSON 合法性:
python3 -m json.tool /opt/mycat/conf/db.json确认输出没有报错,再systemctl restart mycat,这一步能杜绝一大半“改完没生效”的误会。
坑五:主从同步正常,但读流量始终不走从库
现象:MySQL 主从复制已经验证通过,MyCat2 也把reads配了从库,但通过 MyCat 连续查询时,明显感觉到所有流量还是落在主库。
原因:db.json里集群的readdataSource或者reads列表没有正确指向从库数据源,或者修改集群定义后没有重启,MyCat 还在用旧拓扑。这个问题的关键在于拓扑描述和实际连接池状态不一致。
解决:先把拓扑简化到最小单元,单独验证从库能不能被路由到;再逐步加业务。检查配置时重点看clusters段里读写角色是否分清楚,从库必须挂在读角色下,而不是同时挂在写角色里。验证方法是重启后查看日志里数据源初始化的行,确认从库地址出现在读连接池中。
6. 装完怎么验收:五步检查与读写分离验证
装完之后别急着接业务,先走一遍五步验收流程,每一步都有具体的判断标准。这套流程来自我多次部署中间件的习惯,走完能确认这个安装包在你机器上是真跑通了。
第一步看进程。systemctl status mycat输出里进程必须是active (running)状态,而且能看到对应的 JVM 进程 PID。如果进程反复重启,马上打开journalctl -u mycat -n 50看退出原因。
第二步看端口。ss -lntp | grep -E '8066|9066'能同时看到数据端口和管理端口处于LISTEN状态。只看到一个端口,基本可以断定配置文件里有段没加载成功。
第三步看日志。tail -n 100 /opt/mycat/logs/mycat.log里不能有新出现的 ERROR 级日志,启动完成行要正常打印。日志里如果出现连接超时,回到db.json检查connectionTimeout和 MySQL 地址。
第四步看逻辑库。用 mysql 客户端连 8066 端口,执行show databases;,必须能看到db.json里配置的逻辑库名。这是配置映射生效的直接证据。
第五步看读写分离效果。在 MySQL 主库建一张测试表并插入一条数据,从库确认同步后,通过 MyCat 执行查询。如果担心路由不对,可以先在 MyCat 里执行explain select * from t1查看路由目标,确认写操作落在主库、读操作落在从库。这一步走完,这套基础安装包才算真正交付到业务手里。
没有后悔药可吃,每一步都不能省。有一次我图省事,跳过端口检查直接把服务丢给业务,结果业务连不上 8066 才发现端口被别的服务占了,耽误了一整个下午。从那以后,我每次装完新版本的 MyCat2,都强制自己走一遍这五步,先验证再交付,不再相信start成功就等于到位。希望帮到你。
本文还有配套的精品资源,点击获取