news 2026/9/10 15:09:29

TiDB Global Kill 功能端到端测试指南:GlobalKillTest 工具的原理、部署与回归验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TiDB Global Kill 功能端到端测试指南:GlobalKillTest 工具的原理、部署与回归验证

TiDB Global Kill 功能端到端测试指南:GlobalKillTest 工具的原理、部署与回归验证

【免费下载链接】tidbTiDB is built for agentic workloads that grow unpredictably, with ACID guarantees and native support for transactions, analytics, and vector search. No data silos. No noisy neighbors. No infrastructure ceiling.项目地址: https://gitcode.com/GitHub_Trending/ti/tidb

GlobalKillTest 是 TiDB 仓库中专门用于自动化验证 "Global Kill"(全局 Kill)特性的测试命令工具。本文以 tests/globalkilltest/README.md 为主体,结合 Global Kill 设计文档、测试源码与核心实现,完整讲解该工具的命令行参数、集群环境准备、七大测试场景、底层原理以及集成回归与手动单测两种用法,帮助你理解并复跑这一套针对全局连接 ID 与KILL语句的测试体系。

一、为什么需要 GlobalKillTest:Global Kill 特性回顾

在阅读测试工具之前,有必要先理解它要验证的目标特性。传统 MySQL 协议中,连接 ID(connID)是 TiDB 实例本地的:执行KILL x必须连到正确的实例上,无法在集群层面安全地做负载均衡。为此,TiDB 通过 docs/design/2020-06-01-global-kill.md 设计了"全局 Kill"方案,核心包括三点:

  1. 全局连接 ID:在所有 TiDB 实例间全局唯一;
  2. KILL 重定向:将KILL x转发到连接 x 所在的 TiDB 实例上执行;
  3. 32/64 位双模式 connID:集群规模较小时(TiDB 实例数小于 2048)使用 32 位 connID 以兼容旧客户端;大集群使用 64 位。connID 的 bit 0 作为标记位区分两者。

32 位与 64 位 connID 的位布局(来自设计文档)如下:

32 bits: 31 21 20 1 0 +--------+------------------+------+ |serverID| local connID |markup| | (11b) | (20b) | =0 | +--------+------------------+------+ 64 bits: 63 62 41 40 1 0 +--+---------------------+--------------------------------------+------+ | | serverID | local connID |markup| |=0| (22b) | (40b) | =1 | +--+---------------------+--------------------------------------+------+

其中serverID由每个 TiDB 实例启动时从 PD(etcd)随机获取并由租约(默认 12 小时)保证唯一;bit 63 恒为 0,使 connID 落在非负 int64 范围内。在 pkg/util/globalconn/globalconn.go 中,ParseConnID(globalconn.go)负责从 uint64 解析出 ServerID 与 LocalConnID 并检测 32 位截断;MaxLocalConnID32 = 1<<LocalConnIDBits32 - 1MaxLocalConnID64 = 1<<LocalConnIDBits64 - 1则定义了本地连接池容量(约 2^20 与 2^40)。

注意:设计文档中提到的KILL TIDB语法与compatible-kill-query配置项已废弃,本测试工具只针对新的全局 Kill 语义。

问题在于:生产环境中的关键超时参数(如 PD 断连判定、serverID 租约)默认长达数小时,不适合自动化测试。GlobalKillTest 正是为此而生——它通过编译期 ldflags 将这些变量压缩到秒级,再在真实 PD + TiKV + 多 TiDB 节点集群上验证各种 Kill 与断连场景。

二、工具总览与命令行参数

GlobalKillTest 由 run-tests.sh 驱动,其完整用法如下:

Usage: ./run-tests.sh [options] -h: Print this help message. -L <info|warn|error>: Log level of testing. Defaults to "info". --server_log_level <info|warn|error>: Log level of TiDB server. Defaults to "info". --tmp <temporary path>: Temporary files path. Defaults to "/tmp/tidb_globalkilltest". -s <tidb-server-path>: Use tidb-server in <tidb-server-path> for testing. Defaults to "bin/globalkilltest_tidb-server". --tidb_start_port <port>: First TiDB server listening port. port ~ port+2 will be used. Defaults to "5000". --tidb_status_port <port>: First TiDB server status listening port. port ~ port+2 will be used. Defaults to "8000". --pd <pd-client-path>: PD client path, ip:port list separated by comma. Defaults to "127.0.0.1:2379". --pd_proxy_port <port>: PD proxy port. PD proxy is used to simulate lost connection between TiDB and PD. Defaults to "3379". --conn_lost <timeout in seconds>: Lost connection to PD timeout, should be the same as TiDB ldflag <ldflagLostConnectionToPDTimeout>. See tidb/Makefile for detail. Defaults to "5". --conn_restored <timeout in seconds>: Time to check PD connection restored, should be the same as TiDB ldflag <ldflagServerIDTimeToCheckPDConnectionRestored>. See tidb/Makefile for detail. Defaults to "1".

