MySQL - mysqlslap 를 이용한 DB 부하 생성 및 성능 테스트

Last Updated on 2월 15, 2021 by 태랑(정현호)



MySQL 서버에 대한 클라이언트 로드 에뮬레이터



mysqlslap 은 MySQL 서버에 대한 클라이언트 로드를 에뮬레이트하고 각 단계의 타이밍을 보고 하도록 설계된 진단 프로그램입니다.

Concurrency 파라미터를 통해 여러 클라이언트가 동시에 DB서버에 액세스하는 것처럼 작동합니다


Mysql 설치 시 같이 제공 되는 기본 유틸리티 중 하나 입니다.







Mysqlslap runs in three stages



mysqlslap은 세 단계로 실행되게 됩니다(3-Phase)


Phase 1 - 테스트에 사용할 스키마, 테이블 및 선택적으로 저장된 프로그램 또는 데이터를 생성합니다. 이 단계는 단일 클라이언트 연결을 사용합니다.
이 단계는 --auto-generate-sql 를 사용하면서 사용 되는 단계이고 사용자가 직접 테이블을 미리 생성하거나 --query 절을 통해 수행 하는 경우 Phase2 로 넘어가게 됩니다.


Phase 2 - 실제로 부하가 발생하고 테스트 하는 과정으로 실행시 지정한 --concurrency 옵션 값으로 동시에 많은 클라이언트가 접속되어 수행 합니다.


Phase 3 - 정리 (연결 해제, 지정된 경우 테이블 삭제). 이 단계는 단일 클라이언트 연결을 사용합니다.
사용자가 별도로 생성한 Database(Schema) 와 Table 을 이용하여 수행시 삭제되지 않습니다.







mysqlslap 예제



예제를 보면서 옵션을 살펴보도록 하겠습니다.


예제)

[root]# mysqlslap --login-path=dba --concurrency=200 --iterations=100 --auto-generate-sql --verbose

먼저 mysqlslap 에서도 --login-path 를 사용 할 수 있습니다.
사용하게 되면 명령어 라인이 짧아지고 쉬워져서 사용하는 것이 편리합니다.
--login-path 는 아래 포스트를 참고하시면 됩니다.


--concurrency=200 --iterations=100 는 동시 접속자 200세션으로 100번 수행을 의미 합니다

--auto-generate-sql 는 데이터베이스,테이블을 자동으로 생성하게 됩니다
  auto-generate-sql 를 사용하게 되면 종료 되면서 생성한 테이블과 데이터베이스(Schema)는 삭제 됩니다.





예제)

[root]# mysqlslap --login-path=dba --concurrency=200 --iterations=100 --auto-generate-sql --auto-generate-sql-guid-primary --auto-generate-sql-load-type=read --verbose



다음은 auto-generate-sql 과 연계되어서 사용되는 auto-generate-* 와 auto-generate-sql-load-type 을 살펴보겠습니다.


더 많은 내용은 아래 문서를 확인 하시면 됩니다



--auto-generate-sql-add-autoincrement : Add AUTO_INCREMENT column to automatically generated tables

--auto-generate-sql-execute-number :  Specify how many queries to generate automatically

--auto-generate-sql-guid-primary :  Add a GUID-based primary key to automatically generated tables

--auto-generate-sql-load-type    Specify the test load type(Default=mix)
    read (scan tables), write (insert into tables), key (read primary keys), update (update primary keys) or mixed (half inserts, half scanning selects). The default is mixed.

--auto-generate-sql-secondary-indexes :  Specify how many secondary indexes to add to automatically generated tables

--auto-generate-sql-unique-query-number : How many different queries to generate for automatic tests

--auto-generate-sql-unique-write-number: How many different queries to generate for --auto-generate-sql-write-number

--auto-generate-sql-write-number   :  How many row inserts to perform on each thread




--auto-generate-sql-load-type 는 load에 대한 타입을 지정해주는 옵션으로 red,write ,key, update, mixed 가 있으며 default는 mixed 입니다.

그 외 위에서 언급한 옵션 들은 옵션의 명칭으로 대략의 내용을 확인 할 수 있습니다.




