用 DataGrip 直连 Yearning:我写了个只读 SQL 中转代理
项目地址:github.com/toolsHelp/Y... 程序名
sql-relay,MIT 开源。本文为第三方工具介绍,与 Yearning 官方无关。
一、起因:审批很稳,查数很痛
我们公司在用 Yearning 做数据库审批平台。线上 DDL / DML 全部走工单审批,数据库真实账号密码由平台统一保管,开发人员碰不到------这套机制在安全和合规上确实让人放心。
但真正日常查数、排查问题的时候,体验就比较难受了:
- 写 SQL 没有任何提示。 库名、表名、字段名全靠手打,跨库查询时连有哪些库都得先去别处确认。
- 历史查询找不回来。 上周写过的那条复杂查询,想复用只能靠翻记录或者重写。
- 结果集不能转 INSERT。 想把几行数据搬到测试环境,只能手动拼
INSERT语句,字段一多就想砸键盘。 - 多数据源来回切。 要在 A 数据源和 B 数据源之间比对数据,页面切来切去,没法放在一起看。
这些恰恰是 DataGrip、Navicat 这类桌面客户端最擅长的事:结构联想补全、本地执行历史、结果集编辑与「转写 INSERT / 导出」、多标签多会话。
于是问题变成:能不能让 DataGrip 直接连上 Yearning?
二、思路:不改造 Yearning,只在中间加一层
我没有去动 Yearning 的代码(它是 AGPL 项目,也不该随便改),而是写了一个本地代理 sql-relay:
arduino
DataGrip ──MySQL 协议──► 本地代理 sql-relay ──HTTP/WebSocket──► Yearning 后端
│ 按库名路由 + 只读拦截 │ 用真凭据查真实 MySQL
└─ config.yaml
它伪装成一个 MySQL 5.7 服务端,于是任何标准 MySQL 客户端都能直连。收到查询后,代理用你自己的 Yearning 账号登录、走 Yearning 的查询通道执行,再把结果按 MySQL 协议原样返回。
关键是安全模型一点没变:
- 代理本地不保存任何数据库密码,只保存你的 Yearning 登录口令;真实库凭据始终在 Yearning 服务端。
- 只读,写语句 / DDL /
SELECT ... INTO/CALL/ 加锁读一律拦截,返回 MySQL 错误。要改数据?去 Yearning 提工单,流程照旧。 - 只监听
127.0.0.1,加一道本地连接口令,防止同机其他进程蹭连。
三、三分钟上手
1. 下载 :从 Releases 拿对应平台的二进制,连同 config.yaml 模板放一起。
2. 配置:只改这几项,其余保持默认。
yaml
proxy_password: "你自己定的本地口令"
yearning:
base_url: "http://你的-yearning地址" # 不带末尾斜杠
login_user: "你的-yearning账号"
login_password: "你的-yearning密码"
3. 启动:
bash
./sql-relay-linux-amd64 -config config.yaml # Linux / macOS
# Windows: .\sql-relay-windows-amd64.exe -config config.yaml
启动日志会列出你有权限的所有数据源名,记住它们。
4. 连接 DataGrip:
| 字段 | 值 |
|---|---|
| Host | 127.0.0.1 |
| Port | 3307 |
| User | 上面日志里的数据源名 |
| Password | proxy_password |
| Driver | 任意 MySQL 驱动 |
建议关掉数据源设置里的 "Execute statements atomically"。连上之后,SHOW DATABASES 会列出你所有数据源的库,直接 SELECT * FROM 库名.表名 就能跨库查。
四、它替你做了哪些脏活
只做协议转发是不够的,桌面客户端会发一大堆 Yearning 查询引擎处理不了的语句,代理在中间都消化掉了:
- 一个连接汇总所有数据源 :按库名自动路由,
USE 库名后不带前缀也能查,WebSocket 会话按数据源缓存,切库不重连。 - 查询工单自动处理:Yearning 开了查询审核时,代理会自动帮你提交一次工单再重试。审核关闭的话直接通过,你完全无感。
SET/USE本地消化:Yearning 解析不了这些,代理自己吃掉。- 表结构元数据本地缓存 :DataGrip 打开库表树会疯狂查
information_schema,代理缓存 5 分钟(可配),打开速度完全不一样。 - 客户端兼容改写 :预处理语句的参数内联成普通 SQL;后端是 MySQL 5.6 时自动剥离 5.7 才有的
generation_expression列。
五、说实话,它有哪些限制
不想让人抱着过高期待踩坑,几个必须提前讲清楚的:
- 只读。这是设计目标,不是缺陷。要改数据请走 Yearning 工单。
- 结果值全部按字符串返回 。数值列在客户端排序、筛选是按字符串比较的,需要精确数值请
CAST或客户端转换。 - 依赖 Yearning 的审核状态。开了查询审核就得等审批通过(代理会自动提单,但审批得人来)。
- 同名库取第一个匹配。多个数据源下有同名库时,路由保留第一个,遇到查错库的情况欢迎提 issue。
六、适合谁
已经部署了 Yearning、又想用 DataGrip / Navicat 查数的开发和 DBA。如果你只需要在网页上提交和审批工单,Yearning 本身就够用。
项目是 MIT 协议,依赖也都是宽松许可证(MIT / BSD / Apache-2.0),可以放心在公司里用。地址在下面,觉得有用给个 star 就是对我最大的鼓励,有问题欢迎提 issue。
MySQL 是 Oracle Corporation 及其关联公司的注册商标,本项目仅实现其网络协议以兼容标准 MySQL 客户端,与 Oracle 无关。