ITPub博客

首页 > 数据库 > MySQL > 用mysqlslap对MySQL进行压力测试

用mysqlslap对MySQL进行压力测试

MySQL 作者:小亮520cl 时间:2015-11-11 16:45:49 0 删除 编辑
MySQL5.1地的确提供了好多有力的工具来帮助我们DBA进行数据库管理。
现在看一下这个压力测试工具mysqlslap.
关于他的选项手册上以及--help介绍的很详细。
我解释一下一些常用的选项。
这里要注意的几个选项:
  1. –auto-generate-sql, -a
  2. 自动生成测试表和数据
  3. –auto-generate-sql-load-type=type
  4. 测试语句的类型。取值包括:read,key,write,update和mixed(默认)。
  5. –number-char-cols=N, -x N
  6. 自动生成的测试表中包含多少个字符类型的列,默认1
  7. –number-int-cols=N, -y N
  8. 自动生成的测试表中包含多少个数字类型的列,默认1
  9. –number-of-queries=N
  10. 总的测试查询次数(并发客户数×每客户查询次数)
  11. –query=name,-q
  12. 使用自定义脚本执行测试,例如可以调用自定义的一个存储过程或者sql语句来执行测试。
  13. –create-schema
  14. 测试的schema,MySQL中schema也就是database
  15. –commint=N
  16. 多少条DML后提交一次
  17. –compress, -C
  18. 如果服务器和客户端支持都压缩,则压缩信息传递
  19. –concurrency=N, -c N
  20. 并发量,也就是模拟多少个客户端同时执行select。可指定多个值,以逗号或者–delimiter参数指定的值做为分隔符
  21. –engine=engine_name, -e engine_name
  22. 创建测试表所使用的存储引擎,可指定多个
  23. –iterations=N, -i N
  24. 测试执行的迭代次数
  25. –detach=N
  26. 执行N条语句后断开重连
  27. –debug-info, -T
  28. 打印内存和CPU的信息
  29. –only-print
  30. 只打印测试语句而不实际执行

  31. 测试的过程需要生成测试表,插入测试数据,这个mysqlslap可以自动生成,默认生成一个mysqlslap的schema,如果已经存在则先删除,这里要注意了,不要用–create-schema指定已经存在的库,否则后果可能很严重。可以用–only-print来打印实际的测试过程:
    $mysqlslap -a –only-print
    DROP SCHEMA IF EXISTS `mysqlslap`;
    CREATE SCHEMA `mysqlslap`;
    use mysqlslap;
    CREATE TABLE `t1` (intcol1 INT(32) ,charcol1 VARCHAR(128));
    INSERT INTO t1 VALUES (1804289383,’mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL’);
    …
    SELECT intcol1,charcol1 FROM t1;
    INSERT INTO t1 VALUES (364531492,’qMa5SuKo4M5OM7ldvisSc6WK9rsG9E8sSixocHdgfa5uiiNTGFxkDJ4EAwWC2e4NL1BpAgWiFRcp1zIH6F1BayPdmwphatwnmzdwgzWnQ6SRxmcvtd6JRYwEKdvuWr’);
    DROP SCHEMA IF EXISTS `mysqlslap`;

    可以看到最后由删除一开始创建的schema的动作,整个测试完成后不会在数据库中留下痕迹。假如我们执行一次测试,分别50和100个并发,执行1000次总查询,那么:

    $mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –debug-info
    Benchmark
    Average number of seconds to run all queries: 0.375 seconds
    Minimum number of seconds to run all queries: 0.375 seconds
    Maximum number of seconds to run all queries: 0.375 seconds
    Number of clients running queries: 50
    Average number of queries per client: 20

    Benchmark
    Average number of seconds to run all queries: 0.453 seconds
    Minimum number of seconds to run all queries: 0.453 seconds
    Maximum number of seconds to run all queries: 0.453 seconds
    Number of clients running queries: 100
    Average number of queries per client: 10

    User time 0.29, System time 0.11
    Maximum resident set size 0, Integral resident set size 0
    Non-physical pagefaults 4032, Physical pagefaults 0, Swaps 0
    Blocks in 0 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 7319, Involuntary context switches 681

    上结果可以看出,50和100个并发分别得到一次测试结果(Benchmark),并发数越多,执行完所有查询的时间越长。为了准确起见,可以多迭代测试几次:

    $ mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –iterations=5 –debug-info
    Benchmark
    Average number of seconds to run all queries: 0.380 seconds
    Minimum number of seconds to run all queries: 0.377 seconds
    Maximum number of seconds to run all queries: 0.385 seconds
    Number of clients running queries: 50
    Average number of queries per client: 20

    Benchmark
    Average number of seconds to run all queries: 0.447 seconds
    Minimum number of seconds to run all queries: 0.444 seconds
    Maximum number of seconds to run all queries: 0.451 seconds
    Number of clients running queries: 100
    Average number of queries per client: 10

    User time 1.44, System time 0.67
    Maximum resident set size 0, Integral resident set size 0
    Non-physical pagefaults 17922, Physical pagefaults 0, Swaps 0
    Blocks in 0 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 36796, Involuntary context switches 4093

    测试同时不同的存储引擎的性能进行对比:

    $ mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –iterations=5 –engine=myisam,innodb –debug-info
    Benchmark
    Running for engine myisam
    Average number of seconds to run all queries: 0.200 seconds
    Minimum number of seconds to run all queries: 0.188 seconds
    Maximum number of seconds to run all queries: 0.210 seconds
    Number of clients running queries: 50
    Average number of queries per client: 20

    Benchmark
    Running for engine myisam
    Average number of seconds to run all queries: 0.238 seconds
    Minimum number of seconds to run all queries: 0.228 seconds
    Maximum number of seconds to run all queries: 0.251 seconds
    Number of clients running queries: 100
    Average number of queries per client: 10

    Benchmark
    Running for engine innodb
    Average number of seconds to run all queries: 0.375 seconds
    Minimum number of seconds to run all queries: 0.370 seconds
    Maximum number of seconds to run all queries: 0.379 seconds
    Number of clients running queries: 50
    Average number of queries per client: 20

    Benchmark
    Running for engine innodb
    Average number of seconds to run all queries: 0.443 seconds
    Minimum number of seconds to run all queries: 0.440 seconds
    Maximum number of seconds to run all queries: 0.447 seconds
    Number of clients running queries: 100
    Average number of queries per client: 10

    User time 2.83, System time 1.66
    Maximum resident set size 0, Integral resident set size 0
    Non-physical pagefaults 34692, Physical pagefaults 0, Swaps 0
    Blocks in 0 out 0, Messages in 0 out 0, Signals 0
    Voluntary context switches 87306, Involuntary context switches 10326

