IT评测·应用市场-qidao123.com技术社区

标题: 特性介绍 | MySQL 测试框架 MTR 系列教程(一):入门篇 [打印本页]

作者: 我可以不吃啊    时间: 2023-4-17 01:23
标题: 特性介绍 | MySQL 测试框架 MTR 系列教程(一):入门篇
作者:卢文双 资深数据库内核研发
去年年底通过微信公众号【数据库内核】设定了一个目标——2023 年要写一系列 特性介绍+内核解析 的文章(现阶段还是以 MySQL 为主)。
虽然关注者很少,但本着“说到就要做到”的原则,从这篇就开始了。
序言:
以前对 MySQL 测试框架 MTR 的使用,主要集中于 SQL 正确性验证。近期由于工作需要,深入了解了 MTR 的方方面面,发现 MTR 的能力不仅限于此,还支持单元测试、压力测试、代码覆盖率测试、内存错误检测、线程竞争与死锁等功能,因此,本着分享的精神,将其总结成一个系列。
主要内容如下:
由于个人水平有限,所述难免有错误之处,望雅正。
本文是第一篇入门篇
本文首发于 2023-03-18 21:58:52
本系列基于 MySQL 8.0.29 版本,且主要在 Ubuntu 22.04 X86_64 验证(部分指令也在 Ubuntu 20.04 X86_64、Ubuntu 22.04 ARM64、MacOS M1 做了验证),如有例外,会特别说明。
简介

在修改内核代码后,不仅需要测试新增功能,同时也要对原有功能做回归测试,以保证新加代码对原有功能没有影响,这就需要用到 MySQL 源码自带的测试框架 mtr。
MySQL 测试框架是一个以 MySQL 框架和内部引擎为测试对象的工具,主要执行脚本在安装路径(make install后的路径)下的mysql-test目录,基本覆盖了所有 MySQL 的特性和异常情况。
MySQL 测试框架 mtr 主要包含如下几个组件:
除此之外,还提供了单元测试工具(严格来说不属于 mtr ),以便为存储引擎和插件创建单独的单元测试程序。
由于 MySQL 测试框架的入口是 mysql-test-run.pl(它会调用上述其他组件),因此,一般将 MySQL 测试框架简称为 mtr
mtr 工作原理

概述

mtr 采用t/r模式(t目录中存储具体的测试 case,文件以.test结尾;r目录中存储了对应 case 的期望结果,文件以.result结尾),主要测试步骤是“通过执行一个 case,将该 case 的输出结果,与标准的输出结果(期望结果)作 diff”:
如果t目录中的某个 case 在r目录中没有对应.result文件:
上文说的 case 是指一系列的语句,包括 SQL 语句和一些必要的 mysqltest command。
所有 case 可分为三部分,分别为:
框架流程

mysql-test-run.pl框架运行流程如下:
1、初始化(Initialization)
2、运行用例(run test)
主线程根据参数--parallel(默认是 1)启动一个或者多个用例执行线程(worker),各线程有自己独立的 client port,data dir 等。
启动的 worker 与主线程之间是 server-client 模式,主线程是 server,worker 是 client。
以 rpl.rpl_multi_source_basic 测试 case 为例来说明执行过程。
  1. # This is the basic test required in for multisource replication
  2. # The aim of this file is to test the basic usecases of msr.
  3. # 0. Create two masters and a slave and setup a multisource replication
  4. #    between them.
  5. # 1. create a different databases on each master and test if they are replicated
  6. #    to the slave.
  7. # 2. create a different table on each master and test if they are replicated to
  8. #    the to the slave.
  9. # 3. Create a table with the same name on both masters and update non conflicting
  10. #    data on that table. Test if the replication is done properly.
  11. # 4. Check if updates happen on different master such that the resulting
  12. #    data on slave is conflicting, check that one of the channels the slave
  13. #    SQL thread is stopped.
  14. #
  15. #
  16. # Note: Out of convention, server 2 is always made a slave for multisource testing.
复制代码
启动测试指令 perl mysql-test-run.pl --do-test=rpl_multi_source 后,会启动 3 个 mysqld 进程,其中 2 个 master 节点,1 个 slave 节点:
  1. ➜  rpl ps -xf | grep mysql
  2.    6982 pts/2    S+     0:00      \_ perl mysql-test-run.pl rpl_multi_source_basic
  3.    7125 pts/2    S+     0:00          \_ perl mysql-test-run.pl rpl_multi_source_basic
  4.    7130 pts/2    S+     0:00              \_ /data/work/mysql/mysql80-install.bak_valgrind/bin//mysqltest_safe_process -- /data/work/mysql/mysql80-install.bak_valgrind/bin/mysqld --defaults-group-suffix=.1 --defaults-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/my.cnf --log-output=file --loose-debug-sync-timeout=600 --binlog-format=mixed --core-file
  5.    7131 pts/2    Sl     0:04              |   \_ /data/work/mysql/mysql80-install.bak_valgrind/bin/mysqld --defaults-group-suffix=.1 --defaults-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/my.cnf --log-output=file --loose-debug-sync-timeout=600 --binlog-format=mixed --core-file
  6.    7132 pts/2    S+     0:00              \_ /data/work/mysql/mysql80-install.bak_valgrind/bin//mysqltest_safe_process -- /data/work/mysql/mysql80-install.bak_valgrind/bin/mysqld --defaults-group-suffix=.2 --defaults-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/my.cnf --log-output=file --loose-debug-sync-timeout=600 --binlog-format=mixed --core-file
  7.    7133 pts/2    Sl     0:06              |   \_ /data/work/mysql/mysql80-install.bak_valgrind/bin/mysqld --defaults-group-suffix=.2 --defaults-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/my.cnf --log-output=file --loose-debug-sync-timeout=600 --binlog-format=mixed --core-file
  8.    7134 pts/2    S+     0:00              \_ /data/work/mysql/mysql80-install.bak_valgrind/bin//mysqltest_safe_process -- /data/work/mysql/mysql80-install.bak_valgrind/bin/mysqld --defaults-group-suffix=.3 --defaults-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/my.cnf --log-output=file --loose-debug-sync-timeout=600 --binlog-format=mixed --core-file
  9.    7135 pts/2    Sl     0:04              |   \_ /data/work/mysql/mysql80-install.bak_valgrind/bin/mysqld --defaults-group-suffix=.3 --defaults-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/my.cnf --log-output=file --loose-debug-sync-timeout=600 --binlog-format=mixed --core-file
  10.    7283 pts/2    S+     0:00              \_ /data/work/mysql/mysql80-install.bak_valgrind/bin//mysqltest_safe_process -- /data/work/mysql/mysql80-install.bak_valgrind/bin/mysqltest --defaults-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/my.cnf --silent --tmpdir=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/tmp --character-sets-dir=/data/work/mysql/mysql80-install.bak_valgrind/share/charsets --logdir=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/log --database=test --plugin_dir=/data/work/mysql/mysql80-install.bak_valgrind/lib/plugin --timer-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/log/timer --test-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/suite/rpl/t/rpl_multi_source_basic.test --tail-lines=20 --result-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/suite/rpl/r/rpl_multi_source_basic.result
  11.    7284 pts/2    R      0:00                  \_ /data/work/mysql/mysql80-install.bak_valgrind/bin/mysqltest --defaults-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/my.cnf --silent --tmpdir=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/tmp --character-sets-dir=/data/work/mysql/mysql80-install.bak_valgrind/share/charsets --logdir=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/log --database=test --plugin_dir=/data/work/mysql/mysql80-install.bak_valgrind/lib/plugin --timer-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/var/log/timer --test-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/suite/rpl/t/rpl_multi_source_basic.test --tail-lines=20 --result-file=/data/work/mysql/mysql80-install.bak_valgrind/mysql-test/suite/rpl/r/rpl_multi_source_basic.result
