TiDB IntegrationTest 集成测试套件实战指南:运行、录制与调试执行计划回归测试
【免费下载链接】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
导读
tests/integrationtest是 TiDB 的集成测试套件,它以"SQL 输入 + 期望输出"的黄金文件(golden file)模式,系统性地验证 TiDB 的执行计划(EXPLAIN 输出)、查询结果与端到端行为。本文基于 tests/integrationtest/README.md 展开,覆盖经典 Runnerrun-tests.sh与新一代基于真实 TiKV 集群的 Runnerrun-tests-next-gen.sh,并深入脚本源码说明每个选项的行为、结果录制机制与调试方法。读完本文,你将掌握如何运行全部集成测试、如何用-r生成新的期望结果、如何在 VSCode/Goland 中单步调试 TiDB-Server,以及新老两套 Runner 的底层差异。
一、套件概览:目录结构与工作模式
集成测试套件位于 tests/integrationtest 目录,其核心资产分为四类:
| 路径 | 作用 |
|---|---|
| t/ | 测试用例输入,共 258 个*.test文件,按模块分子目录(ddl/、executor/、expression/、planner/等),也有explain.test、select.test、index_merge.test等平铺用例 |
| r/ | 期望输出,与t/一一对应的*.result文件,同样按模块组织 |
| s.zip | 打包的统计信息(statistics),用于s/*.json统计数据的加载,保证 EXPLAIN 类用例在固定统计信息下输出稳定 |
| config.toml、disable_new_collation.toml | 启动 TiDB-Server 用的配置文件,区别在于new_collations_enabled_on_first_bootstrap是否为true |
以最基础的 t/select.test 为例,测试内容就是一段可执行的 SQL 脚本(CREATE TABLE、INSERT、若干SELECT),而对应的 r/select.result 则是每条 SQL 的期望输出——SQL 语句原样回显,随后紧跟制表符分隔的结果集:
SELECT * from t; c1 c2 c3 1 2 3 SELECT c1 as a, c2 as a from t; a a 1 2整个套件的执行模型是:对每条t/*.test中的 SQL,执行后与r/*.result逐字对比;统计信息从s.zip解压出的s/*.json加载;当执行计划或行为发生变化时,对比失败即测试失败。这种模式特别适合捕捉执行计划变更这类难以用断言函数描述的回归。
二、Quick Start:两种 Runner
1. 经典 Runner:run-tests.sh
使用默认配置运行全部集成测试:
./run-tests.sh该脚本的完整行为链(详见 run-tests.sh):
- 解压
s.zip提取统计信息(extract_stats函数,使用unzip -qq s.zip); - 默认构建测试用二进制:TiDB-Server(输出为
integrationtest_tidb-server)与mysql_tester(一个 MySQL 协议驱动的测试执行器,通过go install github.com/pingcap/mysql-tester/src安装); - 自动挑选两个空闲端口(从 4000 起探测,
find_multiple_available_ports),一个作为 SQL 服务端口、一个作为 status 端口; - 以 config.toml(或禁用新排序规则时的
disable_new_collation.toml)启动tidb-server,默认使用-store unistore(内存/本地存储引擎),即不依赖外部集群; - 运行
mysql_tester执行测试并对比结果,测试日志输出到integration-test.out; - 通过
trap在退出时清理所有后台进程,并在结束时检查日志中的DATA RACE(详见下文"数据竞态检查")。
注:脚本固定
export TZ="Asia/Shanghai",确保时间函数类用例(如NOW()、FROM_UNIXTIME)在不同机器上输出一致,这是黄金文件对比稳定的关键前提。
2. 新一代 Runner:run-tests-next-gen.sh(真实 TiKV 集群)
./run-tests-next-gen.sh [run-tests.sh options]从源码看(run-tests-next-gen.sh),它做的事非常直接:
- 导出
TIDB_TEST_STORE_NAME="tikv"和TIKV_PATH="127.0.0.1:2379",把存储后端切换为真实 TiKV; - 调用 tests/realtikvtest/scripts/next-gen/bootstrap-test-with-cluster.sh 引导真实集群;
- 引导完成后以
NEXT_GEN=1环境变量调用run-tests.sh,把你的全部选项原样透传。
这意味着所有run-tests.sh支持的选项都可以传给run-tests-next-gen.sh。
端口占用要求
run-tests-next-gen.sh会拉起一整套 TiDB 生态组件,需要以下 TCP 端口空闲:
- PD:
2379、2380、2381、2383、2384(3 个 PD 实例的 client/peer 端口); - TiKV:
20160、20161、20162(存储端口)与20180、20181、20182(status 端口); - tikv-worker:
19000(远程压缩/共享存储 worker)。
此外,引导脚本还会在9000端口启动一个 MinIO(S3 兼容对象存储,用于创建next-gen-testbucket),并可根据STARTER_COLUMNAR_AP环境变量选择是否额外拉起 TiFlash Compute 节点。集群启动后 sleep 10 秒等待就绪,再进入测试阶段。
三、脚本选项详解
run-tests.sh选项全表
以下为 run-tests.sh 中help_message与getopts解析逻辑所定义的全部选项:
Usage: ./run-tests.sh [options] -h: 打印帮助信息。 -d <y|Y|n|N|b|B>: 控制新排序规则(new collation)特性: "y" 或 "Y": 测试期间只启用新排序规则。 "n" 或 "N": 测试期间只禁用新排序规则。 "b" 或 "B": 对以 `collation` 前缀命名的用例同时跑启用/禁用两轮, 其余用例只启用 [默认值]。 -s <tidb-server-path>: 使用指定路径的 tidb-server 二进制进行测试。 示例: ./run-tests.sh -s ./integrationtest_tidb-server -b <y|Y|n|N>: 是否构建测试二进制: "y" 或 "Y": 构建 [默认]。 "n" 或 "N": 不构建。 (若提供了 -s,则跳过 tidb-server 的构建。) -r <test-name>|all: 运行指定的一个或多个测试用例,并将结果录制到 r/<test-name>.result。 示例: ./run-tests.sh -r select 使用 "all" 录制全部测试的结果。 -t <test-name>: 运行指定的测试用例(若同时提供了 -r 则忽略 -t)。 示例: ./run-tests.sh -t select 不提供时运行全部测试。 -v <vendor-path>: 将 <vendor-path> 加入 $GOPATH。 -p <portgenerator-path>: 使用指定的端口生成器进行端口分配。此外,脚本还支持帮助信息中未列出、但getopts "t:s:r:b:d:c:i:P:h"明确解析的-P <port>选项:直接连接一个已经运行在指定端口上的 tidb-server进行测试(runs_on_port非零时自动跳过构建与自启服务器)。这为"外部已启动集群 + 复用二进制"的场景提供了便利。
选项组合的行为细节(源码级)
- 构建策略:
build=1时,若未指定-s则调用build_tidb_server——当TIDB_TEST_STORE_NAME=tikv时执行make -C ../.. server SERVER_OUT=$tidb_server(不带 race),否则追加RACE_FLAG="-race"(即经典模式默认开启竞态检测编译);mysql_tester则统一通过go install构建。 - 录制模式:
-r使record=1,mysql_tester会附加--record参数;-r all录制全部用例,-r <name>只录制指定用例。录制时同时开启--check-error=true以校验 SQL 错误。 - 新排序规则双轮执行:
collation_opt控制执行轮次。默认-d b(collation_opt=2)时,脚本先以enabled_new_collation=0(使用disable_new_collation.toml,对应new_collations_enabled_on_first_bootstrap=false)跑一轮,再以enabled_new_collation=1(使用config.toml,对应new_collations_enabled_on_first_bootstrap=true)跑一轮;-d y只跑启用轮,-d n只跑禁用轮。check_case_name函数做了更细的优化:非b模式下,若用例名以collation开头则自动按双轮处理,否则只启用新排序规则。这也解释了r/目录中collation_misc_enabled.result与collation_misc_disabled.result成对存在的原因。 -c选项:getopts字符串中的c:目前没有对应 case 分支,属于预留项,实际使用请忽略。
新一代 Runner 的附加说明
run-tests-next-gen.sh把run-tests.sh的所有选项原样透传,因此-r、-t、-s等均可用;- 由于它强制
TIDB_TEST_STORE_NAME=tikv,TiDB-Server 将以-store tikv -path 127.0.0.1:2379连接真实 PD/TiKV; - 引导脚本会临时创建数据目录并在结束后
killall清理 PD/TiKV/tikv-worker/MinIO 进程,同时执行make failpoint-disable复位 failpoint 状态。
四、工作原理:黄金文件对比闭环
结合 run-tests.sh 源码,整个测试闭环如下:
- 准备阶段:解压
s.zip→ 构建/定位tidb-server与mysql_tester→ 探测空闲端口; - 启动阶段:
start_tidb_server依据存储后端与 NEXT_GEN 模式拼装启动参数:- 经典模式:
-store unistore -path ''; - 真实 TiKV 模式:
-store tikv -path ${TIKV_PATH}; - 新一代模式(
NEXT_GEN非空且非0/false)额外追加-keyspace-name SYSTEM --tidb-service-scope dxf_service,即按 keyspace 与 service-scope 方式接入分布式 TiDB 服务;
- 经典模式:
- 执行阶段:
mysql_tester -port <port> --check-error=true --collation-disable=<true|false>运行用例,--collation-disable与脚本的-d选择联动; - 对比阶段:
mysql_tester将实际输出与r/*.result逐行对比,任何差异(包括结果集内容与 SQL 报错)都会判失败; - 清理与校验:
kill -15关闭 TiDB-Server,等待进程退出;check_data_race在经典模式下扫描integration-test.out,发现DATA RACE即打印日志并以非零码退出——竞态检测因此成为回归流程的硬性门槛。
五、典型工作流
1. 代码改动后的回归测试
修改 TiDB 代码(尤其是优化器、执行器)后,运行:
make dev或只跑集成测试部分:
make integrationtestmake integrationtest的实际命令(见根目录 Makefile 中integrationtest目标,第 188-192 行)为:
integrationtest: server_check @cd tests/integrationtest && GOCOVERDIR=../../$(TEST_COVERAGE_DIR) ./run-tests.sh -s ../../bin/tidb-server即它会先复用bin/tidb-server(-s指定,跳过重复构建),并开启覆盖率收集(GOCOVERDIR)。如果你的改动影响了执行计划,这里会立刻报出r/*.result的 diff,从而定位回归。
2. 新增或更新测试用例
在 tests/integrationtest/t 下新增
xxx.test文件,或向已有文件追加 SQL 语句;生成期望结果:
cd tests/integrationtest ./run-tests.sh -r [casename]脚本会执行
t/<casename>.test并把输出录制到r/<casename>.result。生成后请人工审阅.result内容是否符合预期(尤其是 EXPLAIN 输出),再提交t/、r/两个文件。
3. 运行单个用例快速验证
./run-tests.sh -t select # 只跑 select 用例 ./run-tests.sh -t executor/xxx # 跑子目录下的用例4. 连接外部已有 TiDB-Server
./run-tests.sh -P 4000 # 复用 4000 端口上已启动的 tidb-server六、调试集成测试
VSCode
在项目根目录
.vscode/launch.json中添加如下调试配置(示例来自 README,可自行调整配置文件或后端):{ "version": "0.2.0", "configurations": [ { "name": "Debug TiDB With Default Config", "type": "go", "request": "launch", "mode": "auto", "program": "${fileWorkspaceFolder}/cmd/tidb-server", "args": ["--config=${fileWorkspaceFolder}/pkg/config/config.toml.example"] } ] }若需要改配置(例如切换到 TiKV 后端运行集成测试),可以修改 pkg/config/config.toml.example。TiDB-Server 入口位于 cmd/tidb-server。
打开Run and Debug视图按F5启动 TiDB-Server;
用任意 MySQL 客户端连接(默认端口
4000,用户root,无密码):mysql --comments --host 127.0.0.1 --port 4000 -u root之后就可以手工执行 SQL、打断点观察执行计划生成过程。
Goland
可参考仓库内开发文档(如根目录 CLAUDE.md 与 docs/agents 中的开发指南)了解 IDE 配置;核心思路与 VSCode 一致:以调试模式启动cmd/tidb-server(带或不带 TiKV 均可),再用 MySQL 客户端连接 4000 端口执行 SQL。对集成测试用例本身,也可以在mysql_tester或 TiDB-Server 源码上打断点,结合-t <case>复现具体用例。
七、进阶:新一代集群引导内部
如果你关心run-tests-next-gen.sh到底拉起了什么,tests/realtikvtest/scripts/next-gen/bootstrap-test-with-cluster.sh 给出了完整答案:
- 3 个 PD(
pd-0/1/2),peer 端口2380/2381/2383,client 端口2379/2382/2384,--force-new-cluster强制初始化; - 3 个 TiKV(
tikv-0/1/2),监听20160/20161/20162,status 端口20180/20181/20182,均指向 3 个 PD 的 client 地址; - 1 个 tikv-worker:监听
19000,用于远程压缩与共享存储(DFS)场景; - 1 个 MinIO:
9000端口,bucket 固定为next-gen-test(访问密钥默认minioadmin/minioadmin),供 TiFlash 与 tikv-worker 的 S3 存储使用; - 可选 TiFlash Compute:当
STARTER_COLUMNAR_AP为真时启动,采用tiflash_compute拆分布式模式,通过 MinIO 提供对象存储,用于覆盖列式引擎相关用例。
集群数据目录由mktemp -d动态创建,测试结束由cleanup统一销毁并复位 failpoint,保证每次运行环境干净可复现。
八、注意事项速查
- 测试存储:默认
unistore(无需外部依赖、开 race 检测);需要真实 TiKV 时请用run-tests-next-gen.sh,并确保上述端口未被占用; - 新排序规则:
-d b是默认双轮模式;以collation开头的用例天然覆盖启用/禁用两种配置; - 时区稳定性:脚本强制
TZ=Asia/Shanghai,修改本机时区不会影响时间类用例结果; - 结果录制:
-r会覆盖对应r/*.result,提交前务必人工确认新输出; - 新增用例:
t/与r/必须成对维护,统计信息相关的用例还需关注s.zip内的s/*.json; - 更多用例结构细节:可直接参考 tests/integrationtest/t 目录下既有
*.test文件的注释与写法(如select.test、explain.test、各模块子目录)。
结语
tests/integrationtest是 TiDB 执行计划与行为回归的最后一道防线:它以最小化的"SQL + 期望输出"格式覆盖了 planner、executor、DDL、表达式、统计信息等核心模块,既能跑在轻量的 unistore 上做快速回归,也能通过run-tests-next-gen.sh在真实 PD/TiKV 集群(乃至 TiFlash)上进行端到端验证。掌握-r录制、-t定点运行与 IDE 调试三板斧,你就能在修改执行计划相关代码后快速定位回归,并为新特性低成本地补充黄金文件测试。
【免费下载链接】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),仅供参考