💡 본 내용은 Real MySQL 8.0 1권을 읽으면서 정리한 내용입니다.
이미 프로그래밍 언어를 접하고 사용하고 있는 많은 분들은 문제가 생겼을 때 로그 파일을 확인해서 문제가 되는 부분을 찾곤 한다.
MySQL도 마찬가지로 서버에 문제가 생겼을 때, 로그 파일을 자세히 확인하는 습관을 가지는 것이 필요하다.
여러가지 로그 파일들에 대해 같이 알아보자.
MySQL이 실행되는 도중에 발생하는 에러나 경고 메세지가 출력되는 로그 파일이다.
에러 로그 파일 위치는 MySQL 설정파일(my.cnf)에서 log_err라는 이름의 파라미터로 정의된 경로에 생성된다.
설정 파일에 별도로 정의되지 않은 경우에는 데이터 디렉터리에 .err 확장자가 붙은 파일로 생성된다.
MySQL의 설정 파일을 변경하거나 DB가 비정상적으로 종료된 후 다시 시작할 때 에러 로그 파일을 통해 설정된 변수의 이름 or 값이 명확하게 적용됐는지 확인해야 한다.
MySQL 서버를 작동하면서 경고가 없거나 에러가 없다면 정상 적용이 된 것
만약 특정 변수가 무시된 경우에는 MySQL 서버는 잘 작동했지만, 해당 파라미터는 MySQL에 제대로 적용이 안 된 것이다.
또한 변수명을 인식 못하거나 설정된 파라미터 값의 내용을 인식하지 못하는 경우 -> MySQL이 에러 메시지를 출력하고 시작 못했다는 메시지를 보여준다.
InnoDB는 비정상적으로 종료되면 다시 시작되면서 완료 못했던 트랜잭션을 정리하고, 기록 못한 데이터가 있다면 다시 기록하는 재처리 작업을 한다.
그럼에도 복구되지 못할 때는 에러 메시지를 출력하고 MySQL은 다시 종료된다.
이전 게시글에서 봤던 innodb_force_recovery 파라미터를 설정하고 순차적으로 해야지 재시작할 수 있을 것이다.
쿼리 도중에는 발생하는 에러는 사전 예방이 어려우며, 주기적으로 에러 로그 파일을 검토하는 과정에서 알게 된다.
자주 에러 로그 파일을 검토하는 것이 DB의 숨겨진 문제점을 해결하는데 도움을 줄 것이다.
DB 서버를 볼 때 이 메시지가 상당히 누적된 경우도 볼 수 있다.
클라이언트 애플리케이션에서 정상적으로 접속 종료를 못한 채로 프로그램이 종료된 경우 MySQL의 에러 로그 파일에 이런 내용이 기록된다고 한다.
중간에 네트워크 문제로 의도치 않게 접속이 끊어져도 기록된다고 하고, 너무 많은 경우에는 커넥션 종료 로직을 검토해야 한다.
max_connect_errors 시스템 변숫값이 너무 낮게 설정된 경우-> 시스템 변수 값을 늘려주면 해결된다.
그럼에도 어떻게 발생하게 됐는지 그 원인을 살펴봐야 한다.
사용해본 경험자라면 가끔 MySQL이 아무도 모르게 종료돼 있거나 재시작한 경우를 본 적 있을 것이다.
이 때는 에러 로그 파일에서 마지막으로 종료되면서 출력한 메시지를 확인하는 것이 왜 종료됐는지 확인하는 유일한 방법이다.
Received SHUTDOWN from user ... 과 같은 메시지2번째와 같은 경우에는 스택 트레이스의 내용을 최대한 참조 해 버그와 연관이 있는지 조사하고 업그레이드하거나, 회피책을 찾는 것이 최적의 방법이다.
MySQL 서버에서 실행되는 전체 쿼리를 조회하기 위해 사용한다.
MySQL 서버의 쿼리 튜닝은 아래와 같이 나눌 수 있다.
후자의 경우 어떤 쿼리가 문제의 쿼리인지 판단하기 상당히 어려운데, 슬로우 쿼리 로그가 상당한 도움이 되니 알아보자.
슬로우 쿼리 로그 파일엔 long_query_time 시스템 변수에 설정한 시간 이상이 소요된 쿼리가 기록된다.
실제 소요된 시간을 기준으로 기록 여부를 판단하기 때문에 정상적으로 실행된 쿼리만 기록된다.
즉, 슬로우 쿼리 로그 파일에 기록된 쿼리는 일단 정상적으로 실행됐고, 실행하는데 걸린 시간이
long_query_time에 정의도니 시간보다 많이 걸린 쿼리인 것이다.
log_output 옵션을 이용하여 로그를 파일로 기록할지 테이블로 기록할지 선택할 수 있다.
하지만 테이블로 설정하더라도 slow_log 테이블과 general_log 테이블은 CSV 스토리지 엔진을 사용하기 때문에 파일 저장과 동일하게 동작한다.
슬로우 쿼리 로그 구성
Time: 쿼리가 종료된 시점 -> 언제 시작됐는지 알려면 (Time) - (Query_time)
User@Host: 쿼리를 실행한 사용자 계정
Query_time: 쿼리가 실행되는 데 걸린 시간
Lock_time: InnoDB의 경우 MySQL 엔진 레벨의 잠금과 스토리지 엔진 자체의 잠금을 가지고 있는데, Lock_time은 MySQL 엔진 레벨에서의 테이블 잠금에 대한 대기 시간을 의미한다. 이 값은 쿼리 실행 전의 잠금 체크와 같은 코드 실행 시간까지 포함되기 때문에 매우 작은 값이라면 무시해도 무방하다.
Rows_examined: 쿼리가 처리되기 위해 접근한 레코드
Rows_sent: 실제 클라이언트로 보내진 레코드
로그 분석을 좀 더 쉽게 하기 위해 Percona Toolkit의 pt-query-digest 스크립트를 사용할 수 있다.
아래 내용은 Real MySQL 8.0 -> p.152 참고
- 슬로우 쿼리 통계
- 실행 빈도 및 누적 실행 시간순 랭킹
- 쿼리별 실행 횟수 및 누적 실행 시간 상세 정보