본문 바로가기
MySQL

pt-kill

by 타마마임팩트_쫀 2021. 8. 19.

pt-kill은 이해하기 어렵고 예제가 많지 않습니다. pt-kill의 가장 일반적인 사용법에 대해 알아 봅시다.

pt-kill 은 SHOW PROCESSLIST에서 쿼리를 캡처하고 필터링한 다음 종료하거나 인쇄합니다. 용도는 너무 많은 리소스를 소비할 수 있는 쿼리를 감시하고 종료하는 것입니다.

보통은 쿼리 종료에 사용하지만 주어진 옵션에 따라 출력도 할 수 있습니다.

일반적으로 pt-kill 은 MySQL에 연결하여 SHOW PROCESSLIST에서 쿼리를 가져 오지만 파일에서 SHOW PROCESSLIST 출력을 읽을 수 있습니다. 이 경우 pt-kill 은 MySQL에 연결하지 않으며 '--kill' 옵션이 효과가 없습니다. '--print'는 파일을 읽을 때 대신 사용해야 합니다. 파일을 읽는 기능을 '--test-matching'으로 사용하면 SHOW PROCESSLIST를 캡처하고 나중에 pt-kill 로 일치하는 항목이 적절한 쿼리를 종료하는지 확인할 수 있습니다.

일반적으로 하나 이상의 '--match'옵션 을 지정해야 합니다 . 그렇지 않으면 '--match-all' 옵션으로 모든 쿼리와 일치하도록 지정할 수 있습니다. 일치하는 쿼리가 없을 경우 '--ignore' 사용 할 수 있습니다..

다음과 같은 쿼리를 실행하는 sysbench 도구를 실행하고 있다고 가정해 보겠습니다.

select distinct c from sbtest1 where id between 1 and 20 order by c
select distinct c from sbtest2 where id between 5 and 25 order by c
select distinct c from sbtest3 where id between 3 and 7 order by c
select distinct c from sbtest1 where id between 2 and 8 order by c
select distinct c from sbtest3 where id between 15 and 30 order by c

동시에 다른 프로세스에서 다음을 실행하고 있습니다.

SELECT SLEEP 10

그런 다음 위 쿼리가 실행되는 동안 다음 매개변수(2초 이상 수행 중인 select|SELECT 쿼리) 를 사용하여 pt-kill 을 시작합니다.

pt-kill --kill-busy-commands=Query --run-time 30m --interval 1 --busy-time 2s --print --match-info "(select|SELECT)"

출력에 다음과 같은 내용이 표시됩니다.

# 2019-06-20T11:40:23 KILL 31 (Query 2 sec) SELECT SLEEP(10)
# 2019-06-20T11:40:23 KILL 513 (Execute 0 sec) SELECT DISTINCT c FROM sbtest48 WHERE id BETWEEN 4980 AND 5079 ORDER BY c
# 2019-06-20T11:40:23 KILL 524 (Execute 0 sec) SELECT c FROM sbtest24 WHERE id=4997
# 2019-06-20T11:40:23 KILL 512 (Execute 0 sec) SELECT c FROM sbtest48 WHERE id BETWEEN 5001 AND 5100 ORDER BY c
# 2019-06-20T11:40:23 KILL 516 (Execute 0 sec) SELECT SUM(k) FROM sbtest41 WHERE id BETWEEN 4988 AND 5087

'select sleep 10'은 '--busy-time 2s' 초과하므로 종료해야 하지만 실행 시간이 0초인 다른 쿼리도 종료되는 이유는 무엇일까요?

먼저 프로그램이 동작하는 기준을 확인 해야 합니다.

첫째, '--group-by'에 따라 쿼리를 버킷으로 그룹화 합니다. 명령줄에는 그룹화 기준이 없으므로 찾은 모든 쿼리가 포함된 버킷은 하나만 있습니다. 두 번째 단계는 일치 기준을 확인하는 것입니다. 지정된 모든 기준이 논리적 'OR'을 통해 결합된다는 점이 중요합니다.

위에 예제에는 두 가지 일치 조건이 있습니다.

