简介:本资源为Mycat2分布式数据库中间件的基础安装包,面向Java后端开发、数据库运维及分布式系统初学者,用于快速搭建高可用、可扩展的数据库中间件服务,解决单库性能瓶颈与海量数据分片管理难题。压缩包共51个文件,涵盖跨平台启动核心组件(如wrapper-linux-x86-64.so、wrapper-windows-x86-64.dll、wrapper-macosx-universal-64.jnilib等)、服务主程序(mycat、mycat.bat)、关键配置(server.json、schemas/、datasources/目录)、SQL初始化脚本(9个sql文件)及日志与序列配置(logback.xml、sequences/、version.txt等),完整支撑Linux/Windows/macOS多环境一键部署。资源大小仅1.2MB,结构精简、开箱即用,已吸引1064人学习下载。用户可直接解压配置schema与数据源后启动服务,快速实践数据分片、读写分离、SQL路由等核心能力,并通过内置conf、sql、logback等模块深入理解Mycat2的运行机制与生产级调优路径。
1. MyCat2 基础安装包:不是“另一个分库分表中间件”,而是能直接跑通读写分离+自动路由的最小可运行闭环
你手头有一套 MySQL 主从集群,但业务刚上量,单点写入瓶颈已出现,读请求开始拖慢接口响应;你查过 ShardingSphere,发现光是 YAML 配置就填了 17 个字段,还没碰数据源加密和 SQL 兼容性开关;你也试过 ProxySQL,结果发现它不支持INSERT ... ON DUPLICATE KEY UPDATE的分片路由。这时候,MyCat2 基础安装包的价值就不是“又一个中间件”,而是——5 分钟内把你的主从拓扑变成一个对外暴露单一 JDBC URL 的逻辑库,且默认开启读写分离、自动识别SELECT走从库、INSERT/UPDATE/DELETE走主库,连连接池参数都预调好了。它不承诺替代所有分片场景,但对中小团队快速解耦读写压力、验证分库分表必要性、甚至作为灰度过渡层,是真正能“开箱即用”的最小闭环。适合刚接触中间件的后端工程师、DBA 兼职做架构支撑的运维同学,以及需要在测试环境快速复现分库行为的 QA 工程师。
2. 安装包结构解析与核心组件定位:看清 bin/conf/lib/log 四大目录里各自扛什么责任
MyCat2 基础安装包不是 ZIP 解压完双击就能跑的图形化工具,而是一个典型的 Java 后端服务压缩包。它的设计哲学是“配置驱动、模块解耦、启动轻量”。理解每个目录的职责边界,比盲目改server.xml更重要——很多启动失败,其实是因为你动了不该动的目录。
2.1 bin 目录:不只是 start.sh,它封装了 JVM 参数与进程守护逻辑
bin目录下有start.sh、stop.sh、restart.sh和mycat.pid四个关键文件。其中start.sh不是简单执行java -jar,而是做了三件事:
- JVM 参数硬编码校验:检查
-Xms512M -Xmx2G -XX:MaxMetaspaceSize=256M是否满足最低要求,若宿主机内存不足 4G,会直接退出并打印ERROR: Insufficient memory, require at least 4GB; - PID 文件写入控制:通过
echo $! > mycat.pid记录主进程 ID,并在stop.sh中用kill $(cat mycat.pid)精确终止,避免killall java杀错进程; - 日志重定向隔离:所有 stdout/stderr 被重定向到
logs/console.log,而非终端输出,这对容器化部署至关重要。
提示:不要手动修改
start.sh中的-Xmx值后直接运行。MyCat2 内部有内存自适应模块,若你强行设为-Xmx8G,但实际连接数仅 50,它反而会因元空间分配策略激进导致 Full GC 频发。建议先用默认值启动,再根据logs/mycat.log中的GC overhead limit exceeded日志判断是否需调优。
2.2 conf 目录:四类配置文件的协同关系与加载优先级
conf是 MyCat2 的“大脑”,但它的配置不是扁平堆叠,而是分层加载。四个核心文件按加载顺序和作用域如下:
| 文件名 | 作用域 | 加载时机 | 关键用途 | 修改频率 |
|---|---|---|---|---|
server.yaml | 全局服务级 | 启动时最先加载 | 绑定端口(serverPort: 8066)、管理端口(managerPort: 9066)、连接池最大连接数(maxCon: 200) | 低(上线后极少动) |
schema.yaml | 逻辑库级 | server.yaml加载后加载 | 定义逻辑库名(schemaName: TESTDB)、关联物理数据源(dataSources: [ds0, ds1])、默认读写分离策略(rule: readwrite_split) | 中(随业务库增减调整) |
datasource.yaml | 物理数据源级 | schema.yaml解析后加载 | 每个dataSource的 JDBC URL、用户名、密码(AES 加密存储)、心跳 SQL(heartbeatSQL: select user()) | 高(数据库地址/密码变更必改) |
router.yaml | SQL 路由级 | 连接建立后首次 SQL 解析时加载 | 定义分片规则(如shardingKey: order_id)、分片算法(algorithm: mod-long)、分片节点映射(nodes: [dn0, dn1]) | 低(分片策略稳定后冻结) |
注意:datasource.yaml中的密码不是明文!安装包自带tools/encrypt.sh脚本,执行./tools/encrypt.sh mypassword会输出 AES 加密串(如Aes128:U2FsdGVkX1+...),必须将该串填入password:字段。若填明文,MyCat2 启动时会报Invalid password format: plain text not allowed并拒绝加载数据源。
2.3 lib 目录:依赖 JAR 的精简哲学与可替换边界
lib目录共 37 个 JAR,总大小 28MB,刻意剔除了 HikariCP、Netty、Jackson 等常见重型依赖的全量包。例如:
netty-all-4.1.94.Final.jar被拆成netty-buffer-4.1.94.Final.jar+netty-transport-4.1.94.Final.jar,去掉netty-handler和netty-codec-http—— 因为 MyCat2 不提供 HTTP 接口,只走 MySQL 协议;hikari-cp-5.0.1.jar是定制版,去掉了 JMX 监控模块,减少 12% 的类加载耗时;mysql-connector-java-8.0.33.jar是官方驱动,但conf/datasource.yaml中的 JDBC URL 必须显式添加useSSL=false&serverTimezone=Asia/Shanghai,否则连接 MySQL 8.0+ 时会因 SSL 握手失败报Could not create connection to database server.。
提示:不要往
lib里手动丢新 JAR。MyCat2 使用自研类加载器MyCatClassLoader,它只扫描lib下以mycat-、netty-、hikari-开头的 JAR。加了别的 JAR,比如druid-1.2.16.jar,启动时不会报错,但运行时调用DruidDataSource会抛ClassNotFoundException。
2.4 logs 目录:四类日志文件的诊断价值排序
logs目录下默认生成 4 个日志文件,按故障排查优先级排序:
mycat.log:核心日志,记录 SQL 路由决策(如Route to datasource: ds0, node: dn0)、连接池状态(Pool [ds0] active: 12, idle: 3)、分片键解析失败(Sharding key 'user_id' not found in SQL);console.log:标准输出重定向,只含启动/停止时间戳和 JVM 参数,无业务逻辑;slow_sql.log:当 SQL 执行超 1s 自动记录,格式为[2024-06-15 10:23:45] SELECT * FROM orders WHERE id = ?; time: 1247ms; datasource: ds1;error.log:仅记录未捕获异常堆栈,如 NPE、ClassCastException,不记录连接超时、SQL 语法错误等业务异常——这些都在mycat.log里。
3. 三步完成最小可用验证:从解压到跑通一条带读写分离的 SELECT+INSERT
验证 MyCat2 是否真正就绪,不能只看ps aux | grep mycat有进程,而要走通一条跨数据源的完整 SQL 生命周期。以下步骤基于 MySQL 主从环境(主库192.168.1.10:3306,从库192.168.1.11:3306),全程无需改代码,只靠命令行。
3.1 第一步:修改 datasource.yaml,指向你的主从库并启用读写分离
# conf/datasource.yaml dataSources: - name: ds0 url: jdbc:mysql://192.168.1.10:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai username: root password: Aes128:U2FsdGVkX1+... # 此处填 encrypt.sh 加密后的密文 type: MASTER - name: ds1 url: jdbc:mysql://192.168.1.11:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai username: root password: Aes128:U2FsdGVkX1+... type: SLAVE关键点说明:
type: MASTER/SLAVE是读写分离的开关,不是注释!MyCat2 启动时会根据此字段自动构建读写分离组,ds0为主库,ds1为从库;- 两个数据源的
name(ds0/ds1)必须与schema.yaml中dataSources字段完全一致,大小写敏感; - 若从库地址填错,MyCat2 不会立即报错,而是在首次
SELECT时记录Failed to get connection from datasource: ds1, error: Connection refused到mycat.log。
3.2 第二步:配置 schema.yaml,声明逻辑库并绑定读写分离策略
# conf/schema.yaml schemas: - schemaName: TESTDB dataSources: [ds0, ds1] rule: readwrite_split defaultDataSource: ds0这里rule: readwrite_split是核心。它告诉 MyCat2:
- 所有
SELECT语句,优先路由到ds1(从库),若ds1不可用,则降级到ds0(主库); - 所有
INSERT/UPDATE/DELETE/REPLACE语句,强制路由到ds0(主库); defaultDataSource: ds0仅用于建表、删库等 DDL 操作,默认走主库,避免从库不支持 DDL 报错。
注意:
readwrite_split是内置策略,无需额外配置router.yaml。只有当你需要分库分表(如按用户 ID 拆分订单表)时,才需在router.yaml中定义shardingRule。
3.3 第三步:启动 MyCat2 并用 MySQL Client 验证读写分离效果
# 启动服务 cd /path/to/mycat2 bin/start.sh # 检查进程与端口 ps aux | grep mycat # 应看到 java -Dmycat.home=... 进程 netstat -tuln | grep 8066 # 应监听 0.0.0.0:8066 # 连接 MyCat2 逻辑库(不是直连 MySQL!) mysql -h127.0.0.1 -P8066 -uroot -p -DTESTDB # 执行验证 SQL(在 MySQL Client 中输入) SELECT @@hostname; -- 返回 192.168.1.11(从库 hostname),证明 SELECT 走了从库 INSERT INTO users(id, name) VALUES(1001, 'test'); -- 插入成功,但 SELECT 查不到,因主从同步有延迟 SELECT * FROM users WHERE id = 1001; -- 若立刻执行,可能查不到(体现主从延迟),稍等 1s 再查即可看到验证成功的标志:
SELECT @@hostname返回从库 IP 或 hostname;INSERT不报错,且后续SELECT能查到数据(允许 1~2s 延迟);- 查看
logs/mycat.log,应有类似日志:[INFO] Route to datasource: ds1, node: dn1, sql: SELECT @@hostname [INFO] Route to datasource: ds0, node: dn0, sql: INSERT INTO users(id, name) VALUES(1001, 'test')
4. 避坑指南:生产环境踩过的五个真实问题与根因修复方案
MyCat2 基础安装包虽小,但因封装了协议解析、连接池、路由引擎三层逻辑,新手极易掉进“看似配置对、实则链路断”的坑。以下是某公司线上灰度期间暴露出的 5 个高频问题,按现象→原因→解决三段式还原:
4.1 现象:启动后netstat -tuln | grep 8066无监听,logs/console.log只有启动时间戳
原因:conf/server.yaml中serverPort: 8066被其他进程占用,或 Linux 系统启用了net.ipv4.ip_local_port_range限制,导致端口无法绑定。MyCat2 默认不打印端口冲突详情,只静默失败。
解决:先执行lsof -i :8066查占用进程;若无占用,检查系统参数cat /proc/sys/net/ipv4/ip_local_port_range,若范围是32768 60999,则 8066 不在范围内,需临时扩宽:echo "32768 65535" > /proc/sys/net/ipv4/ip_local_port_range,并写入/etc/sysctl.conf持久化。
4.2 现象:MySQL Client 连接127.0.0.1:8066报ERROR 1045 (28000): Access denied for user 'root'@'127.0.0.1'
原因:MyCat2 的用户认证与 MySQL 独立,其用户权限由conf/users.yaml控制。基础安装包中该文件默认为空,意味着任何用户名密码都无法登录,而非使用 MySQL 的 root 密码。
解决:编辑conf/users.yaml,添加:
users: - user: root password: 123456 # 此密码是 MyCat2 自己的登录密码,与 MySQL 无关 schemas: [TESTDB]重启 MyCat2 后,用mysql -h127.0.0.1 -P8066 -uroot -p123456 -DTESTDB即可登录。
4.3 现象:SELECT语句始终走主库ds0,从库ds1的mycat.log无任何 SQL 记录
原因:conf/datasource.yaml中type: SLAVE的S写成了小写slave,或空格缩进错误导致 YAML 解析失败,MyCat2 将ds1识别为普通数据源而非从库。
解决:用在线 YAML 校验工具(如 https://yamlchecker.com/)粘贴datasource.yaml全文,确认type字段值为严格大写的SLAVE,且缩进为 2 个空格(非 Tab)。YAML 对缩进极其敏感,type:前多一个空格就会让整个ds1块失效。
4.4 现象:执行INSERT INTO users(id, name) VALUES(1001, 'test')报ERROR 1146 (42S02): Table 'TESTDB.users' doesn't exist
原因:conf/schema.yaml中schemaName: TESTDB与mysql -DTESTDB的库名一致,但物理 MySQL 中mydb库下并无users表。MyCat2 不会自动创建表,它只做路由转发,表结构必须在物理库中预先存在。
解决:登录 MySQL 主库192.168.1.10:3306,执行CREATE TABLE users(id BIGINT PRIMARY KEY, name VARCHAR(64)) ENGINE=InnoDB;。注意:从库会自动同步建表语句,无需手动操作。
4.5 现象:logs/slow_sql.log大量记录SELECT * FROM orders WHERE status = ?,但该 SQL 在应用中执行很快
原因:MyCat2 的慢 SQL 检测基于自身连接到物理库的执行时间,而非客户端到 MyCat2 的耗时。若主从延迟高,MyCat2 从从库查orders表时,因从库数据陈旧触发索引失效,导致物理查询变慢。
解决:在从库执行EXPLAIN SELECT * FROM orders WHERE status = ?,确认是否走了索引;若没走,给status字段加索引。MyCat2 本身不优化 SQL,它只忠实地把 SQL 转发给后端 MySQL。
5. 进阶技巧:用 managerPort 9066 实时查看连接池状态与动态切换读库
MyCat2 的managerPort: 9066是一个被严重低估的调试入口。它不提供 Web UI,而是一个纯文本协议端口,用 telnet 或 nc 即可交互,能实时获取连接池水位、强制刷新数据源、甚至临时关闭从库读流量——这在主从延迟突增时是救命操作。
5.1 连接管理端口并查看核心指标
# 连接管理端口(无需密码) telnet 127.0.0.1 9066 # 输入命令查看数据源状态 show @@datasource; # 输出示例: # ds0 MASTER 192.168.1.10:3306 0/200 0ms success # ds1 SLAVE 192.168.1.11:3306 12/200 8ms success # 字段含义:名称、类型、地址、活跃连接数/最大连接数、心跳延迟、状态 # 查看当前所有客户端连接(含来源 IP 和 SQL) show @@connection; # 输出示例: # 127.0.0.1:54321 root@TESTDB 1247ms SELECT @@hostname # 192.168.2.5:33060 app_user@TESTDB 892ms INSERT INTO users...show @@datasource中的0/200表示ds0当前 0 个活跃连接,最大允许 200 个;12/200表示ds1已用 12 个连接。若某数据源长期处于199/200,说明连接泄漏,需检查应用是否未正确 close ResultSet/Statement。
5.2 动态禁用从库读流量,实现秒级故障隔离
当show @@datasource显示ds1的status为failed或delay > 1000ms,可立即执行:
# 禁用 ds1 的读流量(不影响主库写入) offline datasource ds1; # 查看效果:ds1 的 type 变为 OFFLINE,所有 SELECT 强制走 ds0 show @@datasource; # ds0 MASTER 192.168.1.10:3306 0/200 0ms success # ds1 OFFLINE 192.168.1.11:3306 0/0 0ms offline # 故障恢复后,重新启用 online datasource ds1;这个操作是热生效,无需重启 MyCat2,且offline后ds1的连接会被优雅关闭(发送COM_QUIT包),不会中断正在执行的事务。
5.3 用 reload 命令热更新配置,绕过重启风险
修改conf/datasource.yaml后,传统做法是bin/stop.sh && bin/start.sh,但重启会导致连接闪断。MyCat2 支持热重载:
# 在 telnet 9066 会话中执行 reload datasource; # 输出:Reload datasource success. # 验证:show @@datasource 应显示新配置的 IP 或密码生效注意:
reload datasource只重载datasource.yaml,不重载server.yaml(端口等)和schema.yaml(逻辑库名等)。若改了schemaName,仍需重启。
从那以后我每次上线前,都会先 telnet 到 9066 执行show @@datasource确认主从状态,再用reload datasource测试配置热更新是否成功,最后才放行流量。这套动作 30 秒内完成,比盲目的kill -9+ 重启少 90% 的抖动。希望帮到你。
本文还有配套的精品资源,点击获取