复制代码
可见:
编译安装

安装依赖

mysql-server 编译需要:
  1. # for mysql 8.0
  2. sudo apt install gdb gcc g++ cmake -y
  3. sudo apt install openssl libssl-dev -y
  4. sudo apt install libncurses-dev libudev-dev -y
  5. sudo apt install bison flex libaio-dev libreadline-dev libjemalloc-dev -y
  6. sudo apt install libevent-dev zlib1g-dev libmecab-dev libgcrypt20-dev -y
  7. sudo apt install libsasl2-dev libldap2-dev libtirpc-dev
  8. sudo apt-get install libsasl2-dev # SASL
  9. sudo apt-get install slapd ldap-utils # LDAP
  10. sudo apt install valgrind doxygen libcurl4-gnutls-dev -y # extra
  11. # centos 7.6
  12. sudo yum install cmake gcc g++ # 由于 cmake、gcc 版本偏低,需要自行通过源码编译安装
  13. sudo yum install readline-devel bison flex libarchive openssl-devel
  14. sudo yum install rpcgen libudev-devel ncurses-devel libtirpc libtirpc-devel
  15. sudo yum install cyrus-sasl-devel # SASL
  16. sudo yum install openldap openldap-devel # LDAP
  17. sudo yum install valgrind # extra
  18. # centos stream 9
  19. sudo yum install cmake gcc g++ gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-binutils
  20. sudo yum install readline-devel bison flex libarchive openssl-devel # libtirpc-devel
  21. sudo yum install rpcgen libudev-devel ncurses-devel libtirpc libtirpc-devel
  22. sudo yum install cyrus-sasl-devel # SASL
  23. sudo yum install openldap openldap-devel # LDAP
  24. sudo yum install valgrind # extra
  25. # macos
  26. brew install lz4
  27. brew install zlib
  28. brew install clang
复制代码
由于系统及版本差异,这里罗列的软件包可能会有所缺失,版本也可能会有所不同。
对于 mtr 来说,也需要额外安装一些依赖:
  1. # centos
  2. yum -y install perl -y
  3. sudo yum install perl-JSON -y
  4. sudo yum install perl-Test-use-ok.noarch -y
  5. # ubuntu
  6. sudo apt install perl -y
  7. sudo perl -MCPAN -e 'install JSON'
复制代码
编译

Debug 版本编译选项示例:
  1. # for MacOS and Ubuntu
  2. CURDIR=`pwd`
  3. INSTALLDIR=$CURDIR/../../mysql80-install
  4. DATADIR=$CURDIR/../../mysql80-default-data
  5. BOOSTDIR=$CURDIR/../../boost_1_77_0
  6. rm CMakeCache.txt -f
  7. cmake .. \
  8. -DCMAKE_BUILD_TYPE=Debug \
  9. -DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
  10. -DSYSCONFDIR=/etc \
  11. -DMYSQL_DATADIR=$DATADIR \
  12. -DMYSQL_UNIX_ADDR=/tmp/mysqld.sock \
  13. -DMYSQL_TCP_PORT=3306 \
  14. -DWITH_MYISAM_STORAGE_ENGINE=1 \
  15. -DWITH_INNOBASE_STORAGE_ENGINE=1 \
  16. -DENABLED_LOCAL_INFILE=1 \
  17. -DWITH_DEBUG=1 \ # 必须是 debug 版本
  18. -DWITH_BOOST=$BOOSTDIR \
  19. -DWITH_SSL=/usr/local/openssl-1.1.1 \
  20. -DFORCE_INSOURCE_BUILD=1
  21. # -DWITH_ASAN=ON -DWITH_ASAN_SCOPE=ON -DWITH_UBSAN=ON \ # 选择启用哪些组件
  22. # -DWITH_VALGRIND=ON \
  23. # -DENABLE_GCOV=1 -DENABLE_GPROF=1 \
  24. if [ $? != 0 ]; then
  25.   exit 1
  26. fi
  27. # for MacOS, only need make
  28. make -j4
  29. make install