'--busy-time 2s', '--match-info "(select|SELECT)"'

'select sleep 10' 쿼리는 두가지 조건에 모두 일치 하지만 일지 기준은 'OR'을 통해 적용 되므로 조건 중 하나만 일치해도 실행 되므로 sysbench 쿼리 또한 적용 대상이 됩니다.

그러면 '--busy-time' 대신에 '--each-busy-time'을 사용하면 어떻게 될까요?

쿼리가 종료되지 않습니다.

Bucket:
default

Queries:
- SELECT SLEEP (10)
- SELECT c FROM sbtest24 WHERE id=4997

보기 쉽게 만들었습니다. 동일한 버킷에 10초 동안 수행되는 쿼리와 0초 동안 수행하는 쿼리가 있습니다. 수행되는 모든 쿼리가 2초 이상 실행이 되어야지만 기준이 일치 합니다.

그러면 다시 처음으로 돌아가서 2초 이상 수행 중인 select|SELECT 쿼리를 종료 하려면 아래와 같이 수행하면 됩니다.

pt-kill --kill-busy-commands=Query --run-time 30m --interval 1 --each-busy-time 2s --print --match-info "(select|SELECT)" --group-by=fingerprint

'--group-by'를 사용하여 2개의 버킷을 생성 하였습니다.

매칭 기준인 '--each-busy-time'은 그룹에 개별적으로 적용 됩니다.

Bucket:
select sleep(?)
 
Queries:
- (Query 3 sec) SELECT SLEEP(10)
Bucket:
select c from sbtest? where id=?
 
Queries:
# (Execute 0 sec) SELECT DISTINCT c FROM sbtest9 WHERE id BETWEEN 4985 AND 5084 ORDER BY c
# (Execute 0 sec) SELECT SUM(k) FROM sbtest32 WHERE id BETWEEN 4986 AND 5085
# (Execute 0 sec) SELECT c FROM sbtest8 WHERE id=5983
# (Execute 0 sec) SELECT DISTINCT c FROM sbtest20 WHERE id BETWEEN 5570 AND 5669 ORDER BY c
# (Execute 0 sec) SELECT c FROM sbtest30 WHERE id BETWEEN 4504 AND 4603 ORDER BY c
# (Execute 0 sec) SELECT c FROM sbtest8 WHERE id BETWEEN 4988 AND 5087
# (Execute 0 sec) SELECT c FROM sbtest27 WHERE id=5013

첫 번째 그룹의 경우 SELECT가 2초 이상 실행되고 나서 종료되므로 일치합니다.

두 번째 그룹에 대해 쿼리는 모두 2초보다 커야합니다. 따라서 두 번째 그룹의 쿼리는 종료되지 않으며 처음에 원하는 것을 달성했습니다.

 

pt-kill에 대한 기본적은 사용법은 다음에서 확인 가능 합니다.

https://www.percona.com/doc/percona-toolkit/LATEST/pt-kill.html

사용법

pt-kill  [ 옵션 ]  [ DSN ]

60초 이상 실행되는 쿼리 종료:

pt-kill --busy-time 60 --kill

60초 이상 실행되는 쿼리를 종료 하지 않고 출력:

pt-kill --busy-time 60 --print

sleep 프로세스를 확인하고 10초마다 모두 종료:

pt-kill --match-command Sleep --kill --victims all --interval 10

모든 로그인 프로세스 출력:

pt-kill --match-state login --print --victims all

'SHOW PROCESSLIST'에서 어떤 쿼리가 일치하는지 확인:

mysql -e "SHOW PROCESSLIST" > proclist.txt 
pt-kill --test-matching proclist.txt --busy-time 60 --print

 

 

'MySQL' 카테고리의 다른 글

MySQL Shell Upgrade Checker Utility  (0) 2021.08.24
MySQL 8 및 MySQL 5.7 메모리 소비  (0) 2021.08.24
ONLY_FULL_GROUP_BY SQL 쿼리 실패  (0) 2021.08.12
MySQL sorted index 생성  (0) 2021.08.06
innodb_open_files과 open_files_limit  (0) 2021.08.04