news 2026/9/10 16:37:14

TiDB IntegrationTest 集成测试套件实战指南:运行、录制与调试执行计划回归测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TiDB IntegrationTest 集成测试套件实战指南:运行、录制与调试执行计划回归测试

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.testselect.testindex_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 TABLEINSERT、若干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):

  1. 解压s.zip提取统计信息(extract_stats函数,使用unzip -qq s.zip);
  2. 默认构建测试用二进制:TiDB-Server(输出为integrationtest_tidb-server)与mysql_tester(一个 MySQL 协议驱动的测试执行器,通过go install github.com/pingcap/mysql-tester/src安装);
  3. 自动挑选两个空闲端口(从 4000 起探测,find_multiple_available_ports),一个作为 SQL 服务端口、一个作为 status 端口;
  4. 以 config.toml(或禁用新排序规则时的disable_new_collation.toml)启动tidb-server,默认使用-store unistore(内存/本地存储引擎),即不依赖外部集群;
  5. 运行mysql_tester执行测试并对比结果,测试日志输出到integration-test.out
  6. 通过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 端口空闲:

  • PD23792380238123832384(3 个 PD 实例的 client/peer 端口);
  • TiKV201602016120162(存储端口)与201802018120182(status 端口);
  • tikv-worker19000(远程压缩/共享存储 worker)。

此外,引导脚本还会在9000端口启动一个 MinIO(S3 兼容对象存储,用于创建next-gen-testbucket),并可根据STARTER_COLUMNAR_AP环境变量选择是否额外拉起 TiFlash Compute 节点。集群启动后 sleep 10 秒等待就绪,再进入测试阶段。


三、脚本选项详解

run-tests.sh选项全表

以下为 run-tests.sh 中help_messagegetopts解析逻辑所定义的全部选项:

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=1mysql_tester会附加--record参数;-r all录制全部用例,-r <name>只录制指定用例。录制时同时开启--check-error=true以校验 SQL 错误。
  • 新排序规则双轮执行collation_opt控制执行轮次。默认-d bcollation_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.resultcollation_misc_disabled.result成对存在的原因。
  • -c选项getopts字符串中的c:目前没有对应 case 分支,属于预留项,实际使用请忽略。

新一代 Runner 的附加说明

  • run-tests-next-gen.shrun-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 源码,整个测试闭环如下:

  1. 准备阶段:解压s.zip→ 构建/定位tidb-servermysql_tester→ 探测空闲端口;
  2. 启动阶段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 服务;
  3. 执行阶段mysql_tester -port <port> --check-error=true --collation-disable=<true|false>运行用例,--collation-disable与脚本的-d选择联动;
  4. 对比阶段mysql_tester将实际输出与r/*.result逐行对比,任何差异(包括结果集内容与 SQL 报错)都会判失败;
  5. 清理与校验kill -15关闭 TiDB-Server,等待进程退出;check_data_race在经典模式下扫描integration-test.out,发现DATA RACE即打印日志并以非零码退出——竞态检测因此成为回归流程的硬性门槛。

五、典型工作流

1. 代码改动后的回归测试

修改 TiDB 代码(尤其是优化器、执行器)后,运行:

make dev

或只跑集成测试部分:

make integrationtest

make 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. 新增或更新测试用例

  1. 在 tests/integrationtest/t 下新增xxx.test文件,或向已有文件追加 SQL 语句;

  2. 生成期望结果:

    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

  1. 在项目根目录.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。

  2. 打开Run and Debug视图按F5启动 TiDB-Server;

  3. 用任意 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 个 PDpd-0/1/2),peer 端口2380/2381/2383,client 端口2379/2382/2384--force-new-cluster强制初始化;
  • 3 个 TiKVtikv-0/1/2),监听20160/20161/20162,status 端口20180/20181/20182,均指向 3 个 PD 的 client 地址;
  • 1 个 tikv-worker:监听19000,用于远程压缩与共享存储(DFS)场景;
  • 1 个 MinIO9000端口,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.testexplain.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),仅供参考

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

chrome-devtools-mcp 在 WSL 中无法启动 Chrome 怎么排查?

chrome-devtools-mcp 在 WSL 中无法启动 Chrome 怎么排查&#xff1f; 【免费下载链接】chrome-devtools-mcp Chrome DevTools for coding agents 项目地址: https://gitcode.com/GitHub_Trending/chr/chrome-devtools-mcp 在 WSL 里运行 chrome-devtools-mcp&#xff0…

作者头像 李华
网站建设 2026/9/10 16:32:30

“查不出毛病“ 的失眠,怎么调?知医邦冲调栀子豉汤的合方实践

前言&#xff1a;从3亿失眠人群说起中国睡眠研究会的数据显示&#xff0c;超过 3 亿中国人有睡眠障碍&#xff0c;成年人失眠发生率达 38.2%。但更值得关注的是&#xff0c;其中相当一部分人查不出任何器质性病变&#xff0c; 脑电图正常&#xff0c;激素水平正常&#xff0c;西…

作者头像 李华