复制代码
Release 版本编译选项示例:
  1. #!/bin/bash
  2. # for MacOS and Ubuntu
  3. CURDIR=`pwd`
  4. # for 8.0.29
  5. INSTALLDIR=$CURDIR/../../mysql80-install
  6. #INSTALLDIR=/usr
  7. DATADIR=$CURDIR/../../mysql80-default-data
  8. BOOSTDIR=$CURDIR/../../boost_1_77_0
  9. rm CMakeCache.txt -f
  10. cmake .. \
  11. -DCMAKE_BUILD_TYPE=Release \
  12. -DBUILD_CONFIG=mysql_release \
  13. -DFEATURE_SET=community \
  14. -DWITH_EMBEDDED_SERVER=OFF \
  15. -DWITHOUT_ROCKSDB=ON \
  16. -DWITH_UNIT_TESTS=OFF \
  17. -DWITH_BOOST=$BOOSTDIR \
  18. -DFORCE_INSOURCE_BUILD=1 \
  19. -DCOMPILATION_COMMENT="MySQL build $(date +%Y%m%d.%H%M%S.$(git rev-parse --short HEAD))"
  20. #-DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
  21. #-DSYSCONFDIR=/etc \
  22. #-DMYSQL_DATADIR=$DATADIR \
  23. #-DWITH_MYISAM_STORAGE_ENGINE=1 \
  24. #-DWITH_INNOBASE_STORAGE_ENGINE=1 \
  25. #-DWITH_MEMORY_STORAGE_ENGINE=1 \
  26. #-DWITH_PARTITION_STORAGE_ENGINE=1 \
  27. if [ $? != 0 ]; then
  28.         exit 1
  29. fi
  30. # for MacOS, only need make
  31. make -j4
  32. make install
复制代码
-DCMAKE_BUILD_TYPE=type 选项说明:
The type of build to produce:
目录结构

