
TiDB 7.x 源码编译之 TiProxy 篇,及尝鲜体验


TiProxy 简介
TiProxy 是一个基于 Apache 2.0 协议开源的、轻量级的 TiDB 数据库代理,基于 Go 语言编写,支持 MySQL 协议。
TiProxy 支持负载均衡,接收来自应用程序的请求,然后将其发送到 TiDB 集群。支持自动故障转移,当后端 TiDB Server 发生故障,可以自动将连接转移到其他节点,以提高应用程序的可用性。

TiProxy 编译
TiProxy 是轻量级组件,编译步骤很简洁,编译环境同前 《TiDB 源码编译之 TiUP 篇》 。
编译步骤如下:
1 | git clone https://github.com/shawn0915/tiproxy --depth=1 |
日志输出:
1 | $ make |
检查版本号:
1 | $ ./bin/tiproxy -v |
这里遇到第一个问题,tiproxyctl
不识别 VERSION
变量,原因是在代码中出现硬编码。([Closed] Hard code in tiproxyctl #340 )
修改后,版本号获取正常。
1 | $ ./bin/tiproxy -v |
TiProxy 尝鲜
TiProxy 的日志格式支持 TiDB 原生格式、json
格式和 console
格式。
下面启动 TiProxy 服务,日志采用 json
格式和 DEBUG
级别。
1 | ./bin/tiproxy --config ./conf/proxy.toml --log_encoder console --log_level debug |
tiproxy 启动后尝试连接:
1 | mysql --comments --host 127.0.0.1 --port 6000 -u root |
值得注意的是,TiDB 服务端与客户端之间默认采用非加密连接 [1],TiDB 启动时默认也不会生成 TLS 证书 [2],但是 tiproxy 启动时默认启用 tls 认证,这里为了简化测试,选择修改默认配置项,不要求配置 tls。
1 | vi conf/proxy.toml |
否则会连接失败,遇到报错:
1 | $ mysql --comments --host 127.0.0.1 --port 6000 -u root |
以及控制台打印日志:
1 | 2023/08/23 12:00:27.645 +09:00 INFO main.proxy proxy/proxy.go:159 new connection {"connID": 0, "client_addr": "127.0.0.1:42944"} |
使用 TiUP 启动 TiProxy
TiUP 下个版本应该就会包含这个功能,感谢 @xhebox 大佬的贡献,得以让我们使用 tiup 来调用 tiproxy 组件,这里先抢先体验一下如何使用 tiup playground 启动 tidb 和 tiproxy,当然 tiup cluster 也是支持的。
由于含有该功能代码的 tiup 还没发布,所以需要自行编译 tiup,编译步骤可参考 《TiDB 源码编译之 TiUP 篇》 。
编译后的 tiup 版本信息如下:
1 | $ tiup --version |
tiproxy 组件尚未发布到官方的镜像库,所以要想使用 tiup 调度 tiproxy 组件,需要先将 tiproxy 包上传至当前使用的 tiup 镜像库,这里使用的是本地镜像库,使用如下命令进行上传:
1 | tiup mirror publish tiproxy v0.1.1 ./tiproxy.tar.gz tiproxy --desc tiproxy |
具体操作步骤可参考 《TiUP:TiDBAer 必备利器》 ,提示,需要同时提交 nightly
版本,否则会提示错误信息。
1 | Error: Playground bootstrapping failed: component tiproxy doesn't have nightly version on platform linux/amd64 |
上述步骤完成后,可以看到 tiup-playground
已经增加了 tiproxy 相关选项。
1 | $ ./tiup-playground --version |
启动演示如下:
1 | tiup playground 7.0 --tag 7.0 --without-monitor --tiflash 0 --tiproxy 1 |

通过端口 6000 连接 tiproxy:

到此,tiproxy 已经启动成功,并成功通过 tiproxy 连接到后端 tidb 集群。由于篇幅有限,tiproxy 的功能演示、测试内容另行成文。
期许
1. 源码 repo 命名小写
目前的 repo 名为 [pingcap/TiProxy],建议改为小写 pingcap/tiproxy
,统一命名方式。
毕竟是 pingcap/tidb
而非 [pingcap/TiDB],是 tikv/tikv
而非 [tikv/TiKV],是 tikv/pd
而非 [tikv/PD]。
2. tiproxy 端口非 4000
我相信大家已经达成共识,端口 4000 就是 TiDB Server 的默认端口,所以真的不建议在 tiproxy 和 tidb server 同时启动时,将 tidb server 的端口改成其他端口,而将 tiproxy 的端口改成 4000。AskTUG 论坛中有相关贴子:闲聊贴 | 数据库端口的问题
3. tiproxy 可以独立启动
对 TiDB 深入了解的同学都知道,TiDB 的三大核心组件 TiDB Server / TiKV / PD 都可以独立启动。希望 TiProxy 也可以做到这点,不依赖 PD 也可以独立启动,而不是找不到 PD 就原地“躺平”,无时间限制不断重试连接 PD。
1 | [2023/08/22 11:47:46.122 +09:00] [WARN] [main.infosync.etcdcli] [v3@v3.5.6/retry_interceptor.go:62] [retrying of unary invoker failed] [target=etcd-endpoints://0xc000802380/127.0.0.1:2379] [attempt=0] [error="rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing dial tcp 127.0.0.1:2379: connect: connection refused\""] |
tiproxy 连接 pd 异常时,通过客户端连接 6000 端口会报错:
1 | $ mysql -uroot -hlocalhost -P6000 |
4. 包版本升级
建议升级包的版本,比如 【 go 1.19 】 升级到 【 go 1.21 】,跟核心组件对齐,参考帖子:
还有其他包,比如:
1 | github.com/go-mysql-org/go-mysql v1.6.0 |
相关 Issue:[Closed] Upgrade go-sql-driver/mysql version to v1.7.1 #2237
5. 监控面板
TiProxy 已经提供了一些 API 来对其进行管理,但还是期望可以有一个极简的 Web 页面来达到可视化的目的。
毕竟 HAProxy 有 http://localhost:9999/haproxy-status
, ProxySQL 也有 http://localhost:6080
。
甚至,TiDB Lightning 都有 http://localhost:8289
,参见文档:TiDB Lightning Web 界面 。
6. 操作系统支持
由于 tiproxy 尚未上载到 tiup mirror,所以想要测试 tiproxy 只能从 github repo asset 下载,或者自行编译。测试 github 上的包时发现,在 CentOS 7 上无法运行,相关讨论帖参见:tiproxy 无法使用 。
这只是一个点,tiproxy 兼容性测试也要加油啊。

7. 编译参数
建议加上 make clean
选项,或者 make file 可以再完善一下,如果能做到像 tiup 那样一个 make
命令搞定就很棒了。([Closed] support make clean option #343 )
另外,希望将环境变量 GO111MODULE="on"
也写进 makefile。
8. 错误日志
error code 建议细化一下,不然使用者真的容易 UNKNOWN
。
1 | ERROR 1105 (HY000): Unknown error%!(EXTRA string=TiProxy fails to connect to TiDB, please check network) |
有些日志的告警级别希望调整一下,比如查询错误现在是 DEBUG
,可以改为 WARN
,或者单独输出到一个日志文件。
1 | 2023/08/22 23:51:33.138 +08:00 DEBUG main.proxy.conn.be backend/backend_conn_mgr.go:283 got a mysql error {"connID": 0, "client_addr": "127.0.0.1:41942", "ns": "default", "error": "ERROR 1105 (HY000): conflict hypo index name hypo_a", "cmd": "Query"} |
此外,开启 DEBUG 日志后,有大量的 main.infosync.etcdcli
日志输出,每 3s 打印一次,建议优化掉。
1 | 2023/08/22 23:59:02.799 +08:00 DEBUG main.infosync.etcdcli v3@v3.5.6/retry_interceptor.go:53 retrying of unary invoker {"target": "etcd-endpoints://0xc000980000/127.0.0.1:2379", "attempt": 0} |
总结
据说 TiProxy 的云化版本已经用在了 TiDB Cloud 中,期待 TiProxy 早日 GA,并且最终可以到达能够替换 HAProxy 或 ProxySQL 的水准。
附:

End.

- Title: TiDB 7.x 源码编译之 TiProxy 篇,及尝鲜体验
- Author: ShawnYan
- Created at: 2023-08-23 23:44:30
- Updated at: 2023-08-23 23:44:30
- Link: https://shawnyan.cn/2023/tidb/tidb-7.x-compile-tiproxy/
- License: This work is licensed under CC BY-NC-SA 4.0.