--concurrency代表并发数量,多个可以用逗号隔开,当然你也可以用自己的分隔符隔开,这个时候要用到--delimiter开关。
--engines代表要测试的引擎,可以有多个,用分隔符隔开。
--iterations代表要运行这些测试多少次。
--auto-generate-sql 代表用系统自己生成的SQL脚本来测试。
--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
--number-of-queries 代表总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算。比如倒数第二个结果2=200/100。
--debug-info 代表要额外输出CPU以及内存的相关信息。
--number-int-cols 代表示例表中的INTEGER类型的属性有几个。
--number-char-cols 意思同上。
--create-schema 代表自己定义的模式(在MySQL中也就是库)。
--query 代表自己的SQL脚本。
--only-print 如果只想打印看看SQL语句是什么,可以用这个选项。

现在来看一些我测试的例子。

1、用自带的SQL脚本来测试。
MySQL版本为5.1.23
[root@localhost ~]# mysqlslap --defaults-file=/usr/local/mysql-maria/my.cnf --concurrency=50,100,200 --iterations=1 --number-int-cols=4 --number-char-cols=35 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=200 --debug-info -uroot -p1 -S/tmp/mysql_3310.sock

Benchmark
        Running for engine myisam
        Average number of seconds to run all queries: 0.063 seconds
        Minimum number of seconds to run all queries: 0.063 seconds
        Maximum number of seconds to run all queries: 0.063 seconds
        Number of clients running queries: 50
        Average number of queries per client: 4