编译安装后,mysql-test 目录树结构如下:
  1. mysql-test
  2. ├── README
  3. ├── README.gcov # 代码覆盖率测试说明,最后更新于2006年
  4. ├── README.stress # 压力测试说明,针对 mysql-stress-test.pl ,最后更新于2006年
  5. ├── collections # 该目录下的文件是官方推荐的回归测试指令集
  6. │   ├── README # 说明文档
  7. │   ├── coverage.ignore # 指定需要忽略代码覆盖率测试的目录
  8. │   ├── disabled.def # 列出需要临时禁用的测试用例,在运行测试时会跳过
  9. │   ├── disabled-asan.list # 除 disabled.def 文件所列用例之外,还需要临时禁用的测试用例
  10. │   ├── disabled-ubsan.list # 同上
  11. │   ├── disabled-valgrind.list # 同上
  12. │   ├── disabled_ndb.def # 仅在运行 MySQL Cluster 时才需要临时禁用的测试用例
  13.         # 适合每天都运行的回归测试指令集
  14.         # 涵盖 default suites、非 default suites、针对复制和binlog的扩展测试(区分不同的复制参数)、InnoDB 扩展测试(区分不同页面大小)
  15. │   ├── default.daily
  16.         # 由于 valgrind 运行比较耗时,因此,该指令集只能涵盖除 big-test 之外的所有 suites 。
  17.         # 需要编译时添加选项 -DWITH_DEBUG=1 -DWITH_VALGRIND=1 的情况下,才能执行 valgrind 测试。
  18.         # 注意:通过实测、分析代码,运行 mtr 时必须添加 --valgrind 选项才能用到 valgrind 组件。
  19. │   ├── default.daily-valgrind
  20.         # 适合每周运行一次的指令集,运行耗时能达到48小时。
  21.         # 是 default.daily 的超集,同时,还指定了 --debug-server 。
  22.         # 覆盖 default suites + 非 default suites + 复制和binlog的扩展 + InnoDB扩展 + 其他按周运行的指令集。
  23. │   ├── default.weekly
  24. │   ├── default.weekly-ndbcluster # 覆盖 default.daily + ndbcluster + 部分非默认指令集
  25. │   ├── default.weekly-protocol # 编译时需要设置 DWITH_TEST_TRACE_PLUGIN=1,只覆盖 main suite。
  26.         # 在启用 --big-test 和 --debug-server 选项的前提下,运行所有的指令集。
  27.         # 需要编译时添加选项 -DWITH_DEBUG=1 -DWITH_VALGRIND=1 的情况下,才能执行 valgrind 测试。
  28.         # 注意:通过实测、分析代码,运行 mtr 时必须添加 --valgrind 选项才能用到 valgrind 组件。
  29. │   ├── default.weekly-valgrind
  30. │   ├── default.weekly.basic # 在禁用 --big-test 选项的前提下,运行所有的指令集,即包含 default suites + 非 default suites。
  31.         # 适用于每次push代码时运行的指令集,能控制在一个小时内。
  32.         # 更适用于 mysql 5.7 版本。
  33. │   ├── default.push
  34. │   ├── default.push-ndbcluster # 分为 default suites + 与 ndbcluster 相关的指令集
  35. │   ├── default.push-valgrind # 分为 default suites(排除 rpl)+ ndb 相关 suites + group_replication suite
  36. │   ├── mysql-8.0-stage.push # 在 default.push 基础上,为 mysql-8.0-stage 扩展的测试用例,在merge到main分支前使用
  37. │   ├── mysql-8.0-stage.push.basic # mysql-8.0-stage.push 的子集
  38. │   ├── mysql-trunk-meb-itch.push # 文件为空
  39.         # default.push 的超集,目的是在 push 到 main 分支前,提前发现问题。
  40. │   ├── mysql-trunk-stage.push # 内容与 mysql-8.0-stage.push 一样,在merge到main分支前使用
  41. │   ├── mysql-trunk-stage.push.basic # mysql-trunk-stage.push 的子集
  42. │   └── mysql-trunk-tsan.push # 由于 ThreadSanitizer 非常慢,因此,只测试 main suite
  43. ├── extra # 不属于 main 和 其他 suites 的测试 case
  44. │   ├── binlog_tests
  45. │   │   ├── binlog.test
  46. │   │   ├── binlog_cache_stat.test
  47. │   │   ├── binlog_crash_safe_ddl.inc
  48. │   │   ├── binlog_ddl.inc
  49.         ......
  50. │   │   └── tmp_table.test
  51. │   └── rpl_tests
  52. │       ├── binlog_transaction_compression.inc
  53. │       ├── check_slave_delay.inc
  54.         ......
  55. │       └── type_conversions.test
  56. ├── lib # 测试框架相关依赖文件,里面主要是一些用perl实现的逻辑。
  57. │   ├── My
  58. │   │   ├── Config.pm
  59. │   │   ├── ConfigFactory.pm
  60.         ......
  61. │   │   └── Test.pm
  62. │   ├── mtr_cases.pm
  63.     ......
  64. ├── lock_order_dependencies.txt # mysql-test-run.pl 读取该文件来控制加锁顺序,与 --lock-order 选项有关。该文件非空。
  65. # 在 mtr 运行对应工具期间,比如 asan,对应的 .supp 文件用于指定需要跳过的测试用例。
  66. #
  67. # ASAN、LSAN、TSAN 出自谷歌的 Sanitizer 项目,包含了 ASAN、LSAN、MSAN、TSAN等内存、线程错误的检测工具。
  68. ├── asan.supp # ASAN(Address-Sanitizier),内存错误检测工具。早期是LLVM中的特性,后被加入GCC 4.8。
  69. ├── lsan.supp # LSAN(LeakSanitizer),内存泄漏检测工具,已集成在 ASAN(AddressSanitizer)中。
  70. ├── tsan.supp # TSAN(ThreadSanitizer),线程间数据竞争的检测工具。
  71. ├── valgrind.supp # Valgrind 是一个工具集。集成了:
  72.                   # Memcheck 内存错误检测器。
  73.                   # Cachegrind 缓存和分支预测分析器。
  74.                   # Callgrind 可生成缓存分析器的调用图。
  75.                   # Helgrind 线程错误检测器。
  76.                   # DRD 也是线程错误检测器。
  77.                   # Massif 堆分析器,它可以帮助程序使用更少的内存。
  78.                   # DHAT 一种不同类型的堆分析器。使用它可以了解块寿命,块利用率和布局效率低下的问题。
  79. ├── mtr -> ./mysql-test-run.pl # mysql-test-run.pl 脚本别名
  80. ├── mysql-stress-test.pl
  81. ├── mysql-test-run -> ./mysql-test-run.pl
  82. ├── mysql-test-run.dox
  83. ├── mysql-test-run.pl # mtr 入口文件,测试框架核心逻辑
  84. # include/ 目录包含.inc 文件,在测试用例中通过 source 命令引入,就像 C/C++ 的头文件。建议将多次重复使用的测试语句整合到 .inc 文件中。
  85. ├── include # include 下所有 *.inc 都会被 t/ 目录下的 *.test 引用
  86. │   ├── Load_data.inc
  87.     ......
  88. │   ├── json_lookup.inc
  89. │   ├── keyring_tests
  90. │   │   ├── binlog
  91. │   │   │   ├── rpl_binlog_cache_encryption.inc
  92.         ......
  93. │   ├── keyring_udf_keyring_plugin_loaded.inc
  94.     ......
  95. │   └── year-engine.test
  96. # t/ 和 r/ 目录分别对应于 main suite 的测试 case 和 期望结果。
  97. # 测试 case 以 .test 后缀结尾。
  98. # 另外还有 .opt 后缀文件,它里面指定了MySQL的参数。某些测试用例会涉及重启,在重启时可能会变更 mysql 参数,可能会用 .opt 文件中指定的参数。
  99. ├── t # 该目录下的每个 *.test 都对应一个测试 case 。
  100. │   ├── 1st.test
  101. │   ├── admin_interface.test
  102.     ......
  103. ├── r # 路径和命名 与 t/ 目录一一对应,表示对应测试用例的期望输出。
  104. │   ├── 1st.result
  105. │   ├── admin_interface.result
  106.     ......
  107. │   └── year-myisam.result
  108. ├── std_data # 测试所用的数据文件,某些测试 case 需要使用到。
  109. │   ├── 14897.frm
  110. │   ├── 256kb.json
  111. │   ├── 41_decimal.frm
  112. │   ├── 57import.zip
  113.     ......
  114. │   └── x_y_data.csv
  115. # 测试框架有 suite 的概念,每个 suite 为一个测试用例集合,默认的 suite 为 main,它的测试集合位于当前目录下的 t/ 目录。
  116. # 除了 main suite 之外,其他的 suite 基本都以子目录的形式存放于当前文件夹,比如 json、binlog 等。
  117. ├── suite # 本目录下每个子目录都包含 include/r/t 三个子目录,其中:
  118.           # include/*.inc 会被 t/*.test 引用
  119.           # t/*.test 是各个测试case的主文件
  120.           # r/*.result 是期望的测试输出
  121.           # 另外,t/ 与 r/ 路径中的文件是一一对应的。
  122. │   ├── audit_null
  123.     ......
  124. │   ├── innodb
  125. │   │   ├── include
  126. │   │   │   ├── alter_table_pk_no_sort.inc
  127.             ......
  128. │   │   ├── r
  129. │   │   │   ├── add_foreign_key.result
  130. │   │   │   ├── alter_crash.result
  131.             ......
  132. │   │   └── t
  133. │   │       ├── add_foreign_key.test
  134. │   │       ├── alter_crash.test
  135.             ......
  136. │   │       └── zlob_update_purge.test
  137. │   ├── innodb_fts
  138.     ......
  139. └── var # 测试开启后 mtr 创建的目录,用于存放测试过程产生的数据目录、日志等。
  140.     ├── data
  141.     │   ├── #ib_16384_0.dblwr
  142.         ......
  143.     ......
  144.     ├── my.cnf
  145.     ├── run
  146.     ├── std_data
  147.     │   ├── 14897.frm
  148.     ......
  149.     └── tmp
  150.         └── mysqld.1
复制代码
参数

参考:
常用参数

  1. # --extern  一般情况下mtr是启动自己的MySQL服务来进行测试,如果在启动时指定参数 --extern,则可以使用指定的 MySQL 服务进行测试
  2. ./mtr --extern host=192.168.6.1 --extern port=3306 --extern user=root --extern password='123456'  --record --force example.1
  3. ./mtr --extern host=127.0.0.1 --extern port=3306 --extern user=root --extern password= --force --max-test-fail=0 --suite=main
  4. ./mtr --extern host=127.0.0.1 --extern port=3306 --extern user=root --extern password= --force --max-test-fail=0 --fast --suite=main