参数要点与源码对照

这些 flag 与 global_kill_test.go 中的定义一一对应:

命令行参数测试内 flag默认值作用
-L-Linfo测试自身日志级别
--server_log_levelserver_log_levelinfo被拉起 TiDB server 的日志级别
--tmptmp/tmp/tidb_globalkilltest临时文件路径(日志、数据目录、mocktikv 路径等)
-ssbin/globalkilltest_tidb-server被测 TiDB server 二进制路径
--tidb_start_porttidb_start_port5000首个 TiDB 监听端口,占用 port ~ port+2
--tidb_status_porttidb_status_port8000首个 TiDB 状态端口,占用 port ~ port+2
--pdpd127.0.0.1:2379PD 客户端地址,逗号分隔的 ip:port 列表
--conn_lostconn_lost5PD 断连超时(秒),须与 TiDB ldflagldflagLostConnectionToPDTimeout一致
--conn_restoredconn_restored1PD 连接恢复检测周期(秒),须与 ldflagldflagServerIDTimeToCheckPDConnectionRestored一致

关键点是后两个参数必须与编译进被测二进制中的 ldflag 取值严格一致——它们决定了"断连多久后 TiDB 判定超时并杀掉连接/拒绝新连接"以及"恢复后多久重新接受连接",测试用它精确控制时序。此外 global_kill_test.go 还定义了-p(pd-server 路径,默认 bin/pd-server)、-k(tikv-server 路径,默认 bin/tikv-server)两个二进制参数,run-tests.sh的 help 中同样包含这两项。

三、环境准备:构建被测二进制与准备集群

1. 构建带测试 hack 的 TiDB 二进制

测试要求使用经过特殊编译的 TiDB server。执行:

cd tests/globalkilltest make

Makefile 通过 ldflags 注入一组覆盖默认值的变量,这正是"把数小时超时压缩到秒级"的关键:

-X "github.com/pingcap/tidb/pkg/domain.ldflagIsGlobalKillTest=1" -X "github.com/pingcap/tidb/pkg/domain.ldflagServerIDTTL=10" -X "github.com/pingcap/tidb/pkg/domain.ldflagServerIDTimeToKeepAlive=1" -X "github.com/pingcap/tidb/pkg/domain.ldflagServerIDTimeToCheckPDConnectionRestored=1" -X "github.com/pingcap/tidb/pkg/domain.ldflagLostConnectionToPDTimeout=5" -X "github.com/pingcap/tidb/pkg/store.ldflagGetEtcdAddrsFromConfig=1" -X "github.com/pingcap/tidb/pkg/util/globalconn.ldflagIsGlobalKillTest=1" -X "github.com/pingcap/tidb/pkg/util/globalconn.ldflagServerIDBits32=2" -X "github.com/pingcap/tidb/pkg/util/globalconn.ldflagLocalConnIDBits32=4"

这些变量的生产默认值定义在 pkg/domain/domain.go(如ldflagServerIDTTL = "10"ldflagLostConnectionToPDTimeout = "5",单位为秒)与 pkg/util/globalconn/globalconn.go(如ldflagLocalConnIDBits32 = "20")。测试版将其中的ldflagServerIDBits32压缩为 2 bit、ldflagLocalConnIDBits32压缩为 4 bit,从而让 32 位连接池极小、极易触达上限,方便在短时间内验证 32/64 位升级与降级逻辑。构建成功后输出:

Build TiDB Server (Global Kill Test) successfully! Setup a cluster with PD & TiKV, then Run ./run-tests.sh --pd=<pd client path>.

2. 准备 PD 与 TiKV 二进制(TiUP 方式)

测试需要一个真实集群(PD + TiKV),可通过 TiUP 下载 nightly 二进制:

cd tests/globalkilltest mkdir -p bin tiup install pd:nightly tikv:nightly cp ~/.tiup/components/pd/$(ls ~/.tiup/components/pd | tail -1)/pd-server bin/ cp ~/.tiup/components/tikv/$(ls ~/.tiup/components/tikv | tail -1)/tikv-server bin/

