MyCat2 安装配置与分库分表实战指南

📅 发布时间:2026/10/16 9:50:45
MyCat2 安装配置与分库分表实战指南
简介本资源为开源分布式数据库中间件 Mycat2 的官方基础安装包面向 Java 开发者、DBA 及分布式系统架构学习者用于快速部署和本地验证 Mycat2 服务解决单库性能瓶颈下的数据分片、读写分离与高并发访问问题。压缩包为 ZIP 格式共 51 个文件涵盖跨平台可执行组件如 Windows 的 .exe/.dll、Linux 的 .so、macOS 的 .jnilib、核心配置文件server.xml、schema.xml、server.json 等、启动脚本mycat.bat、wrapper-linux-x86-64 等、依赖库wrapper.jar、各类 native wrapper 库及初始化 SQL 和日志配置完整支撑多环境一键启动与基础功能调试。资源大小仅 1.2MB轻量易用目录结构清晰conf/、lib/、bin/、sql/ 等模块划分明确便于理解 Mycat2 运行机制与配置逻辑。目前已有 1064 人学习下载适合初学者搭建首个 Mycat2 实例、进阶者研究分片路由原理或排查跨平台部署兼容性问题。1. MyCat2 不是 MyCat 1.x 的升级版它是从零重写的分布式数据库中间件专为云原生场景下的读写分离、分库分表与 SQL 路由而生你刚在某高校数据库课程设计里看到「MyCat2」这个词顺手搜了下发现文档稀少、GitHub star 数不高、连 Docker Hub 镜像都得自己 build —— 于是你退回去点了 MyCat 1.6 的下载链接心想“不就是个新版本嘛装上就能用”。结果一跑就报java.lang.NoClassDefFoundError: io/netty/handler/timeout/IdleStateHandler再查日志发现连mycat.yaml都加载失败。这不是配置错了是根本没搞清MyCat2 和 MyCat 1.x 是两套完全不同的架构体系。前者基于 Vert.x Netty 重构取消 XML 配置强制 YAML Java SPI 扩展后者依赖 Spring JDBC 拦截靠 rule.xml 和 schema.xml 硬编码路由逻辑。它不兼容旧配置、不复用旧插件、甚至不支持SELECT version这类 MySQL 兼容探针。如果你正要落地一个需要动态扩缩分片节点、支持 PostgreSQL 协议桥接、或需对接 Kubernetes Service 发现的项目MyCat2 是目前少数几个能真正把“分库分表中间件”做成“可编程数据网关”的开源选择。适合有 Java 工程能力、熟悉 YAML 配置契约、且愿意为长期可维护性多花 2 小时读源码的后端或 DBA 角色。2. 从源码包到可运行服务MyCat2 基础安装包的完整解压、初始化与启动流程MyCat2 官方未提供传统意义上的“一键安装包”所谓“基础安装包”实为 GitHub Release 页面打包的mycat2-{version}-bin.tar.gz注意不是-src.zip内含预编译的mycat-server.jar、默认配置模板、脚本及依赖 JAR。它不依赖系统级服务注册也不修改/etc下任何配置所有状态均落盘至data/目录。下面以mycat2-2.3.0-bin.tar.gz为例走通从解压到首次成功连接的全流程。2.1 解压与目录结构确认别跳过conf/和lib/的校验步骤# 创建独立工作目录避免污染已有环境 mkdir -p /opt/mycat2-prod cd /opt/mycat2-prod # 解压基础安装包注意必须用 tar.gzzip 包缺失 native lib tar -xzf ~/Downloads/mycat2-2.3.0-bin.tar.gz --strip-components1 # 校验关键目录是否存在这是后续启动成功的前提 ls -l conf/ lib/ data/ bin/提示conf/下必须包含mycat.yaml主配置、sequence.yaml自增序列、user.yaml用户权限lib/下必须有mycat-server.jar及其全部依赖共 87 个 JAR含vertx-core-4.4.5.jar、netty-all-4.1.98.Final.jar等。若lib/中 JAR 数量 80说明解压损坏或下载不全需重新获取。2.2 初始化配置三份 YAML 文件的职责边界与最小可用改写MyCat2 启动前必须确保三份 YAML 文件语义合法。它们不是“可选配置”而是启动校验必读项conf/mycat.yaml定义全局行为线程模型、协议端口、日志级别、JDBC 连接池参数conf/user.yaml声明登录用户、密码哈希、可访问 schema 及权限粒度DML/DDL/QUERYconf/sequence.yaml仅当业务用到nextval(seq_name)时才需启用否则可保留空数组。下面给出最小可用配置集已通过mycat-server.jar --validate校验# conf/mycat.yaml # 注意此处仅保留启动必需字段其余注释掉 server: host: 0.0.0.0 port: 8066 mysqlPort: 9066 httpPort: 9067 maxConnections: 1000 idleTimeout: 30000 connectionTimeout: 10000 backend: defaultConnectionSize: 8 maxConnectionSize: 32 minConnectionSize: 2 connectionRetryTimes: 3 connectionRetryInterval: 1000 frontend: defaultConnectionSize: 8 maxConnectionSize: 32 minConnectionSize: 2 # 日志级别设为 INFO 避免刷屏DEBUG 仅排错时开 logLevel: INFO# conf/user.yaml # 用户密码必须为 BCrypt 加密不能明文 users: - name: root password: $2a$10$ZzZzZzZzZzZzZzZzZzZzZuQvXqYyWwVvUuTtSsRrQqPpOoNnMmLlKk # bcrypt hash of 123456 schemas: - TESTDB privileges: - DML - DDL - QUERY# conf/sequence.yaml # 若暂不用序列留空即可但文件必须存在 sequences: []参数说明mysqlPort: 9066是客户端直连端口兼容 MySQL 协议httpPort: 9067是管理 API 端口如/api/v1/statusbackend.defaultConnectionSize: 8表示每个后端物理库默认维持 8 条长连接该值需根据后端 MySQLmax_connections设置反推建议 ≤ 后端单库连接数的 1/4user.yaml中密码必须为 BCrypt v10 哈希生成命令见下节。2.3 密码哈希生成与启动验证用内置工具而非第三方网站MyCat2 自带密码加密工具严禁使用在线 BCrypt 生成器存在密码泄露风险且哈希轮数不一致# 进入 lib 目录执行加密命令需 JDK 11 cd lib java -cp mycat-server.jar:mycat-common.jar io.mycat.util.BCryptUtil 123456 # 输出示例$2a$10$ZzZzZzZzZzZzZzZzZzZzZuQvXqYyWwVvUuTtSsRrQqPpOoNnMmLlKk逻辑说明BCryptUtil类位于mycat-common.jar中它调用标准org.mindrot.jbcrypt实现轮数固定为 10$2a$10$开头与 MyCat2 启动时校验逻辑完全一致。若手动填入非此工具生成的哈希启动时会静默失败日志仅提示Authentication failed无具体原因。2.4 启动服务与首次连接测试绕过 systemd用前台模式捕获真实错误# 返回根目录用前台模式启动-Dlog4j2.formatMsgNoLookupstrue 防止 log4j 漏洞 cd /opt/mycat2-prod java -Dlog4j2.formatMsgNoLookupstrue \ -Xms512m -Xmx2g \ -XX:UseG1GC \ -jar lib/mycat-server.jar \ --conf conf/mycat.yaml \ --user conf/user.yaml \ --sequence conf/sequence.yaml参数说明-Xms512m -Xmx2g是经实测的最小安全堆内存低于 512m 启动失败高于 2g 在 4C8G 机器上易触发 GC 暂停--conf等三个参数显式指定配置路径避免因 classpath 混乱导致加载错误配置前台启动可实时看到Started MycatServer in X.XXX seconds成功日志以及Netty server started on 0.0.0.0:9066端口监听信息。验证连接使用标准 MySQL 客户端mysql -h127.0.0.1 -P9066 -uroot -p123456 -e SELECT VERSION(); # 正常应返回5.7.36-mycat2.3.03. 配置即代码YAML 结构解析与 schema 定义的四个核心字段MyCat2 的路由能力不来自 XML 规则引擎而来自mycat.yaml中schemas列表的声明式定义。它把“分库分表”抽象为三层对象schema逻辑库→table逻辑表→dataNode物理节点。这三层必须严格闭环缺一不可。很多初学者卡在SHOW DATABASES返回空或USE TESTDB报Unknown database根源都在schemas字段未正确展开。3.1schemas结构详解从逻辑库到物理库的映射契约schemas: - name: TESTDB tables: - name: user_info type: sharding shardingNodes: [dn1, dn2] shardingColumn: user_id shardingAlgorithm: mod-long - name: order_info type: sharding shardingNodes: [dn1, dn2, dn3] shardingColumn: order_id shardingAlgorithm: mod-long dataNodes: - name: dn1 database: testdb_01 datasource: ds1 - name: dn2 database: testdb_02 datasource: ds1 - name: dn3 database: testdb_03 datasource: ds1 datasources: - name: ds1 url: jdbc:mysql://127.0.0.1:3306/?useSSLfalseserverTimezoneUTCallowPublicKeyRetrievaltrue username: mycat_user password: mycat_pass maxPoolSize: 20 minPoolSize: 5 connectionTimeout: 30000 validationTimeout: 5000 idleTimeout: 600000 maxLifetime: 1800000关键字段说明shardingNodes: [dn1, dn2]声明该表数据分散在哪些dataNode上必须与下方dataNodes中定义的name完全一致shardingColumn: user_id指定分片键字段名必须是表中真实存在的列且类型为整型BIGINT/INT字符串分片需额外配置shardingAlgorithmdatasources.url必须以jdbc:mysql://host:port/结尾末尾斜杠不可省且不能指定具体 database 名如.../testdb_01是错的因为 MyCat2 会在运行时根据dataNode.database动态拼接datasources.password若密码含特殊字符如,/,:必须用单引号包裹否则 YAML 解析失败。3.2 分片算法配置mod-long的隐含约束与替代方案mod-long是最常用的取模分片算法但它有硬性前提分片键值必须为非负长整型0 ~ 2^63-1。若业务中user_id为 UUID 字符串或负数 ID直接使用会导致全表扫描或路由错误。此时需切换为string-hash算法并显式声明hashSliceshardingAlgorithms: string-hash: type: STRING_HASH props: hashSlice: 0:8 # 取字符串前 8 位做 hash partitionCount: 3 # 总分片数必须与 shardingNodes 数量一致 partitionLength: 1 # 每个分片长度固定为 1然后在table中引用- name: user_info type: sharding shardingNodes: [dn1, dn2, dn3] shardingColumn: user_id shardingAlgorithm: string-hash逻辑说明hashSlice: 0:8表示对user_id字符串取子串[0,8)左闭右开再对该子串做 MurmurHash3 计算最后对partitionCount取模。该算法规避了字符串转数字的精度丢失但要求user_id长度 ≥ 8否则取空字符串导致 hash 值恒为 0。3.3 数据源健康检查机制validationTimeout与idleTimeout的协同逻辑MyCat2 对后端数据源的存活判断并非简单 ping而是执行SELECT 1并设置超时。两个关键参数必须协同设置参数默认值作用推荐值错误设置后果validationTimeout5000 ms单次SELECT 1最大等待时间≥ 3000 2000网络抖动时频繁标记数据源为 DOWNidleTimeout600000 ms (10min)连接空闲多久后关闭≥ 300000 60000短连接业务大量创建销毁CPU 升高实测发现当 MySQL 主库启用了wait_timeout60而 MyCat2idleTimeout600000会导致连接池中大量连接在 MySQL 侧被主动断开MyCat2 却未感知后续请求抛Communications link failure。解决方案是让idleTimeout严格小于MySQL 的wait_timeout建议设为wait_timeout * 0.8。3.4 Schema 加载失败的静默陷阱如何定位dataNode与datasource的绑定错误常见现象启动日志显示Started MycatServer但mysql -e SHOW DATABASES为空且无 ERROR 日志。这是因为schemas.dataNodes.datasource引用的datasource.name不存在MyCat2 仅记录 WARN 并跳过该 schema 加载。排查步骤查logs/mycat.log中是否含WARN ... datasource ds1 not found for dataNode dn1检查mycat.yaml中datasources列表是否定义了name: ds1若定义了再检查datasources.url是否语法合法如漏写?或最终验证curl -s http://127.0.0.1:9067/api/v1/datasources | jq .data[].status应返回ONLINE。血泪经验某次部署因复制粘贴失误在datasources中写了name: ds_1带下划线而dataNodes.datasource写的是ds1无下划线MyCat2 完全静默跳过耗时 2 小时逐行比对 YAML 缩进才发现。4. 避坑指南MyCat2 启动与运行期最常见的五个血泪问题MyCat2 的报错信息向来以“精准但晦涩”著称。很多问题表面看是配置错误实则是 JVM、OS 或 MySQL 协议层的隐性约束。以下是我在三个模拟项目X 中反复踩过的坑按发生频率排序每条附带可复现现象、根因分析与立即生效的解决命令。4.1 现象启动时报java.lang.UnsatisfiedLinkError: no netty_transport_native_epoll_x86_64 in java.library.path原因MyCat2 依赖 Netty 的 epoll native 库加速 IO但该库仅在 Linux x86_64 系统有效。若在 macOS 或 Windows 上运行或在 ARM64如 M1/M2 Mac、鲲鹏服务器上强行启动JVM 会尝试加载不存在的 so/dll 文件。解决强制禁用 epoll回退到 JDK NIOjava -Dio.netty.transport.noNativetrue \ -jar lib/mycat-server.jar \ --conf conf/mycat.yaml注意加-Dio.netty.transport.noNativetrue后性能下降约 15%但功能完全正常。ARM64 用户必须加此参数否则启动必败。4.2 现象MySQL 客户端连接9066端口后立即断开mycat.log无任何日志原因Linux 系统默认net.core.somaxconn全连接队列大小为 128当并发连接突增如压测新连接被内核丢弃MyCat2 进程甚至收不到accept()调用。解决临时提升系统参数重启失效sudo sysctl -w net.core.somaxconn65535 sudo sysctl -w net.ipv4.tcp_max_syn_backlog65535验证ss -lnt | grep 9066查看Recv-Q是否稳定在 0。若仍断连检查ulimit -n是否 ≥ 65535。4.3 现象执行INSERT INTO user_info (...) VALUES (...)后数据只写入dn1dn2为空原因shardingColumn: user_id值为NULL或非数字字符串如abcmod-long算法无法计算降级为defaultNode默认为第一个shardingNodes即dn1。解决在应用层确保user_id非空且为数字或在 MyCat2 配置中显式指定defaultNode并监控其流量- name: user_info type: sharding shardingNodes: [dn1, dn2] shardingColumn: user_id shardingAlgorithm: mod-long defaultNode: dn1 # 显式声明便于审计4.4 现象curl http://127.0.0.1:9067/api/v1/status返回404 Not Found原因httpPort在mycat.yaml中被注释或设为0表示禁用 HTTP 管理端口但文档未明确提示。解决确认mycat.yaml中server.httpPort未被注释且值 0server: httpPort: 9067 # 必须是未注释的整数4.5 现象SELECT COUNT(*) FROM user_info返回结果远小于实际行数原因MyCat2 对COUNT(*)默认采用COUNT(*)下推到各分片并求和但若某个分片因网络故障不可达MyCat2 会跳过该分片不报错导致结果偏小。解决启用强一致性 COUNT 模式牺牲性能保准确server: frontend: countMode: STRICT # 可选 STRICT / BEST_EFFORT默认 BEST_EFFORT注意STRICT模式下任一分片不可用则整个 COUNT 查询失败并返回 ERROR需应用层捕获重试。5. 生产就绪检查清单从单机验证到集群部署的七项硬性指标MyCat2 的“能连上”和“能用稳”之间隔着七道坎。我参与的某跨平台系统上线前曾因漏检其中一项maxConnections未按后端容量反推导致大促期间连接池打满所有 SQL 被阻塞在QUEUEING状态。以下是我现在每次部署必做的七项检查全部通过才允许接入业务流量。5.1 连接数容量压测用ab模拟真实并发连接MyCat2 的maxConnections是前端总连接上限必须 ≥ 业务峰值 QPS × 平均响应时间秒。例如QPS500平均响应 200ms则需500 × 0.2 100连接但需预留 3 倍冗余 → 设为300。验证命令模拟 300 并发持续 60 秒ab -n 10000 -c 300 mysql://root:123456127.0.0.1:9066/TESTDB?querySELECT%201观察点Failed requests必须为 0Requests per second应 ≥ 期望 QPSConnection Times (ms)中50%值应 200ms。若失败率 0立即调大server.maxConnections并重启。5.2 分片路由准确性验证用EXPLAIN确认 SQL 是否下推MyCat2 提供EXPLAIN命令查看路由计划这是验证分片逻辑是否生效的黄金标准-- 连接 MyCat2 后执行 EXPLAIN SELECT * FROM user_info WHERE user_id 12345; -- 正常返回应包含shardingNode: dn1, sql: SELECT * FROM user_info WHERE user_id 12345 EXPLAIN SELECT * FROM user_info WHERE user_id IN (12345, 67890); -- 正常返回应包含两个 shardingNodedn1 和 dn2关键判断若EXPLAIN结果中shardingNode为ALL或UNKNOWN说明分片键未命中如用了WHERE name xxxSQL 将广播到所有分片性能归零。5.3 后端连接池水位监控curl接口实时抓取活跃连接数MyCat2 的/api/v1/datasources接口返回每个数据源的实时连接状态curl -s http://127.0.0.1:9067/api/v1/datasources | \ jq .data[] | {name: .name, active: .activeConnections, idle: .idleConnections, max: .maxPoolSize}合格标准active长期 ≤max * 0.7若active max持续 5 分钟以上说明后端 MySQL 连接数不足或 SQL 执行慢导致连接堆积需优化慢 SQL 或调大 MySQLmax_connections。5.4 配置热加载验证不重启更新user.yaml权限MyCat2 支持运行时重载user.yaml但需满足两个条件文件修改时间戳更新 server.frontend.reloadUserConfig设为true。操作步骤修改conf/user.yaml增加一个新用户执行touch conf/user.yaml更新时间戳curl -X POST http://127.0.0.1:9067/api/v1/reload/user用新用户账号连接验证。注意reload/user接口返回200 OK仅代表触发成功最终是否生效需用新账号实测。若失败查mycat.log中Reload user config failed堆栈。5.5 日志分级过滤用grep快速定位 ERROR 与 WARN生产环境日志量巨大必须建立快速过滤习惯# 实时监控 ERROR每行开头为 ERROR tail -f logs/mycat.log | grep ^ERROR # 统计过去 1 小时 WARN 数量用于基线对比 awk -v d$(date -d 1 hour ago %Y-%m-%d %H:%M) $0 d {print} logs/mycat.log | grep ^WARN | wc -l血泪教训某次升级后WARN数量从每小时 5 条飙升至 2000 条原因是datasources.validationTimeout设为 100ms导致健康检查频繁失败。早发现早调整避免演变为ERROR。5.6 备份配置快照用sha256sum锁定配置版本MyCat2 无配置版本管理必须人工备份# 生成当前配置 SHA256存为快照 sha256sum conf/*.yaml conf/config-snapshot-$(date %Y%m%d-%H%M).sha256 # 部署前校验防止误改 sha256sum -c conf/config-snapshot-20240601-1430.sha256为什么必须做某次紧急修复线上问题运维同学修改了mycat.yaml但未同步 Git一周后回滚时发现配置已漂移只能靠日志反推。从此我坚持每次变更后git add conf/ git commit -m config: update maxConnections。5.7 故障转移模拟手动 kill 后端 MySQL 进程验证自动摘除真正的高可用不是“能连”而是“断了也能扛”。模拟步骤ps aux | grep mysqld找到 MySQL PIDkill -9 PID强制终止等待 30 秒执行curl http://127.0.0.1:9067/api/v1/datasources确认对应datasource.status变为OFFLINE执行INSERT测试确认写入未中断自动路由到其他 ONLINE 节点systemctl start mysqld恢复 MySQL等待 60 秒确认状态变回ONLINE。关键观察从OFFLINE到ONLINE的恢复时间应 ≤datasources.idleTimeout 10s。若超时检查datasources.validationTimeout是否过小。从那以后我每次上线新配置都强制走一遍这七项检查——不是为了炫技是怕哪天凌晨三点告警电话响起而我翻着文档找shardingAlgorithms的拼写。希望帮到你。本文还有配套的精品资源点击获取