作者:卢文双 资深数据库内核研发
序言:
以前对 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 test
或make test-unit
指令(内容具体,更举荐)。 - 注意事项:在执行单元测试时,不倡议启用 ASAN,否则会因 ASAN 检测到单元测试代码有内存透露而导致 case 失败。
unittest/
目录介绍:
CMakeLists.txt
examples # 寄存单元测试示例
gunit # 寄存所有单元测试用例的代码
mytap # 寄存 MyTAP 协定代码
如果新加的测试用例与存储引擎或插件无关,则别离寄存在 unittest/engine_name
和unittest/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 test
或make 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
+ eval
,与 send
不同在于反对变量传递。
如果 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
编写标准
- 尽可能防止每行超过 80 个字符;
- 用
#
结尾,作为正文; - 缩进应用空格,防止应用 tab;
- SQL 语句应用雷同的格调,包含关键字大写,其它变量、表名、列名等小写;
- 减少适合的正文。特地是文件的结尾,正文出测试的目标、可能的援用或者修复的 bug 编号;
- 为了防止可能的抵触,习惯上表命名应用 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 |