3. Docker 一键方式

如果环境具备 Docker,可直接运行 up.sh,它会自动完成二进制下载与make

cd tests/globalkilltest ./up.sh

其内部逻辑为:先tiup install pd:nightly tikv:nightly并拷贝到bin/,然后基于 Dockerfile(基于 rockylinux:9,安装 Development Tools、procps-ng、mysql 客户端与 Go 1.21.13)构建globalkilltest镜像,最后挂载整个 TiDB 仓库到/tidb并在容器内执行make && ./run-tests.sh。如需查看日志,可额外挂载卷到/tmp,例如-v $TIDB_PATH/tmp:/tmp

说明:测试在启动 TiDB 时使用了 tikv.toml(reserve-space = "1KB"),并分别通过 config.toml(enable-global-kill=true,启用 32 位测试)与 config-64.toml(enable-global-kill=trueenable-32bits-connection-id=false,强制 64 位)驱动不同模式。enable-global-kill是 TiDB 的核心开关,见 pkg/config/config.go,默认即为true(config.go)。

四、七大测试场景

GlobalKillTest 覆盖以下场景(对应设计文档中 Scenario A–E 的自动化子集):

  1. 无 PD 的单 TiDB:被 Ctrl+C 终止、被KILL终止;
  2. 带 PD 的单 TiDB:被 Ctrl+C 终止、被KILL终止;
  3. 多 TiDB 节点:分别通过{本地, 远程} × {Ctrl-C, KILL}组合终止连接;
  4. 断连 PD 后,存量连接被终止(长时间断连超时后);
  5. 断连 PD 后,不再接受新连接
  6. 断连 PD 后恢复,新连接可被接受
  7. 断连 PD 后恢复,连接可被 Kill(同场景 3)。

这些场景在 global_kill_test.go 中分别由TestWithoutPDTestOneTiDBTestMultipleTiDBTestLostConnection(内部覆盖场景 4–7)实现,每个测试又分为 32 位变体(如TestWithoutPD32TestLostConnection32)与默认变体。

五、工作原理:SLEEP 载荷 + 秒级超时 hack

README 明确了该工具的两个核心设计:

  • 超时变量 hack:TiDB 由 Makefile 编译时覆盖上述超时变量,因为这些变量的默认值(数小时)对自动化测试而言太长;
  • SLEEP 探针:以SELECT SLEEP(x)作为查询载荷,并在 x 秒到期之前 Kill 该查询。若查询无错误且实际耗时小于 x,则测试 PASSED。

以场景 3 的远程 Kill 为例,代码逻辑为:在 tidb1 上取得连接 connID1,随后在 tidb2 的连接上执行KILL QUERY <connID1>,若远程查询在 2 秒内被终止则断言通过(见 global_kill_test.go)。这实际验证了"从 connID 中提取 serverID → 通过CLUSTER_INFO定位目标实例 → 重定向 Kill 请求"的整条链路。

值得注意的是Ctrl+C 与 64 位 connID 的兼容性边界testKillByCtrlC通过向 mysql CLI 进程发送os.Interrupt模拟 Ctrl+C。在 32 位模式下断言 SLEEP 提前结束(elapsed < sleepTime);而在 64 位模式下断言其不会提前结束(global_kill_test.go),因为 mysql 客户端会把 64 位 connID 截断为 32 位,导致该 Ctrl+C 被 TiDB 忽略(日志中会出现截断警告)。这是设计文档"64 位 connID 与旧 32 位客户端不兼容"论断在测试中的直接体现。

六、使用方式:集成回归与手动单测

集成测试回归(提交后、合并前)

在 TiDB 仓库tests/globalkilltest目录下依次执行:

cd tests/globalkilltest make ./run-tests.sh

run-tests.sh 会在测试前后调用clean_cluster()pkill -9清理 tidb-server / tikv-server / pd-server 残留进程),然后通过go test -args $*运行全部用例,保证测试环境的干净隔离。

手动运行单个用例

TestMultipleTiDB为例:

cd tests/globalkilltest make go test -check.f TestMultipleTiDB -args --pd=<pd client path>

这里-check.f是 gocheck 框架的过滤器(工具仍兼容 gocheck 风格用法);也可用 Go 原生过滤,如go test -test.run MultipleTiDB -args --pd=127.0.0.1:2379。所有用例要求--pd指向一个已就绪的 PD 客户端地址,否则会以connect PD err: ...失败并提示"Establish a cluster with PD & TiKV, and provide PD client path by --pd=ip:port[,ip:port]"。