Benchmark
        Running for engine myisam
        Average number of seconds to run all queries: 0.070 seconds
        Minimum number of seconds to run all queries: 0.070 seconds
        Maximum number of seconds to run all queries: 0.070 seconds
        Number of clients running queries: 100
        Average number of queries per client: 2

Benchmark
        Running for engine myisam
        Average number of seconds to run all queries: 0.092 seconds
        Minimum number of seconds to run all queries: 0.092 seconds
        Maximum number of seconds to run all queries: 0.092 seconds
        Number of clients running queries: 200
        Average number of queries per client: 1

Benchmark
        Running for engine innodb
        Average number of seconds to run all queries: 0.115 seconds
        Minimum number of seconds to run all queries: 0.115 seconds
        Maximum number of seconds to run all queries: 0.115 seconds
        Number of clients running queries: 50
        Average number of queries per client: 4

Benchmark
        Running for engine innodb
        Average number of seconds to run all queries: 0.134 seconds
        Minimum number of seconds to run all queries: 0.134 seconds
        Maximum number of seconds to run all queries: 0.134 seconds
        Number of clients running queries: 100
        Average number of queries per client: 2

Benchmark
        Running for engine innodb
        Average number of seconds to run all queries: 0.192 seconds
        Minimum number of seconds to run all queries: 0.192 seconds
        Maximum number of seconds to run all queries: 0.192 seconds
        Number of clients running queries: 200
        Average number of queries per client: 1


User time 0.06, System time 0.15
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 5803, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 8173, Involuntary context switches 528


我来解释一下结果的含义。
拿每个引擎最后一个Benchmark示例。
对于INNODB引擎,200个客户端同时运行这些SQL语句平均要花0.192秒。相应的MYISAM为0.092秒。

2、用我们自己定义的SQL 脚本来测试。
这些数据在另外一个MySQL实例上。版本为5.0.45
先看一下这两个表的相关数据。
1)、总记录数。
mysql> select table_rows as rows from information_schema.tables where table_schema='t_girl' andtable_name='article';
+--------+
| rows   |
+--------+
| 296693 |
+--------+
1 row in set (0.01 sec)

mysql> select table_rows as rows from information_schema.tables where table_schema='t_girl' andtable_name='category';
+------+
| rows |
+------+
| 113  |
+------+
1 row in set (0.00 sec)

2)、总列数。
mysql> select count(*) as column_total from information_schema.columns where table_schema = 't_girl'and table_name = 'article';
+--------------+
| column_total |
+--------------+
| 32           |
+--------------+
1 row in set (0.01 sec)

mysql> select count(*) as column_total from information_schema.columns where table_schema = 't_girl'and table_name = 'category';
+--------------+
| column_total |
+--------------+
| 9            | 
+--------------+
1 row in set (0.01 sec)


3)、调用的存储过程
DELIMITER $$

DROP PROCEDURE IF EXISTS `t_girl`.`sp_get_article`$$

CREATE DEFINER=`root`@`%` PROCEDURE `sp_get_article`(IN f_category_id int,
 IN f_page_size int, IN f_page_no int
)
BEGIN
  set @stmt = 'select a.* from article as a inner join ';
  set @stmt = concat(@stmt,'(select a.aid from article as a ');
  if f_category_id != 0 then
    set @stmt = concat(@stmt,' inner join (select cid from category where cid = ',f_category_id,' or parent_id = ',f_category_id,') as b on a.category_id = b.cid');
  end if;
  if f_page_size >0 && f_page_no > 0 then
    set @stmt = concat(@stmt,' limit ',(f_page_no-1)*f_page_size,',',f_page_size);
  end if; 
 
  set @stmt = concat(@stmt,') as b on (a.aid = b.aid)');
  prepare s1 from @stmt;
  execute s1;
  deallocate prepare s1;
  set @stmt = NULL;
