乐趣区

关于mysql:特性介绍-MySQL测试框架-MTR-系列教程四语法篇

作者:卢文双 资深数据库内核研发

序言

以前对 MySQL 测试框架 MTR 的应用,次要集中于 SQL 正确性验证。近期因为工作须要,深刻理解了 MTR 的方方面面,发现 MTR 的能力不仅限于此,还反对单元测试、压力测试、代码覆盖率测试、内存谬误检测、线程竞争与死锁等性能,因而,本着分享的精力,将其总结成一个系列。

次要内容如下:

  • 入门篇:工作机制、编译装置、参数、指令示例、举荐用法、增加 case、常见问题、异样调试
  • 进阶篇:高阶用法,包含单元测试、压力测试、代码覆盖率测试、内存谬误检测、线程竞争与死锁
  • 源码篇:剖析 MTR 的源码
  • 语法篇:单元测试、压力测试、mysqltest 语法、异样调试

因为集体程度无限,所述不免有谬误之处,望雅正。

本文是第四篇语法篇。

本文首发于 2023-07-05 21:53:21


MTR 系列基于 MySQL 8.0.29 版本,如有例外,会特地阐明。

单元测试

简介

前文「MySQL 测试框架 MTR 系列教程(二):进阶篇 – 内存 / 线程 / 代码覆盖率 / 单元 / 压力测试」已介绍了单元测试的概念及应用办法,简略回顾一下:

  • MySQL 应用 TAP(Test Anything Protocol)和 Google Test Framework 来实现单元测试。

    • TAP 是 Perl 与测试模块之间所应用的简略的基于文本的接口。
    • 为了实现 C/C++ 的单元测试,MySQL 开发了一个用于生成 TAP 文本的库libmytap.a,源码门路位于unittest/mytap/
  • 应用办法:在执行 cmake 的目录执行 make testmake test-unit 指令(内容具体,更举荐)。
  • 注意事项:在执行单元测试时,不倡议启用 ASAN,否则会因 ASAN 检测到单元测试代码有内存透露而导致 case 失败。

unittest/ 目录介绍:

CMakeLists.txt
examples # 寄存单元测试示例
gunit # 寄存所有单元测试用例的代码
mytap # 寄存 MyTAP 协定代码

如果新加的测试用例与存储引擎或插件无关,则别离寄存在 unittest/engine_nameunittest/plugin_name 目录或它们的子目录中。

单元测试代码都位于 源码目录 /unittest/gunit/ 下,其中有文件也有子目录,无论是当前目录还是子目录下的文件,都以 xxxxx-t.cc 格局命名,每个xxxxx-t.cc 文件都是一个测试 case,编译后都会生成一个二进制文件 bin/xxxxx-t

上面举例说明如何增加单元测试 case。

示例

比方在 源码目录 /unittest/gunit/binlogevents/ 目录下创立一个新的测试用例 myprint

一、创立文件unittest/gunit/binlogevents/myprint-t.cc,内容如下:

#include <gtest/gtest.h>


namespace binary_log {
namespace unittests {

class MyPrintTest : public ::testing::Test {
 public:
  MyPrintTest() {}

  void TestBody() { // 必须实现该虚函数
      std::cout << "print_test ====>" << std::endl;
      ASSERT_TRUE(true);
  }
};

// 第二个参数是测试用例名字
TEST_F(MyPrintTest, PrintTest) {
  MyPrintTest t;
  t.TestBody();}

}  // namespace unittests
}  // namespace codecsog

二、批改 unittest/gunit/binlogevents/CMakeLists.txt 文件,增加 myprint 用例:

......

# Add tests SET(TESTS transaction_payload_codec
  transaction_compression
  transaction_payload_iterator
  gtids
  gno_intervals
  myprint ####### 新加的行
  heartbeat_codec)

......

三、从新执行 cmake(须要设置-DWITH_DEBUG=1 -DWITH_UNIT_TESTS=1)、编译,会生成二进制文件bin/myprint-t

四、运行 make testmake test-unit,或者间接执行bin/myprint-t,测试用例 passed:

wslu@ubuntu:/data/work/mysql/mysql-server/console-build-debug$ ./bin/myprint-t
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from MyPrintTest
[RUN] MyPrintTest.PrintTest
print_test ====>
[OK] MyPrintTest.PrintTest (0 ms)
[----------] 1 test from MyPrintTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (8 ms total)
[PASSED] 1 test.

参考:

  • MySQL: Creating and Executing Unit Tests

    • Home – Test Anything Protocol
    • GoogleTest User’s Guide | GoogleTest

代码覆盖率测试

目前波及 gcov 的程序文件只有 mysys/dbug.cc 文件以及对应的单元测试文件unittest/gunit/dbug-t.cc

gcov 的用法就是在编译时增加选项来实现的:

wslu@ubuntu:/data/work/mysql/mysql-server/console-build-debug/mysql-test$ grep "coverage" ../../CMakeLists.txt -nr
1128:  STRING_APPEND(CMAKE_C_FLAGS   "-fprofile-arcs -ftest-coverage -DHAVE_GCOV")
1129:  STRING_APPEND(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage -DHAVE_GCOV")
1130:  STRING_APPEND(CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage -lgcov")

综上,无需自行编写代码覆盖率测试代码。

压力测试

有两个中央波及压力测试:

一、压力测试 suite 只有两个:

  • stress
  • innodb_stress

如须要增加新 case,参考对应 suite 已有 case 照猫画虎即可,语法可参考下一章节。

二、mysql-stress-test.pl:被 mysql-test-run.pl 调用,参数是--stress

  stress=ARGS           Run stress test, providing options to
                        mysql-stress-test.pl. Options are separated by comma.

对于 mysql-stress-test.pl,更便于自定义测试内容,次要包含:

  • --stress-init-file[=path]

    file_name is the location of the file that contains the list of tests to be run once to initialize the database for the testing. If missing, the default file is stress_init.txt in the test suite directory.

  • --stress-tests-file[=file_name]

    Use this option to run the stress tests. file_name is the location of the file that contains the list of tests. If file_name is omitted, the default file is stress-test.txt in the stress suite directory. (See --stress-suite-basedir).

这部分暂未尝试,不做赘述。

SQL 测试 – mtr/mysqltest 语法

之间文章介绍过 mtr 会将 *.test*.inc 等测试 case 的内容传给 mysqltest 来执行。

mysqltest 是 mysql 自带的测试引擎, 它实现了一种小语言,用来形容测试过程,并将测试后果与预期比照。

本节要解说 mysqltest 语法格局,你可能会好奇学习这个语法有什么用,为了更直观的阐明,首先咱们看一下如何编写 mtr 的测试用例。

语法格局

mysqltest 解释的是以 .test 为后缀的文件(包含其援用的 .inc 文件)。

mysqltest 小语言依照语法大抵分为三类:

  • mysql command:用来管制运行时的行为。个别有两种写法:
command; # 这是前面带; 的
--command # 后面带 --,不须要;
  • SQL:就是一般的 SQL 语句,测试 case 里大部分是 SQL 语句。
  • comment:正文个别用于形容测试过程,用 # 结尾。

示例:借鉴「MySQL 测试框架 MTR 系列教程(一):入门篇」一文中的测试 case(门路是 mysql-test/t/mytest.test),内容如下:

--echo #
--echo # some comments
--echo #

--disable_warnings
DROP TABLE IF EXISTS t1;
SET @@sql_mode='NO_ENGINE_SUBSTITUTION';
--enable_warnings

SET SQL_WARNINGS=1;

CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (2);
SELECT * FROM t1;
DROP TABLE t1;

command 列表

mysqltest 提供了几十个 command,本文只介绍最罕用的,更多内容请查阅官网手册:MySQL: mysqltest Language Reference。

error 解决预期谬误

语法:

error error_code [, error_code] ...
sql_statements

有些 CASE 就是要验证 sql 失败的状况,在 sql 语句后面加上 --error 错误码 就能够了。

  • 如果 sql 报错且错误码等于 --error 指定的错误码,mysqltest 不会 abort,而是持续运行。
  • 反之,如果 sql 报错且错误码不等于--error 指定的错误码,mysqltest 会 abort 并报错退出。

--error前面能够跟两种值:一种是error no,另外一种是sqlstate,如果是后者须要加上 S 做前缀。他们别离是 C API 函数 mysql_errno()mysql_sqlstate() 的返回值。

示例一:应用错误码

--error 1050
create table t1(pk createtime primary key, a int);

等价于

--error ER_TABLE_EXISTS_ERROR
create table t1(pk createtime primary key, a int);

其中数字 1050 对应错误码,ER_TABLE_EXISTS_ERROR 对应谬误的逻辑名。

这样在 mysqltest 运行后,会将返回的错误信息一起写入后果文件,这些错误信息就作为冀望后果的一部分了。

示例二:应用 SQLSTATE

也能够应用 SQLSTATE 来批示冀望有谬误返回,例如与 MySQL 错误码 1050 对应的 SQLSTATE 值是 42S01,应用上面的形式,留神编码减少了 S 前缀:

--error S42S01
create table t1(pk createtime primary key, a int);

示例三:指定多个错误码,满足其一则通过

在指令 error 前面是能够退出多个错误码作为参数的,应用逗号分隔即可:

--error 1050,1052
create table t1(pk createtime primary key, a int);

如果该 SQL 报错,若错误码是 1050 或 1051,则合乎预期,测试持续。

错误码参考 MySQL 安装包 include 子目录下的 mysqld_error.h

disable_abort_on_error / enable_abort_on_error

默认状况下(enable_abort_on_error),sql 执行失败后 mysqltest 就退出了,前面的内容就不会执行,也不会生成 .reject文件。

显示执行 disable_abort_on_error 命令能够在 sql 失败后继续执行前面的内容,并生成 .reject文件。

--disable_abort_on_error
sql_statements
--enable_abort_on_error

disable_query_log / enable_query_log

默认状况下(enable_query_log),所有的 sql 语句都会记录输入后果。

在一些状况下 (比方,应用了循环,query 特地多) 不想记录某些 sql 语句及后果,显示调用 disable_query_log 既可。

--disable_query_log
--enable_query_log

其余形如 enable_xx/disable_xx 的命令还有很多,用法都相似

connect

创立一个到 mysql server 的新连贯并作为以后连贯。

语法格局:

connect (name, host_name, user_name, password, db_name [,port_num [,socket [,options [,default_auth [,compression algorithm, [,compression level]]]]]])
  • name is the name for the connection (for use with the connection, disconnect, and dirty_close commands). This name must not already be in use by an open connection.
  • host_name indicates the host where the server is running.
  • user_name and password are the user name and password of the MySQL account to use.
  • db_name is the default database to use. As a special case, NO-ONE means that no default database should be selected. You can also leave db_name blank to select no database.
  • port_num, if given, is the TCP/IP port number to use for the connection. This parameter can be given by using a variable.
  • socket, if given, is the socket file to use for connections to localhost. This parameter can be given by using a variable.
  • options can be one or more of the following words, separated by spaces:

    • CLEARTEXT: Enable use of the cleartext authentication plugin.
    • COMPRESS: Use the compressed client/server protocol, if available.
    • PIPE: Use the named-pipe connection protocol, if available.
    • SHM: Use the shared-memory connection protocol, if available.
    • SOCKET: Use the socket-file connection protocol.
    • SSL:Use SSL network protocol to have encrypted connection.
    • TCP: Use the TCP/IP connection protocol.
      Passing PIPE or SHM on non-Windows systems causes an error, and, similarly, passing SOCKET on Windows systems causes an error.
  • default_auth is the name of an authentication plugin. It is passed to the mysql_options() C API function using the MYSQL_DEFAULT_AUTH option. If mysqltest does not find the plugin, use the –plugin-dir option to specify the directory where the plugin is located.
  • compression algorithm is the name of compression algorithm to be used to compress data transferred between client server. It is passed to the mysql_options() C API function using the MYSQL_OPT_COMPRESSION_ALGORITHMS option.
  • zstd compression level is the extent of compression to be applied when zstd compression algorithm is used. It is passed to the mysql_options() C API function using the MYSQL_OPT_COMPRESSION_ALGORITHMS option.
  • compression level is the extent of compression to be applied based on the compression algorithm used. It is passed to the mysql_options() C API function using the MYSQL_OPT_COMPRESSION_ALGORITHMS option.

示例:

connect (conn1,localhost,root,,);
connect (conn2,localhost,root,mypass,test);
connect (conn1,127.0.0.1,root,,test,$MASTER_MYPORT);

connection

语法:

connection connection_name

抉择 connection_name作为以后连贯。

示例:

connection master;
connection conn2;
connection default;

disconnect

语法:

disconnect connection_name

敞开连贯connection_name

示例:

disconnect conn2;
disconnect slave;

测试 session 的时候会用到上述三个命令,以在多个 connection 之间切换。比方:

connect (conn3,127.0.0.1,root,,test,25042);
connection conn3;
create table t1(a int primary key);
drop table t1;
disconnect conn3;

exec

执行 shell 命令。语法:

exec command [arg] ...

示例:

--exec $MYSQL_DUMP --xml --skip-create test
--exec rm $MYSQLTEST_VARDIR/tmp/t1
exec $MYSQL_SHOW test -v -v;

On Cygwin, the command is executed from cmd.exe, so commands such as rm cannot be executed with exec. Use system instead.

perl [terminator]

嵌入 perl 代码,以 EOF 为结束符,也能够自定义结束符。

受限于 mtr 语法,很多操作无奈实现,嵌入 perl 脚本能够简化问题。

perl;
  // your perl script
EOF

示例:

perl;
print "This is a test\n";
EOF
perl END_OF_FILE;
print "This is another test\n";
END_OF_FILE

perl 内外的变量交互:

1、能够应用 let 设置环境变量

如果应用 let 时变量名不加 $ 即为设置为环境变量,在 perl 中能够通过 $ENV{'name'} 获取和设置

--let name = "env value"

--perl
  print "name: $ENV{'name'}";
  $ENV{'name'} = 'new env value';
EOF

--echo name: $name

2、在 perl 中拼接 mtr 脚本,而后在 mtr 脚本中执行

perl;
  my $dir = $ENV{'MYSQLTEST_VARDIR'};
  open (OUTPUT, ">$dir/tmp/name.inc") ;
  print OUTPUT "let \$name = abc;\n";
  close (OUTPUT)
EOF

--source  $MYSQLTEST_VARDIR/tmp/name.inc
--echo $name

vertical_results/horizontal_results

设置 SQL 语句后果的默认显示方式(vertical_results 示意纵向,horizontal_results 示意横向,默认是横向),性能跟 sql 语句的 '\G' 相似。

示例:

--vertical_results

exit

退出以后测试 case,后续指令不再执行。

let

变量赋值,可反对整数、字符串。

语法:

let $var_name = value
let $var_name = query_get_value(query, col_name, row_num)

示例:

--let $1= 0 # 加 -- 前缀,就不用以分号结尾
let $count= 10;

# 将查问后果赋给变量 q
let $q= `SELECT VERSION()`;

inc/dec

为整数加 1/ 减 1。

语法:

inc $var_name/dec $var_name

示例:

--inc $i;
inc $3;

eval

语法:

eval statement

执行sql 语句,反对变量的传递。示例:

eval USE $DB;
eval CHANGE MASTER TO MASTER_PORT=$SLAVE_MYPORT;
eval PREPARE STMT1 FROM "$my_stmt";

query

语法:

query [statement]

显示指定以后语句是 SQL 语句,而不是 command。即便 query 之后是 command(比方sleep),也会当成 statement 来解析。

send

语法:

send [statement]

向 server 发送一条 query,但并不期待后果,而是立刻返回,该 query 的后果必须由 reap 指令来接管。

在上一条 query 后果被 reap 指令接管之前,不能向以后 session 发送新的 SQL 语句。

如果 statement 省略了,则执行下一行的 SQL 语句。

示例:

send SELECT 1;

等效于

send;
SELECT 1;

send_eval

语法:

send_eval [statement]

等效于 send + evalsend 不同在于反对变量传递

如果 statement 省略了,则执行下一行的 SQL 语句。

示例:

--send_eval $my_stmt

等效于

--send_eval
$my_stmt;

reap

如果以后 session 之前有通过 send 指令向 server 发送 SQL 语句,reap 指令用来接管该 SQL 语句的执行后果。

如果之前没有通过 send 向 server 发送 SQL,则不要执行 reap 指令。

示例:在同一个 session 中用 send 后盾执行,用 reap 复原期待。

--connection 1
--send select sleep(20)

--connection 2
--send select 1

--connection 1
--reap

echo

语法:

echo text

text 文本输入到测试 result 中。

示例:

--echo Another sql_mode test
echo should return only 1 row;

query_get_value

语法:

query_get_value(query, col_name, row_num)

取得 query 返回的后果中 某行某列的值

示例:

如果 .test 文件内容如下:

CREATE TABLE t1(a INT, b VARCHAR(255), c DATETIME);
SHOW COLUMNS FROM t1;
let $value= query_get_value(SHOW COLUMNS FROM t1, Type, 1);
echo $value;

输入后果为:

CREATE TABLE t1(a INT, b VARCHAR(255), c DATETIME);
SHOW COLUMNS FROM t1;
Field   Type    Null    Key     Default Extra
a       int(11) YES             NULL
b       varchar(255)    YES             NULL
c       datetime        YES             NULL
int(11)

int(11) 就是 Type 列第一行的值。

source

语法:

source file_name

多个 case 可能共用一块代码,这块代码能够独自放到一个 .inc 文件,再通过 source 导入。

示例:

--source path/to/script.inc

sleep

语法:

sleep num

Sleep num seconds.

示例:

--sleep 10
sleep 0.5;

replace_column

语法:

replace_column col_num value [col_num value] ...

将下一条语句的后果中的 某些列的值进行替换 ,能够指定 多组替换规定,列序号从 1 开始。

示例:

--replace_column 9 #
replace_column 1 b 2 d;

expr 命令 (MySQL 8 之后可用)

语法:

expr $var_name= operand1 operator operand2

对数值变量进行运算,反对 +, -, *, /, %, &&, ||, &, |, ^, <<, >>

--let $val1= 10
--let $var2= 20
--expr $res= $var1 + $var2
--echo $res

在 5.7 版本中用 SQL 语句代替

--let $val1= 10
--let $var2= 20
--expr $res= `select $var1 + $var2`

if

语法:

if (expr)

与其余语言的 if 语句含意雷同。

示例:

let $counter= 0;
if ($counter)
{echo Counter is not 0;}

if (!$counter)
{echo Counter is 0;}

while

语法:

while (expr)

与其余语言的 while 语句含意雷同。

示例:

let $i=5;
while ($i)
{
  echo $i;
  dec $i;
}

其余命令

其余的命令还有:

assert (expr)

change_user [user_name], 

  此处含有隐藏内容,需要正确输入密码后可见!

, [db_name] character_set charset_name delimiter str die [message] skip [message] disable_async_client, enable_async_client disable_connect_log, enable_connect_log disable_info, enable_info disable_metadata, enable_metadata disable_ps_protocol, enable_ps_protocol disable_query_log, enable_query_log disable_reconnect, enable_reconnect disable_result_log, enable_result_log disable_rpl_parse, enable_rpl_parse disable_session_track_info, enable_session_track_info disable_testcase bug_number, enable_testcase disable_warnings, enable_warnings end start_timer end_timer # exec command exec_in_background command [arg] ... execw command [arg] ... # 目录相干 force-cpdir src_dir_name dst_dir_name force-rmdir dir_name mkdir dir_name rmdir dir_name list_files dir_name [pattern] list_files_append_file file_name dir_name [pattern] list_files_write_file file_name dir_name [pattern] # 文件相干 diff_files file_name1 file_name2 remove_files_wildcard dir_name pattern [retry] write_file file_name [terminator] append_file file_name [terminator] cat_file file_name chmod octal_mode file_name copy_file from_file to_file [retry] copy_files_wildcard src_dir_name dst_dir_name pattern [retry] file_exists file_name [retry] move_file from_name to_name [retry] output file_name remove_file file_name [retry] # 后果集 lowercase_result result_format version sorted_result partially_sorted_result start_column query_horizontal statement query_vertical statement replace_numeric_round precision replace_regex /pattern/replacement/[i] ... replace_result from_val to_val [from_val to_val] ... # 连贯 ping reset_connection dirty_close connection_name send_quit connection send_shutdown shutdown_server [timeout] sync_slave_with_master [connection_name] # 复制 save_master_pos sync_with_master offset wait_for_slave_to_stop

详见官网手册:MySQL: mysqltest Commands

编写标准

  1. 尽可能防止每行超过 80 个字符;
  2. # 结尾,作为正文;
  3. 缩进应用空格,防止应用 tab;
  4. SQL 语句应用雷同的格调,包含关键字大写,其它变量、表名、列名等小写;
  5. 减少适合的正文。特地是文件的结尾,正文出测试的目标、可能的援用或者修复的 bug 编号;
  6. 为了防止可能的抵触,习惯上表命名应用 t1、t2…,视图命名应用 v1、v2…;

异样调试

本大节已增加到《MySQL 测试框架 MTR 系列教程(一):入门篇》,看过前文的可跳过本节。

剖析日志

默认状况下,在目录 mysql-test/var/log/中有日志生成(若指定 --vardir 参数,则以该参数门路为准),剖析该日志也能失去一些有用信息。

比方 启动失败,则能够查看 bootstrap.log 文件,去掉命令中的 --bootstrap 并运行即可启动对应的 MySQL 服务来验证、调试。

verbose 参数

启动 mtr 时加 --verbose 参数,定位到援用的脚本地位后能够配置 --echo 命令批改调试。

如果加上 --verbose 打印的内容还不够具体,能够再加一个,即 --verbose --verbose,能打印出 mtr perl 脚本中的日志信息。

示例:

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
Logging: mysql-test-run.pl  --timer --force --parallel=1 --vardir=var-rpl --suite=rpl --verbose
> exe_name: mysqld
MySQL Version 8.0.29
Checking supported features
 - Binaries are debug compiled
> Testing FIPS: --test-ssl-fips-mode 0 error:0F06D065:common libcrypto routines:FIPS_mode_set:fips mode not supported

Using suite(s): rpl
Collecting tests
> Collecting: rpl
> suitedir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl
> testdir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl/t
> resdir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl/r
> Read combinations file /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl/combinations.
 - Adding combinations for rpl
> Collecting: i_rpl
Removing old var directory
> opt_vardir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl
> Removing /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var
> Removing /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/
> Removing /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/
Creating var directory '/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl'
> Creating /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl
Installing system database
### 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
Using parallel: 1

==============================================================================
                  TEST NAME                       RESULT  TIME (ms) COMMENT
------------------------------------------------------------------------------
> Client connected
worker[1] > mtr_ping_port: 13000
worker[1] > FREE
worker[1] > mtr_ping_port: 13001
worker[1] > FREE
worker[1] > mtr_ping_port: 13002
worker[1] > FREE
worker[1] > mtr_ping_port: 13003
worker[1] > FREE
......
worker[1] > mtr_ping_port: 13029
worker[1] > FREE
worker[1] > Using MTR_BUILD_THREAD 300, with reserved ports 13000..13029
worker[1] Creating var directory '/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl'
worker[1] > result: , file_mode: 0
[0%] rpl.rpl_atomic_ddl                        [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_atomic_ddl_no_binlog              [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_binlog_cache_encryption           [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_filters_error_cases_on_startup    [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_group_commit_deadlock             [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_group_commit_deadlock_myisam      [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_innodb_auto_increment             [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_killed_ddl                        [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_log_info_repository_persistence_assign_gtids_to_anonymous_transactions  [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_log_info_repository_persistence_require_row  [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_log_info_repository_persistence_require_table_primary_key_check  [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_row_crash_safe                    [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_row_mts_rec_crash_safe            [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_stm_mixed_crash_safe              [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_stm_mixed_mts_rec_crash_safe      [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_stm_mixed_mts_rec_crash_safe_checksum  [skipped]  Test needs 'big-test' or 'only-big-test' option.
[0%] rpl.rpl_io_thd_wait_for_disk_space_stress  [disabled]   BUG#23581287 Disabled until bug is fixed.
[0%] rpl.rpl_writeset_add_unique_key           [disabled]   Bug#33134835 RPL_WRITESET_ADD_UNIQUE_KEY FAILS SPORADICALLY
worker[1] > Running test: rpl.rpl_plugin_load
worker[1] > Setting timezone: GMT-3
worker[1] > Cleaning datadirs...
worker[1] > clean_dir: /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp
worker[1] > unlink: '/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/bootstrap.sql'
worker[1] > Generating my.cnf from '/data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/suite/rpl/my.cnf'
worker[1] > MASTER_MYPORT = 13000
worker[1] > MASTER_MYSOCK = /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/mysqld.1.sock
worker[1] > MASTER_X_MYSOCK = /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/mysqlx.1.sock
worker[1] > SLAVE_MYPORT = 13002
worker[1] > SLAVE_MYSOCK = /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/mysqld.2.sock
worker[1] > SLAVE_X_MYSOCK = /data/work/mysql/mysql80-install.bak_asan_ubsan/mysql-test/var-rpl/tmp/mysqlx.2.sock
worker[1] > mysqld_start:  ['--plugin-dir=/data/work/mysql/mysql80-install.bak_asan_ubsan/lib/plugin', '--binlog-format=mixed']

### 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
worker[1] > Started [mysqld.1 - pid: 61921, winpid: 61921]
worker[1] > mysqld_start:  ['--plugin-dir=/data/work/mysql/mysql80-install.bak_asan_ubsan/lib/plugin', '--binlog-format=mixed']

......

脚本本身反对 debug 参数

如果援用(source)的脚本反对 debug 参数,比方罕用的 $rpl_debug,则能够批改相应的 .inc 文件以取得更多的 debug 信息。

perl 的调试模式

增加-d 参数可进入 perl 语言的 debug 模式。示例:

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

Loading DB routines from perl5db.pl version 1.60
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(mysql-test-run.pl:54):  push @INC, ".";
  DB<1> l
54==>  push @INC, ".";
55
56:  use My::ConfigFactory;
57:  use My::CoreDump;
58:  use My::File::Path;    # Patched version of File::Path
59:  use My::Find;
60:  use My::Options;
61:  use My::Platform;
62:  use My::SafeProcess;
63:  use My::SysInfo;
  DB<1> n
main::(mysql-test-run.pl:72):  require "lib/mtr_gcov.pl";
  DB<1> l
72==>  require "lib/mtr_gcov.pl";
73:  require "lib/mtr_gprof.pl";
74:  require "lib/mtr_io.pl";
75:  require "lib/mtr_lock_order.pl";
76:  require "lib/mtr_misc.pl";
77:  require "lib/mtr_process.pl";
78
79:  our $secondary_engine_support = eval 'use mtr_secondary_engine; 1';
80
81   # Global variable to keep track of completed test cases
  DB<1>

调试模式常用命令:

h       查看帮忙文档
c line  运行到指定行
n       运行到下一行
s       跳到函数外部运行
l       查看代码
q       退出

参考

MySQL: The MySQL Test Framework

MySQL: Writing Test Cases

MySQL: mysqltest Language Reference

MySQL: Creating and Executing Unit Tests

mysqltest 语法整顿 – 叶落 kiss – 博客园 (cnblogs.com)”)


欢送关注我的微信公众号【数据库内核】:分享支流开源数据库和存储引擎相干技术。

题目 网址
GitHub https://dbkernel.github.io
知乎 https://www.zhihu.com/people/dbkernel/posts
思否(SegmentFault) https://segmentfault.com/u/dbkernel
掘金 https://juejin.im/user/5e9d3ed251882538083fed1f/posts
CSDN https://blog.csdn.net/dbkernel
博客园(cnblogs) https://www.cnblogs.com/dbkernel
退出移动版