复制代码
  1. ##############################################################################
  2. # all-default-big
  3. ##############################################################################
复制代码
  1. ......
  2. [----------] 1027 tests from Spec/ReuseConnectionTest (404 ms total)
  3. [----------] Global test environment tear-down
  4. [==========] 1027 tests from 1 test suite ran. (70804 ms total)
  5. Total Test time (real) = 3363.87 sec
  6. ......
  7. The following tests FAILED:
  8.         203 - routertest_component_metadata_ttl (Subprocess aborted)
  9.         206 - routertest_component_rest_api_enable (Failed)
  10.         222 - routertest_component_routing_splicer (Failed)
  11.         224 - routertest_integration_routing_reuse (Failed)
  12. Errors while running CTest
  13.   [  FAILED  ] CheckEdgeHttpsPortValues/UseEdgeHttpsPortValues.ensure_bootstrap_works_for_edge_https_port_values/1, where GetParam() = 65535 (1444 ms)
  14.   [  FAILED  ] 1 test, listed below:
  15.   [  FAILED  ] CheckEdgeHttpsPortValues/UseEdgeHttpsPortValues.ensure_bootstrap_works_for_edge_https_port_values/1, where GetParam() = 65535
  16.    1 FAILED TEST
  17.   [  FAILED  ] Spec/SplicerFailParamTest.fails/client_ssl_dh_params_not_exists, where GetParam() = 64-byte object <C8-CE 3D-2F 4D-56 00-00 F0-DA BB-30 4D-56 00-00 B0-DB BB-30 4D-56 00-00 B0-DB BB-30 4D-56 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 3D-D1 F9-2E 4D-56 00-00 AD-D0 F9-2E 4D-56 00-00> (383 ms)
  18.   [  FAILED  ] 1 test, listed below:
  19.   [  FAILED  ] Spec/SplicerFailParamTest.fails/client_ssl_dh_params_not_exists, where GetParam() = 64-byte object <C8-CE 3D-2F 4D-56 00-00 F0-DA BB-30 4D-56 00-00 B0-DB BB-30 4D-56 00-00 B0-DB BB-30 4D-56 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 3D-D1 F9-2E 4D-56 00-00 AD-D0 F9-2E 4D-56 00-00>
  20.    1 FAILED TEST
  21.   [  FAILED  ] 0 tests, listed below:
  22.    0 FAILED TESTS
  23.   [  FAILED  ] Spec/ReuseConnectionTest: SetUpTestSuite or TearDownTestSuite
  24.    1 FAILED TEST SUITE
  25. Unit tests: 98% tests passed, 4 tests failed out of 224
  26.   The following tests FAILED:
  27.         206 - routertest_component_rest_api_enable (Failed)
  28.         222 - routertest_component_routing_splicer (Failed)
  29.         224 - routertest_integration_routing_reuse (Failed)
  30. Report from unit tests in /data/work/mysql/mysql-server/mysql-test/var-all-default-big/ctest.log
  31. ------------------------------------------------------------------------------
  32. The servers were restarted 3 times
  33. The servers were reinitialized 0 times
  34. Spent 53.181 of 3579 seconds executing testcases
  35. Completed: Failed 1/6 tests, 83.33% were successful.
  36. Failing test(s): unit_tests
复制代码
  1. - ndb
  2. - ndb_big
  3. - ndb_opt
  4. - ndb_ddl
  5. - ndb_binlog
  6. - ndb_rpl
  7. - rpl_ndb
  8. - ndbcluster
  9. - gcol_ndb
  10. - json_ndb
复制代码
  1. # 启动 mtr 时的日志:
  2. Collecting tests
  3. - Adding combinations for binlog
  4. - Adding combinations for binlog_gtid
  5. - Adding combinations for binlog_nogtid
  6. - Adding combinations for rpl
  7. - Adding combinations for rpl_gtid
  8. - Adding combinations for rpl_nogtid
  9. # 对应于
  10. ./suite/rpl_nogtid/combinations
  11. ./suite/binlog_gtid/combinations
  12. ./suite/binlog/combinations
  13. ./suite/rpl/combinations
  14. ./suite/rpl_gtid/combinations
  15. ./suite/binlog_nogtid/combinations
  16. # 除此之外,还有:
  17. ./suite/ndb_rpl/t/ndb_rpl_innodb2ndb.combinations
  18. ./suite/ndb_rpl/t/ndb_rpl_conflict_epoch.combinations
  19. ./suite/ndb_rpl/t/ndb_rpl_basic.combinations
复制代码
suitename 可选范围
  1. main,
  2. audit_null,
  3. auth_sec,
  4. binlog,
  5. binlog_gtid,
  6. binlog_nogtid,
  7. clone,
  8. collations,
  9. component_keyring_file,
  10. connection_control,
  11. encryption,
  12. engines,
  13. engines/funcs,
  14. engines/iuds,
  15. engines/rr_trx,
  16. federated,
  17. funcs_1, # 额外功能(包括视图、存储过程、INFORMATION_SCHEMA等)
  18. funcs_2, # 额外功能(字符集等)
  19. gcol, # 虚拟生成列
  20. gis,
  21. group_replication,
  22. information_schema,
  23. innodb,
  24. innodb_fts, # 全文索引
  25. innodb_gis,
  26. innodb_stress,
  27. innodb_undo,
  28. innodb_zip,
  29. interactive_utilities,
  30. jp, # 日语字符集
  31. json,
  32. large_tests,
  33. lock_order,
  34. max_parts,
  35. memcached,
  36. network_namespace,
  37. opt_trace,
  38. parts,parts/special_tests,
  39. perfschema,
  40. query_rewrite_plugins,
  41. rpl,
  42. rpl_gtid,
  43. rpl_nogtid,
  44. secondary_engine,
  45. service_status_var_registration,
  46. service_sys_var_registration,
  47. service_udf_registration,
  48. special,
  49. stress,
  50. sys_vars,
  51. sysschema,
  52. test_service_sql_api,
  53. test_services,
  54. x
复制代码
suites 分类