七、更深一层:测试基础设施与可扩展验证

除了七大场景,测试框架还提供了多组补充用例,值得手工复跑:

  • ServerID 升级/降级TestServerIDUpgradeAndDowngrade):通过 ldflags 将ldflagServerIDBits32压到 2 bit,使 32 位 serverID 池容量极小。先启动 2 个 TiDB 验证 connID 为 32 位,再扩容验证新实例自动升级到 64 位,最后关闭部分实例验证回落到 32 位;
  • LocalConnID 升级/降级TestConnIDUpgradeAndDowngrade):将ldflagLocalConnIDBits32压到 4 bit,占满 32 位本地连接池后验证升级 64 位,释放超过一半连接后再验证降级回 32 位(对应设计文档 Scenario B/D);
  • 空闲连接上的 KillTestKillQueryOnIdleConnection):验证KILL QUERY只终止当前查询而连接保持存活,KILL CONNECTION则彻底关闭连接。

以上测试全部基于 main_test.go 的TestMain初始化,并通过 util.go 中的checkPDHealth(轮询/health)、checkTiKVStatus(轮询127.0.0.1:20180/status)、checkTiDBStatus(轮询<statusPort>/status)做就绪探测,超时分别设为 10s / 30s / 60s(首次启动 TiDB 较慢)。测试开始时还会通过 etcd client 连接 PD 获取当前成员,并记录集群clusterID用于隔离数据目录。

八、快速参考:文件清单

文件作用
tests/globalkilltest/README.md工具说明(本文主体)
tests/globalkilltest/Makefile以 ldflags 压缩超时/池大小变量的专用构建
tests/globalkilltest/run-tests.sh一键回归入口,自动清理残留进程
tests/globalkilltest/up.shDocker 一键准备 + 构建 + 运行
tests/globalkilltest/Dockerfile测试镜像(rockylinux:9 + Go 1.21.13 + mysql 客户端)
tests/globalkilltest/global_kill_test.go全部测试用例与集群编排逻辑
tests/globalkilltest/util.goPD / TiKV / TiDB 就绪探测
tests/globalkilltest/config.toml32 位模式配置(enable-global-kill=true
tests/globalkilltest/config-64.toml64 位模式配置(额外enable-32bits-connection-id=false
docs/design/2020-06-01-global-kill.mdGlobal Kill 特性设计文档
pkg/util/globalconn/globalconn.goconnID 编解码与本地连接池实现
pkg/domain/domain.goserverID 获取/租约/断连超时实现与 ldflag 默认值
pkg/config/config.goenable-global-kill配置项定义

九、结语

GlobalKillTest 是一套"小而完整"的端到端测试体系:它用编译期 ldflags 将不可测的长时间超时收敛到秒级,以SELECT SLEEP(x)作为精确的时序探针,在真实 PD + TiKV 集群上覆盖了全局 Kill 的全部关键行为——本地/远程 Kill、32/64 位切换、PD 断连的容错与恢复。无论是作为 CI 集成回归、还是针对 Global Kill 行为的手动验证,这套工具都能给出确定性的通过/失败结论,是理解 TiDB 全局连接 ID 机制最直接的实验场。

【免费下载链接】tidbTiDB is built for agentic workloads that grow unpredictably, with ACID guarantees and native support for transactions, analytics, and vector search. No data silos. No noisy neighbors. No infrastructure ceiling.项目地址: https://gitcode.com/GitHub_Trending/ti/tidb

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 15:06:24

5 分钟让老 SWF 重新跑起来:Ruffle Flash 模拟器上手指南

5 分钟让老 SWF 重新跑起来&#xff1a;Ruffle Flash 模拟器上手指南 【免费下载链接】ruffle A Flash Player emulator written in Rust 项目地址: https://gitcode.com/GitHub_Trending/ru/ruffle Ruffle 是一个用 Rust 编写的 Flash 模拟器&#xff0c;面向需要打开 …

作者头像 李华
网站建设 2026/9/10 15:03:50

告别混乱交互:Telegraf场景管理与Wizard系统的7个实战技巧

告别混乱交互&#xff1a;Telegraf场景管理与Wizard系统的7个实战技巧 你是否还在为Telegram机器人的多步骤交互头疼&#xff1f;用户输入混乱、对话逻辑跳转复杂、状态管理繁琐——这些问题让许多开发者望而却步。本文将系统讲解Telegraf框架中场景管理与Wizard系统的核心用法…

作者头像 李华