한 줄 정의
MySQL 로그 파일은 에러 진단, 쿼리 감사, 성능 튜닝을 위한 핵심 도구이며, 특히 슬로우 쿼리 로그는 실무에서 가장 많이 활용됩니다.
쉽게 말하면
MySQL 서버의 상태를 진단하는 청진기 같은 존재입니다. 서버가 아프면(성능 저하, 비정상 종료) 로그 파일을 먼저 확인하는 것이 기본입니다.
내부 지식이 깊지 않아도 로그 파일만 잘 읽으면 대부분의 문제 원인을 파악할 수 있습니다.
왜 중요한가?
- 서버가 비정상 종료됐을 때 → 에러 로그 로 원인 파악
- 어떤 쿼리가 실행되고 있는지 → 제너럴 쿼리 로그 로 전수 확인
- 어떤 쿼리가 느린지 → 슬로우 쿼리 로그 로 튜닝 대상 식별
핵심 내용
에러 로그 파일
MySQL 실행 중 발생하는 에러/경고 메시지가 기록됩니다.
- 위치:
my.cnf의log_error파라미터 (미설정 시datadir/*.err) - MySQL 서버 설정을 변경한 후에는 반드시 에러 로그를 확인 하여 의도대로 적용됐는지 검증해야 합니다
주요 메시지 유형
| 유형 | 설명 | 대응 |
|---|---|---|
| 시작/종료 관련 | 설정 파라미터 적용 여부, ready for connections 확인 | 변경 후 반드시 확인 |
| InnoDB 트랜잭션 복구 | 비정상 종료 후 재시작 시 복구 과정 | 실패하면 innodb_force_recovery 조정 |
| 쿼리 처리 에러 | 실행 중 발생한 에러, 복제 문제 경고 | 주기적으로 검토하여 숨겨진 문제 발견 |
| 비정상 종료 커넥션 (Aborted connection) | 클라이언트가 정상 종료하지 않음 | 많으면 애플리케이션 커넥션 종료 로직 점검. max_connect_errors 값 확인 |
| InnoDB 모니터링 결과 | SHOW ENGINE INNODB STATUS 등의 출력 | 모니터링 후 반드시 비활성화 (로그 파일 비대화 방지) |
| MySQL 종료 메시지 | 정상/비정상 종료 여부 판단 | Received SHUTDOWN from user → 정상. 스택 트레이스 → Segfault |
제너럴 쿼리 로그 (General Log)
MySQL 서버에서 실행되는 모든 쿼리 가 기록됩니다.
- 슬로우 쿼리 로그와 달리 쿼리 요청을 받은 즉시 기록합니다 (실행 완료 전)
- 에러가 발생한 쿼리도 기록됩니다
- 위치:
general_log_file파라미터 log_output으로 파일/테이블 선택 가능
SHOW GLOBAL VARIABLES LIKE 'general_log_file';모든 쿼리를 기록하므로 성능 부하가 크고 로그 파일이 빠르게 커집니다. 상시 활성화가 아니라 특정 기간 동안만 켜서 분석하는 용도로 사용하는 것이 일반적입니다.
슬로우 쿼리 로그
실무에서 가장 자주 활용 되는 로그입니다. long_query_time(초 단위, 소수점으로 마이크로초까지 설정 가능) 이상 걸린 쿼리를 기록합니다.
- 정상 완료된 쿼리만 기록됩니다 (실행 중 에러가 나면 기록 안 됨)
log_output으로 파일 또는 테이블(mysql.slow_log) 선택 가능
로그 항목 해석
# Time: 2020-07-19T15:44:22.178484+09:00
# User@Host: root[root] @ localhost [] Id: 14
# Query_time: 1.180245 Lock_time: 0.002658 Rows_sent: 1 Rows_examined: 2844047
use employees;
SET timestamp=1595141060;
select emp_no, max(salary) from salaries;
| 항목 | 의미 | 주의사항 |
|---|---|---|
| Time | 쿼리 종료 시점 | 시작 시점은 Time - Query_time |
| Query_time | 쿼리 전체 실행 시간 | |
| Lock_time | MySQL 엔진 레벨의 테이블 잠금 대기 시간 | InnoDB의 레코드 잠금은 포함되지 않음. 매우 작은 값이면 무시 가능 |
| Rows_examined | 접근한 레코드 수 | |
| Rows_sent | 클라이언트로 보낸 레코드 수 | Rows_examined >> Rows_sent면 튜닝 대상 |
Rows_examined vs Rows_sent
이 두 값의 비율 이 튜닝 판단의 핵심입니다:
Rows_examined: 2,844,047/Rows_sent: 1→ 284만 건을 읽어서 1건만 반환- 인덱스를 적절히 활용하면 접근 레코드 수를 대폭 줄일 수 있습니다
pt-query-digest로 분석
슬로우 쿼리 로그가 수만 건이면 직접 검토하기 어렵습니다. Percona Toolkit의 pt-query-digest 가 이 문제를 해결합니다.
# 슬로우 쿼리 로그 분석
pt-query-digest --type='slowlog' mysql-slow.log > parsed.log
# 제너럴 로그 분석
pt-query-digest --type='genlog' general.log > parsed_general.log분석 결과는 3개 섹션으로 구성됩니다:
1. 슬로우 쿼리 통계
전체 쿼리의 실행 시간, 잠금 시간 등의 평균/최소/최대 값입니다.
2. 실행 빈도 및 누적 실행 시간 랭킹
쿼리별 응답 시간과 실행 횟수를 보여줍니다. --order-by 옵션으로 정렬 기준을 변경할 수 있습니다.
# Rank Query ID Response time Calls R/Call
# 1 0x47525E2A043E8AF899FD... 2311636.7007 60.1% 35353 65.3873
# 2 0xB77F2FFEBF2338FD3B6C... 173684.6297 4.5% 73740 2.3554
Response time 비율이 높은 쿼리 가 튜닝 우선순위가 됩니다. 위 예시에서 1번 쿼리가 전체 응답 시간의 60.1%를 차지하므로 이 쿼리를 먼저 튜닝해야 합니다.
3. 쿼리별 상세 정보
각 쿼리의 실행 시간 히스토그램, 호출 호스트, 사용 DB 등 상세 내용을 보여줍니다.
정리
로그 파일 비교
| 로그 | 기록 시점 | 대상 | 주용도 | 성능 영향 |
|---|---|---|---|---|
| 에러 로그 | 에러/경고 발생 시 | 서버 이벤트 | 장애 진단 | 거의 없음 |
| 제너럴 쿼리 로그 | 쿼리 요청 즉시 | 모든 쿼리 | 쿼리 감사, 디버깅 | 매우 큼 (상시 사용 비권장) |
| 슬로우 쿼리 로그 | 쿼리 완료 후 | long_query_time 초과 쿼리 | 성능 튜닝 | 적음 |
log_output: FILE vs TABLE
| 기준 | FILE | TABLE |
|---|---|---|
| 저장 위치 | 디스크 파일 | mysql DB의 테이블 (CSV 엔진) |
| 분석 용이성 | pt-query-digest 등 외부 도구 | SQL로 직접 쿼리 가능 |
| 성능 | 상대적으로 빠름 | 상대적으로 느림 |
| 로테이션 | OS 레벨 로그 로테이션 | TRUNCATE TABLE로 정리 |
내 생각
-
슬로우 쿼리 로그는 반드시 상시 활성화 해두는 것이 좋습니다.
long_query_time을 1~2초로 설정하면 성능 부하 없이 문제 쿼리를 자동 수집할 수 있습니다. -
pt-query-digest는 DBA가 아니어도 반드시 알아두어야 할 도구입니다. 슬로우 쿼리 로그 파일을 넣으면 “어떤 쿼리를 먼저 튜닝해야 하는지” 우선순위를 바로 알 수 있습니다.
-
에러 로그의
Aborted connection이 많다면 애플리케이션의 커넥션 풀 설정을 점검해야 합니다. 커넥션 풀의 idle timeout이 MySQL의wait_timeout보다 긴 경우에 자주 발생합니다. -
InnoDB 모니터링(
SHOW ENGINE INNODB STATUS)을 켜두고 끄는 것을 잊으면 에러 로그 파일이 디스크를 다 먹을 수 있습니다. 모니터링은 항상 일시적으로만 활성화해야 합니다.
관련 개념
출처
- Real MySQL 8.0 (1권), 4.4 MySQL 로그 파일