default suites:
  1. auth_sec,binlog,binlog_gtid,binlog_nogtid,clone,
  2. collations,component_keyring_file,connection_control,encryption,
  3. federated,funcs_2,gcol,gis,information_schema,
  4. innodb,innodb_fts,innodb_gis,innodb_undo,innodb_zip,
  5. interactive_utilities,json,
  6. main,
  7. opt_trace,parts,perfschema,query_rewrite_plugins,rpl,rpl_gtid,rpl_nogtid,secondary_engine,
  8. service_status_var_registration,service_sys_var_registration,service_udf_registration,
  9. sys_vars,sysschema,test_service_sql_api,test_services,x
复制代码
非 default suites:
  1. funcs_2, stress, jp, nist
  2. engines, memcached, audit_null
  3. group_replication
复制代码
指令示例

mtr 执行路径:

常用指令:

  1. perl mysql-test-run.pl --record mytest
复制代码
  1. perl mysql-test-run.pl mytestcase1
  2. perl mysql-test-run.pl --suites=main,rpl # 指定多个 suites
复制代码
  1. ./mtr testcasename --record
  2. # 只运行基础套餐里的 subquery_all 用例( t/subquery_all.test )
  3. # 可选 --charset-for-testdb=utf8mb4
  4. ./mtr --force --big-test --nowarnings --max-test-fail=0 main.subquery_all
  5. # 如需执行多个 case,可通过空格分割,比如:
  6. ./mtr --force --big-test --nowarnings --max-test-fail=0 main.subquery_all main.myisam_explain_json_non_select_none
复制代码
  1. ./mtr --force
复制代码
  1. ./mtr  --suite=main --force --max-test-fail=0 --nowarnings --parallel=8
  2. ./mtr  --suite=main --force --max-test-fail=0 --nowarnings --parallel=8 --big-test
复制代码
  1. # --do-test 参数支持正则表达式,该指令等效于./mtr --do-test=events.*
  2. ./mtr --do-test=events --force --max-test-fail=0
  3. # 如果想测试所有包含 innodb 的 case,可以用 ./mtr --do-test=.*innodb.*
复制代码
特殊用法:

  1. --fast
  2. Do not perform controlled shutdown when servers need to be restarted or at the end of the test run. This is equivalent to using --shutdown-timeout=0.
复制代码
  1. Note
  2.     If a test case has an .opt file that requires the server to be restarted with specific options, the
  3.     file will not be used. The test case likely will fail as a result.
复制代码
可见,官方对这种用法的支持尚不完善
推荐用法

如果需要验证 release 版本稳定性(适用于 QA、研发),可参考 default.daily 中的指令集。
如何添加测试用例?

1. 示例一

我们通过一个最简单的例子来说明这个框架是怎么使用的。
1.1. 创建测试用例

在 mysql-test/t 目录下创建一个文件名为 mytest.test 的测试用例:
  1. --disable_warnings
  2. DROP TABLE IF EXISTS t1;
  3. SET @@sql_mode='NO_ENGINE_SUBSTITUTION';
  4. --enable_warnings
  5. SET SQL_WARNINGS=1;
  6. --echo #
  7. --echo # test content
  8. --echo #
  9. CREATE TABLE t1 (a INT);
  10. INSERT INTO t1 VALUES (1);
  11. INSERT INTO t1 VALUES (2);
  12. SELECT * FROM t1;
  13. DROP TABLE t1;
复制代码
在mysql-test/r 目录下创建名为mytest.result 的文件:
  1. DROP TABLE IF EXISTS t1;
  2. SET @@sql_mode='NO_ENGINE_SUBSTITUTION';
  3. SET SQL_WARNINGS=1;
  4. #
  5. # test content
  6. #
  7. CREATE TABLE t1 (a INT);
  8. INSERT INTO t1 VALUES (1);
  9. INSERT INTO t1 VALUES (2);
  10. SELECT * FROM t1;
  11. a
  12. 1
  13. 2
  14. DROP TABLE t1;
复制代码
可见,.result 文件中不仅要记录 SQL,还要记录输出结果。
1.2. 执行测试,成功

指令:
  1. cd mysql80-debug/mysql-test
  2. ./mtr main.mytest
复制代码
输出:
  1. Logging: ./mtr  main.mytest
  2. MySQL Version 8.0.29
  3. Checking supported features
  4. - Binaries are debug compiled
  5. Using 'all' suites
  6. Collecting tests
  7. Checking leftover processes
  8. Removing old var directory
  9. Creating var directory '/Users/wslu/work/mysql/mysql80-debug/mysql-test/var'
  10. Installing system database
  11. Using parallel: 1
  12. ==============================================================================
  13.                   TEST NAME                       RESULT  TIME (ms) COMMENT
  14. ------------------------------------------------------------------------------
  15. [ 50%] main.mytest                               [ pass ]     63
  16. [100%] shutdown_report                           [ pass ]
  17. ------------------------------------------------------------------------------
  18. The servers were restarted 0 times
  19. The servers were reinitialized 0 times
  20. Spent 0.063 of 16 seconds executing testcases
  21. Completed: All 2 tests were successful.
复制代码
看到 successful 说明执行成功。
1.3. 修改 result 文件

在 mytest.result 文件中添加一些字符:
  1. DROP TABLE IF EXISTS t1;
  2. SET @@sql_mode='NO_ENGINE_SUBSTITUTION';
  3. SET SQL_WARNINGS=1;
  4. #
  5. # test content
  6. #
  7. CREATE TABLE t1 (a INT);
  8. INSERT INTO t1 VALUES (1);
  9. INSERT INTO t1 VALUES (2);
  10. SELECT * FROM t1; # new comment
  11. a
  12. 1
  13. 2
  14. DROP TABLE t1;
复制代码
1.4. 再次执行测试,失败

