Mycat2 SQL支持
拦截器与SQL命令
Mycat2通过拦截器机制匹配SQL并决定处理方式:
interceptor:
defaultHandler:
command: execute
tags:
targets: prototype
forceProxy: true
schemas:
- tables: ['db1.travelrecord']
sqls:
- sql: 'select {selectItems} from {any}'
command: distributedQuery
- sql: 'delete {any}'
command: execute
tags:
executeType: UPDATE
getMetaData: true
needTransaction: true
SQL命令类型
| 命令 | 说明 |
|---|---|
| execute | 执行SQL,透传或路由到后端 |
| distributedQuery | 分布式查询,自动拆分合并 |
| explain | 查看执行计划 |
| useStatement | 切换数据库 |
| begin / commit / rollback | 事务控制 |
| setXA / onXA / offXA | XA事务开关 |
| setAutoCommitOn / Off | 自动提交开关 |
execute 标签参数
| 参数 | 说明 |
|---|---|
| forceProxy | 是否强制透传(忽略事务状态) |
| needTransaction | 是否自动开启事务 |
| getMetaData | 是否自动根据SQL路由 |
| targets | 目标数据源/集群名 |
| balance | 负载均衡策略名 |
| executeType | SQL类型: QUERY / INSERT / UPDATE / QUERY_MASTER |
MetaData支持的SQL格式
# 查询
SELECT [ALL|DISTINCT] {*|projectItem [,projectItem]*}
FROM tableExpression
[WHERE booleanExpression]
[GROUP BY {groupItem [,groupItem]*}]
[HAVING booleanExpression]
[ORDER BY orderItem [,orderItem]*]
[LIMIT [start,] {count|ALL}]
[OFFSET start {ROW|ROWS}]
# 支持UNION / INTERSECT / EXCEPT
# 支持(CROSS|LEFT|RIGHT|FULL) JOIN
# 支持子查询
执行计划 (EXPLAIN)
mysql> EXPLAIN SELECT * FROM db1.travelrecord WHERE id = 1;
# 输出示例:
+--------+-------------+------+
| target | sql | ... |
+--------+-------------+------+
| dn1 | SELECT * ...| ... |
+--------+-------------+------+
事务支持
# XA事务
SET xa = on;
BEGIN;
INSERT INTO db1.travelrecord VALUES(1, 'user1', '2026-01-01', 100, 3);
INSERT INTO db1.travelrecord VALUES(2, 'user2', '2026-01-02', 200, 5);
COMMIT;
SET xa = off;
# Proxy事务
BEGIN;
INSERT INTO db1.travelrecord VALUES(3, 'user3', '2026-01-03', 300, 7);
COMMIT;
# 自动提交
SET autocommit=on;
SET autocommit=off;
SQL改写功能
# 配置SQL改写
sqls:
- name: 'mysql set names'
sql: 'SET NAMES {utf8}'
explain: 'SET NAMES utf8mb4'
command: execute
tags:
targets: prototype
forceProxy: true
# 实际效果: 客户端发送 SET NAMES utf8
# Mycat2自动改写为 SET NAMES utf8mb4 发送到后端
EXPLAIN查看执行计划
# 在SQL前加EXPLAIN
mysql> EXPLAIN select * from travelrecord;
# 查看路由信息
mysql> EXPLAIN insert into travelrecord values(1,'a','2026-01-01',100,3);
# 查看UPDATE路由
mysql> EXPLAIN update travelrecord set fee=200 where id=1;
限制: Mycat2 暂不支持预处理语句(PreparedStatement)、游标(Cursor),客户端可以开启客户端预处理来解决此问题。
提示: 使用前建议先用 EXPLAIN 查看执行计划,确认SQL拆分和路由是否正确。