woowacourse-study / 2022-Real-MySQL

⚡️토르⚡️의 짜릿한 Real MySQL 뽀개기 🔨
9 stars 3 forks source link

프로세스 조회 및 강제 종료 #34

Open wishoon opened 2 years ago

wishoon commented 2 years ago

주제

프로세스 조회 및 강제 종료

선정 이유

최근 어플리케이션 서버 장애 문제를 겪은 적이 있었다. 해당 문제를 해결하는 과정 속에서 선배 개발자들의 장애 경험기를 들을 수 있었는데, 이번 글의 내용이 해당 상황에서도 사용할 수 있는 상황이라고 생각이 들어서 선정하게 되었다.

해당 텍스트

프로세스 조회 및 강제 종료

MySQL은 서버에 접속된 사용자의 목록이나 각 클라이언트의 사용자가 현재 어떤 쿼리를 실행하고 있는지 SHOW PROCESSLIST 명령으로 확인할 수 있다.

mysql> SHOW PROCESSLIST:

해당 명령의 결과에는 현재 MySQL 서버에 접속된 클라이언트의 요청을 처리하는 스레드 수만큼의 레코드가 표시가 되는데, 각 칼럼에 포함된 값의 의미는 다음과 같다.

* Id : MySQL 서버의 스레드 아이디이며, 쿼리나 커넥션을 가엦 종료할 때는 이 칼럼 값을 식별자로 사용한다.
* User: 클라이언트가 MySQL 서버에 접속할 때 인증에 사용한 사용자 계정을 의미한다.
* Host: 클라이언트의 호스트명이나 IP 주소가 포함된다.
* db: 클라이언트가 기본으로 사용하는 데이터베이스의 이름이 표시된다.
* Command: 해당 스레드가 현재 어떤 작업을 처리하고 있는지 표시한다.
* Time: Command 칼럼에 표시되는 작업이 얼마나 실행되고 있는지 표시한다. 
* State: Command 칼럼에 표시되는 내용이 해당 스레드가 처리하고 있는 작업의 큰 분류를 보여준다면 State 칼럼에는 소분류 작업 내용을 보여준다.
* Info: 해당 스레드가 실행 중인 쿼리 문장을 보여준다. (화면에 맞춰서 쿼리를 보여주기 때문에 전체를 보고 싶을 때는 `SHOW PULL PROCESSLIST` 명령어를 사용한다.

SHOW PROCESSLIST 명령은 MySQL 서버가 어떤 상태인지를 판단하는 데도 많은 도움이 된다. 일반적으로 쾌적한 상태로 서비스되는 MySQL에서는 대부분 프로세스의 Command 칼럼이 Sleep 상태로 표시된다.

만약 Command 칼럼이 Query이면서 Time이 상당히 큰 값을 가지고 있다면 상당히 장시간동안 쿼리가 지속되고 있음을 알 수가 있다.

SHOW PROCESSLIST의 결과에서 특별히 관심을 둬야 할 부분은 State 칼럼의 내용이다. State 칼럼에 표시될 수 있는 값은 종류가 다양한데, MySQL의 문서에 자세하게 나와있다.

또한, 현재 실행 중인 쿼리나 커넥션을 강제 종료하려면 KILL 명령을 사용하여 문제를 해결할 수 있다.

mysql> KILL QUERY 4228;
mysql> KILL 4228;

위의 명령은 ID가 4228인 스레드가 실행 중인 쿼리를 종료하라는 의미이고, 밑의 명령은 ID가 4228인 커넥션을 종료하라는 의미이다. 커넥션이 종료될 경우, 커넥션에서 처리하고 있던 트랜잭션은 자동으로 롤백 처리된다.

활성 트랜잭션 조회

쿼리가 오래 실행되는 것도 문제지만, 트랜잭션이 오랜 시간 완료되지 않고 활성 상태로 남아있는 것도 MySQL 서버의 성능에 영향을 줄 수 있다. 이를 확인하고 싶다면 information_schema.inodb_trx 테이블에서 확인이 가능하다.

다음 예시를 통해서 어떻게 사용하는지 확인할 수 있다.

mysql> SELECT trx_id,
            (SELECT CONCAT(user, '@', host)
             FROM information_schema.processlist
             WHERE id=trx_mysql_thread_id) AS source_info,
             trx_state, trx_started, now() ....
       FROM information_schema.innodb_trx
       WHERE (unix_timestamp(now()) - unix_timestamp(trx_started)))>5 \G

위의 쿼리는 트랜잭션이 5초 이상 활성 상태로 남아있는 프로세스만 조사하는 쿼리다. 이를 통해서 프로세스 칼럼의 값, 계정, 몇분(초)동안 활성 트랜잭션 상태를 유지하고 있는지, 얼마나 많은 레코드를 변경했고 레코드를 잠그고 있는지 확인이 가능하다.

관련 페이지

202p ~ 207p

HJ-Rich commented 2 years ago

이건 귀하군요..👍