再次执行指令./mtr main.mytest ,可见# new comment 那一行报错:
  1. ==============================================================================                  TEST NAME                       RESULT  TIME (ms) COMMENT------------------------------------------------------------------------------[ 50%] main.mytest                               [ fail ]        Test ended at 2023-03-20 15:07:50CURRENT_TEST: main.mytest--- /Users/wslu/work/mysql/mysql80-debug.bak_asan_ubsan_gcov/mysql-test/r/mytest.result  2023-03-20 10:07:31.000000000 +0300+++ /Users/wslu/work/mysql/mysql80-debug.bak_asan_ubsan_gcov/mysql-test/var/log/mytest.reject  2023-03-20 10:07:50.000000000 +0300@@ -7,7 +7,7 @@ CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2);-SELECT * FROM t1; # new comment+SELECT * FROM t1; a 1 2mysqltest: Result length mismatchThe result from queries just before the failure was:DROP TABLE IF EXISTS t1;
  2. SET @@sql_mode='NO_ENGINE_SUBSTITUTION';
  3. SET SQL_WARNINGS=1;
  4. #
  5. # test content
  6. #
  7. CREATE TABLE t1 (a INT);
  8. INSERT INTO t1 VALUES (1);
  9. INSERT INTO t1 VALUES (2);
  10. SELECT * FROM t1;
  11. a
  12. 1
  13. 2
  14. DROP TABLE t1;safe_process[19130]: Child process: 19131, exit: 1 - the logfile can be found in '/Users/wslu/work/mysql/mysql80-debug.bak_asan_ubsan_gcov/mysql-test/var/log/main.mytest/mytest.log'[100%] shutdown_report                           [ pass ]------------------------------------------------------------------------------
复制代码
mtr 会指出具体是哪行导致的 case 失败。
常见问题 FAQ

test case failed 原因

此外,测试用例可以执行外部程序,因此在某些方面,测试框架可以扩展为测试 SQL 语句以外的用途。
最后,可以在测试中嵌入一小段 Perl 代码。这有时可用于执行超出测试语言或 SQL 能力的操作或执行逻辑。
可使用一些技巧来定为具体的错误原因,详见下节。
异常调试

分析日志

默认情况下,在目录 mysql-test/var/log/中有日志生成(若指定 --vardir 参数,则以该参数路径为准),分析该日志也能得到一些有用信息。
比如 启动失败,则可以查看 bootstrap.log 文件,去掉命令中的 --bootstrap 并运行即可启动对应的 MySQL 服务来验证、调试。
verbose 参数