그래서 위에서 예제로 수행한 명령어는 아래와 같은 의미 입니다.
--auto-generate-sql : 자동으로 생성하고 
--auto-generate-sql-guid-primary : 수행하는 종류
--auto-generate-sql-load-type=read  : 부하의 종류 



--create-schema 옵션은 --auto-generate-sql 과 같이 사용했을 경우 테이블이 생성할 database(Schema)를 별도로 지정하는 옵션입니다.





별도로 지정하지 않는다면 기본은 mysqlslap 으로 스키마를 생성하고 테이블명은 t1  으로 생성 합니다.

수행이 완료되면 위에서 언급한것처럼 삭제 가 됩니다.



mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| mysqlslap |
| performance_schema |
| sys |
+--------------------+
9 rows in set (0.00 sec)



mysql> use mysqlslap;
Database changed



mysql> show tables;
+---------------------+
| Tables_in_mysqlslap |
+---------------------+
| t1 |
+---------------------+
1 row in set (0.00 sec)



--create-schema 옵션을 -query 와 같이 사용할 경우에는 별도로 생성 해줘야 합니다.





예제)

[root]# mysqlslap --login-path=dba --concurrency=200 --iterations=100 \
--create-schema=employees --query="SELECT * FROM emp;" --delimiter=";" --verbose


이와 같이 수행을 하게 되면 아래와 같이 
mysqlslap: Error when connecting to server: 1049 Unknown database 'employees'



데이터베이스 생성 후 수행하게 되면 아래와 같은 에러가 발생됩니다.

mysqlslap: Cannot run query SELECT * FROM employees ERROR : Table 'employees.emp' doesn't exist





그래서 query 로 별도로 수행할 경우 에는 직접 스키마(데이터베이스) 와 쿼리에 사용할 테이블의 생성이 필요 합니다.





위의 예제를 정상적으로 수행하기 위해서는 아래와 같이 데이터베이스와 테이블을 생성후 수행을 하면 됩니다.


mysql> CREATE DATABASE employees;


mysql> CREATE TABLE emp (
`id` int(11) NOT NULL,
`name` varchar(16) NOT NULL,
`department_id` int(11) NOT NULL,
`birth_date` date NOT NULL,
PRIMARY KEY (`id`)
) CHARSET=utf8;


mysql> INSERT INTO emp (id, name, department_id, birth_date) VALUES

(1, 'AB', 1, '1999-01-01'),
(2, 'BC', 2, '2000-01-01'),
(3, 'CD', 2, '1999-01-01'),
(4, 'EF', 3, '2000-01-01');


mysql> commit;



별도로 생성 후 수행을 하게 되면 수행 완료 후 삭제 되지는 않습니다.








예제)

--query="SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;" --delimiter=";"




--delimiter=";" 은 아래와 같이 --query 절에 여러 sql이 있을때 쿼리간의 구분점을 지정하는 것 입니다.



다시 --query 옵션을 보면 아래 처럼 테이블을 생성 하면서 데이터를 입력하면서 조회까지 하는 쿼리를 명령어 라인에서 기재하여 수행이 가능하고

--delimiter=";" --create="CREATE TABLE a (b int);INSERT INTO a VALUES (23)" --query="SELECT * FROM a" --concurrency=50 --iterations=200



--query 절에서는 --query=/usr/local/mysql/test.sql 이와 같이 파일로 저장된 sql 파일로 저장된 쿼리를 수행하는 것도 가능 합니다.







Benchmark 결과 



# 결과는 아래와 같은 형태로 확인 할 수 있습니다.



Benchmark


Average number of seconds to run all queries: 24.863 seconds
Minimum number of seconds to run all queries: 24.761 seconds
Maximum number of seconds to run all queries: 25.020 seconds
Number of clients running queries: 3
Average number of queries per client: 1



sysbench 를 별도로 설치하여 조금더 복잡하고 자세한 성능테스트를 할수 있지만 기본적으로 제공되는 유틸리티인 만큼 별도의 설치 없이 테스트 용도로 부하생성기 역활 이나 기본적인 성능 테스트 용도로 충분히 사용이 가능 할걸로 생각 됩니다.




연관된 글 : Sysbench 를 사용하여 성능 테스트(벤차마크) 수행

CTAS/Insert Select 에서 공유락 관련된 내용 확인



답글 남기기