MyCat不支持逻辑库级细粒度权限控制,其schemas配置仅决定用户可见的逻辑库名,不校验SQL操作类型或后端真实权限;可靠权限拦截必须依赖后端MySQL账号授权。

MyCat 本身不支持按逻辑库粒度做细粒度权限控制,用户配置里的 user 和 schemas 只是路由白名单,不是权限闸门。
MyCat 的 schema.xml 和 server.xml 中的 schemas 配置到底管什么
它只决定这个 user 能“看到”哪些逻辑库名,请求一进来,只要目标库名在列表里,MyCat 就放行并尝试路由——不管你是 SELECT 还是 DROP TABLE,也不校验你对后端真实分片是否有对应权限。
- 比如
schemas="shop,order",用户连上后能执行USE shop,也能发DELETE FROM order_detail(只要表名在逻辑库里定义过) - 后端 MySQL 实例上的真实账号权限完全独立,MyCat 不转发、不校验、不拦截
- 如果你在
server.xml里漏写了某个逻辑库,用户连上去就报Unknown database 'xxx',但这只是路由层拒绝,不是权限拒绝
想拦 UPDATE 或限制只读,只能靠后端 MySQL 账号权限 + MyCat 的 readOnly 标识
MyCat 唯一能干预 DML 的地方,是给连接打上 readOnly=true 标签,然后依赖后端 MySQL 拒绝写操作。但它不校验语句类型,也不做 SQL 解析。
- 在
server.xml的user配置里加readOnly="true",该用户所有连接默认走只读节点(如果配置了读写分离) - 但注意:如果后端 MySQL 账号本身有
UPDATE权限,且你没配读写分离,readOnly="true"不会阻止写语句执行,只会让它去读节点——而读节点通常不允许写,这时才报错,比如ERROR 1290 (HY000): The MySQL server is running with the --read-only option - 真正可靠的拦截,必须在每个后端 MySQL 实例上,为 MyCat 使用的代理账号单独授权,例如:
GRANT SELECT ON shop_db.* TO 'mycat_user'@'%';
为什么不能依赖 MyCat 自带的 sqlInterceptor 做权限拦截
理论上可以写插件拦截 SQL,但实际非常脆弱:SQL 解析不完整、不支持复杂嵌套、权限规则难维护,且 MyCat 2.x 已废弃该机制,1.x 的 sqlInterceptor 仅用于日志和简单改写。
- 它拿不到完整的 AST,
WHERE条件、子查询、UNION 等结构基本无法安全识别 - 拦截逻辑写在 JVM 里,每次升级 MyCat 版本都可能破坏兼容性
- 哪怕你成功拦截了一条
DELETE,用户换用REPLACE INTO或存储过程绕过,你就得持续追加规则
真要实现逻辑库级权限控制,得接受一个现实:MyCat 是路由中间件,不是数据库防火墙。核心防线必须落在后端 MySQL 账号权限体系上,MyCat 的配置只是辅助路由可见性。最容易被忽略的一点是——很多人以为在 server.xml 里删掉某个 schema 就等于“禁用了访问”,其实只要用户知道物理库名,仍可通过 USE 物理库名 直连后端实例绕过(如果网络通且账号有权限)。