启动 mtr 时加 --verbose 参数,定位到引用的脚本位置后可以配置 --echo 命令修改调试。
如果加上 --verbose 打印的内容还不够详细,可以再加一个,即 --verbose --verbose,能打印出 mtr perl 脚本中的日志信息。
示例:
  1. wslu@ubuntu:/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test$ perl mysql-test-run.pl --timer  --force --parallel=1 --vardir=var-rpl --suite=rpl --verbose
  2. Logging: mysql-test-run.pl  --timer --force --parallel=1 --vardir=var-rpl --suite=rpl --verbose
  3. > exe_name: mysqld
  4. MySQL Version 8.0.29
  5. Checking supported features
  6. - Binaries are debug compiled
  7. > Testing FIPS: --test-ssl-fips-mode 0 error:0F06D065:common libcrypto routines:FIPS_mode_set:fips mode not supported
  8. Using suite(s): rpl
  9. Collecting tests
  10. > Collecting: rpl
  11. > suitedir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl
  12. > testdir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl/t
  13. > resdir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl/r
  14. > Read combinations file /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl/combinations.
  15. - Adding combinations for rpl
  16. > Collecting: i_rpl
  17. Removing old var directory
  18. > opt_vardir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl
  19. > Removing /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var
  20. > Removing /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/
  21. > Removing /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/
  22. Creating var directory '/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl'
  23. > Creating /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl
  24. Installing system database
  25. ### safe_path: /data/work/mysql/mysql80-install.bak_asan_ubsan/bin//mysqltest_safe_process --verbose -- /data/work/mysql/mysql80-install.bak_asan_ubsan/bin/mysqld --no-defaults --initialize-insecure --loose-skip-ndbcluster --tmpdir=/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/ --core-file --datadir=/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/data/ --secure-file-priv=/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl --innodb_buffer_pool_size=24M --innodb-log-file-size=5M --innodb_autoextend_increment=8 --character-sets-dir=/data/work/mysql/mysql80-install.bak_asan_ubsan/share/charsets --loose-auto_generate_certs=OFF --loose-sha256_password_auto_generate_rsa_keys=OFF --loose-caching_sha2_password_auto_generate_rsa_keys=OFF --init-file=/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/bootstrap.sql
  26. Using parallel: 1
  27. ==============================================================================
  28.                   TEST NAME                       RESULT  TIME (ms) COMMENT
  29. ------------------------------------------------------------------------------
  30. > Client connected
  31. worker[1] > mtr_ping_port: 13000
  32. worker[1] > FREE
  33. worker[1] > mtr_ping_port: 13001
  34. worker[1] > FREE
  35. worker[1] > mtr_ping_port: 13002
  36. worker[1] > FREE
  37. worker[1] > mtr_ping_port: 13003
  38. worker[1] > FREE
  39. ......
  40. worker[1] > mtr_ping_port: 13029
  41. worker[1] > FREE
  42. worker[1] > Using MTR_BUILD_THREAD 300, with reserved ports 13000..13029
  43. worker[1] Creating var directory '/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl'
  44. worker[1] > result: , file_mode: 0
  45. [  0%] rpl.rpl_atomic_ddl                        [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  46. [  0%] rpl.rpl_atomic_ddl_no_binlog              [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  47. [  0%] rpl.rpl_binlog_cache_encryption           [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  48. [  0%] rpl.rpl_filters_error_cases_on_startup    [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  49. [  0%] rpl.rpl_group_commit_deadlock             [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  50. [  0%] rpl.rpl_group_commit_deadlock_myisam      [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  51. [  0%] rpl.rpl_innodb_auto_increment             [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  52. [  0%] rpl.rpl_killed_ddl                        [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  53. [  0%] rpl.rpl_log_info_repository_persistence_assign_gtids_to_anonymous_transactions  [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  54. [  0%] rpl.rpl_log_info_repository_persistence_require_row  [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  55. [  0%] rpl.rpl_log_info_repository_persistence_require_table_primary_key_check  [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  56. [  0%] rpl.rpl_row_crash_safe                    [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  57. [  0%] rpl.rpl_row_mts_rec_crash_safe            [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  58. [  0%] rpl.rpl_stm_mixed_crash_safe              [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  59. [  0%] rpl.rpl_stm_mixed_mts_rec_crash_safe      [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  60. [  0%] rpl.rpl_stm_mixed_mts_rec_crash_safe_checksum  [ skipped ]  Test needs 'big-test' or 'only-big-test' option.
  61. [  0%] rpl.rpl_io_thd_wait_for_disk_space_stress  [ disabled ]   BUG#23581287 Disabled until bug is fixed.
  62. [  0%] rpl.rpl_writeset_add_unique_key           [ disabled ]   Bug#33134835 RPL_WRITESET_ADD_UNIQUE_KEY FAILS SPORADICALLY
  63. worker[1] > Running test: rpl.rpl_plugin_load
  64. worker[1] > Setting timezone: GMT-3
  65. worker[1] > Cleaning datadirs...
  66. worker[1] > clean_dir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp
  67. worker[1] > unlink: '/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/bootstrap.sql'
  68. worker[1] > Generating my.cnf from '/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl/my.cnf'
  69. worker[1] > MASTER_MYPORT = 13000
  70. worker[1] > MASTER_MYSOCK = /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/mysqld.1.sock
  71. worker[1] > MASTER_X_MYSOCK = /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/mysqlx.1.sock
  72. worker[1] > SLAVE_MYPORT = 13002
  73. worker[1] > SLAVE_MYSOCK = /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/mysqld.2.sock
  74. worker[1] > SLAVE_X_MYSOCK = /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/mysqlx.2.sock
  75. worker[1] > mysqld_start:  [' --plugin-dir=/data/work/mysql/mysql80-install.bak_asan_ubsan/lib/plugin', '--binlog-format=mixed ']
  76. ### safe_path: /data/work/mysql/mysql80-install.bak_asan_ubsan/bin//mysqltest_safe_process --verbose -- /data/work/mysql/mysql80-install.bak_asan_ubsan/bin/mysqld --defaults-group-suffix=.1 --defaults-file=/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/my.cnf --log-output=file --loose-debug-sync-timeout=600 --plugin-dir=/data/work/mysql/mysql80-install.bak_asan_ubsan/lib/plugin --binlog-format=mixed --core-file
  77. worker[1] > Started [mysqld.1 - pid: 61921, winpid: 61921]
  78. worker[1] > mysqld_start:  [' --plugin-dir=/data/work/mysql/mysql80-install.bak_asan_ubsan/lib/plugin', '--binlog-format=mixed ']
  79. ......
复制代码
debug 参数和 gdb 参数

mtr 支持的一些 debug 参数:
  1.   debug                 Dump trace output for all servers and client programs.
  2.   debug-common          Same as debug, but sets 'd' debug flags to
  3.                         "query,info,error,enter,exit"; you need this if you
  4.                         want both to see debug printouts and to use
  5.                         DBUG_EXECUTE_IF.
  6.   debug-server          Use debug version of server, but without turning on
  7.                         tracing.
  8.   debugger=NAME         Start mysqld in the selected debugger.
  9.   gdb                   Start the mysqld(s) in gdb.
  10.   lldb                  Start the mysqld(s) in lldb.
复制代码
可见,要想跟踪调用过程,只有 --debug 和 --gdb 参数满足要求,会生成 trace 信息。
示例:
  1. # 这几条指令很耗费内存
  2. ./mtr --debug --suite=rpl
  3. ./mtr --gdb --suite=rpl
  4. ./mtr --debug --gdb --suite=rpl
复制代码
指令执行后,生成 trace 文件,比如 var/log/bootstrap.trace 。
脚本自身支持 debug 参数

如果引用(source)的脚本支持 debug 参数,比如常用的 $rpl_debug,则可以修改相应的 .inc 文件以获得更多的 debug 信息。
perl 的调试模式

添加-d 参数可进入 perl 语言的 debug 模式,便于调试 mysql-test-run.pl 及其调用。示例:
  1. wslu@ubuntu:/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test$ perl -d mysql-test-run.pl --timer  --force --parallel=1 --vardir=var-rpl --suite=rpl
  2. Loading DB routines from perl5db.pl version 1.60
  3. Editor support available.
  4. Enter h or 'h h' for help, or 'man perldebug' for more help.
  5. main::(mysql-test-run.pl:54):  push @INC, ".";
  6.   DB<1> l
  7. 54==>  push @INC, ".";
  8. 55
  9. 56:  use My::ConfigFactory;
  10. 57:  use My::CoreDump;
  11. 58:  use My::File::Path;    # Patched version of File::Path
  12. 59:  use My::Find;
  13. 60:  use My::Options;
  14. 61:  use My::Platform;
  15. 62:  use My::SafeProcess;
  16. 63:  use My::SysInfo;
  17.   DB<1> n
  18. main::(mysql-test-run.pl:72):  require "lib/mtr_gcov.pl";
  19.   DB<1> l
  20. 72==>  require "lib/mtr_gcov.pl";
  21. 73:  require "lib/mtr_gprof.pl";
  22. 74:  require "lib/mtr_io.pl";
  23. 75:  require "lib/mtr_lock_order.pl";
  24. 76:  require "lib/mtr_misc.pl";
  25. 77:  require "lib/mtr_process.pl";
  26. 78
  27. 79:  our $secondary_engine_support = eval 'use mtr_secondary_engine; 1';
  28. 80
  29. 81   # Global variable to keep track of completed test cases
  30.   DB<1>
复制代码
调试模式常用命令:
  1. h       查看帮助文档
  2. c line  运行到指定行
  3. n       运行到下一行
  4. s       跳到函数内部运行
  5. l       查看代码
  6. q       退出
复制代码
欢迎关注我的微信公众号【数据库内核】:分享主流开源数据库和存储引擎相关技术。
标题网址GitHubhttps://dbkernel.github.io知乎https://www.zhihu.com/people/dbkernel/posts思否(SegmentFault)https://segmentfault.com/u/dbkernel掘金https://juejin.im/user/5e9d3ed251882538083fed1f/postsCSDNhttps://blog.csdn.net/dbkernel博客园(cnblogs)https://www.cnblogs.com/dbkernel
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4