END$$

DELIMITER ;

4)、我们用mysqlslap来测试
以下得这个例子代表用mysqlslap来测试并发数为25,50,100的调用存储过程,并且总共调用5000次。
[root@localhost ~]# mysqlslap --defaults-file=/usr/local/mysql-maria/my.cnf --concurrency=25,50,100 --iterations=1 --query='call t_girl.sp_get_article(2,10,1);' --number-of-queries=5000 --debug-info -uroot -p -S/tmp/mysql50.sock
Enter password: 
Benchmark
        Average number of seconds to run all queries: 3.507 seconds
        Minimum number of seconds to run all queries: 3.507 seconds
        Maximum number of seconds to run all queries: 3.507 seconds
        Number of clients running queries: 25
        Average number of queries per client: 200
平均每个并发运行200个查询用了3.507秒。
Benchmark
        Average number of seconds to run all queries: 3.742 seconds
        Minimum number of seconds to run all queries: 3.742 seconds
        Maximum number of seconds to run all queries: 3.742 seconds
        Number of clients running queries: 50
        Average number of queries per client: 100

Benchmark
        Average number of seconds to run all queries: 3.697 seconds
        Minimum number of seconds to run all queries: 3.697 seconds
        Maximum number of seconds to run all queries: 3.697 seconds
        Number of clients running queries: 100
        Average number of queries per client: 50


User time 0.87, System time 0.33
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 1877, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 27218, Involuntary context switches 3100


看一下SHOW PROCESSLIST 结果
mysql> show processlist;
+------+------+--------------------+--------------------+---------+-------+--------------------+------------------------------------------------------------------------------------------------------+
| Id   | User | Host               | db                 | Command | Time  | State              | Info                                                                                                 |
+------+------+--------------------+--------------------+---------+-------+--------------------+------------------------------------------------------------------------------------------------------+
…………
| 3177 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3178 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3179 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3181 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3180 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3182 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3183 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3187 | root | %                  | t_girl             | Query   |     0 | removing tmp table | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3186 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3194 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3203 | root | %                  | t_girl             | Query   |     0 | NULL               | deallocate prepare s1                                                                                |
…………
| 3221 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3222 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3223 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3224 | root | %                  | t_girl             | Query   |     0 | removing tmp table | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3225 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
| 3226 | root | %                  | t_girl             | Query   |     0 | NULL               | select a.* from article as a inner join (select a.aid from article as a  inner join (select cid from |
+------+------+--------------------+--------------------+---------+-------+--------------------+------------------------------------------------------------------------------------------------------+
55 rows in set (0.00 sec)

上面的测试语句其实也可以这样写
[root@localhost ~]# mysqlslap --defaults-file=/usr/local/mysql-maria/my.cnf --concurrency=25,50,100 --iterations=1 --create-schema='t_girl' --query='call sp_get_article(2,10,1);' --number-of-queries=5000 --debug-info -uroot -p -S/tmp/mysql50.sock

小总结一下。
mysqlslap对于模拟多个用户同时对MySQL发起“进攻”提供了方便。同时详细的提供了“高负荷攻击MySQL”的详细数据报告。
而且如果你想对于多个引擎的性能。这个工具再好不过了。

本文出自 “上帝,咱们不见不散!” 博客,转载请与作者联系!
http://yueliangdao0608.blog.51cto.com/397025/81602

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29096438/viewspace-1828727/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
毕业以后专业任职数据库工程师职位,itpub一直作为自己的笔记记录的地方,blog写的不详细,草书笔记,仅供参考!

注册时间:2013-09-12

  • 博文量
    529
  • 访问量
    1126938