아래는 로그 위치/확인법을 먼저 안내한 뒤, my.cnf 설정 예시와 함께 검증→재시작 순서로 안전하게 진행하는 절차입니다.
1) 먼저 확인할 로그 위치(배포판/설치 방식별)
MySQL 로그는 환경에 따라 파일로 남기도 하고(systemd journal에만 남기도) 합니다. 아래 순서대로 보면 대부분 1~2분 안에 “현재 이 서버의 정답 위치”를 찾을 수 있습니다.
- systemd journal(가장 먼저): distro/패키지에 상관없이 단서가 많이 나옵니다.
- /var/log/mysql/: Ubuntu/Debian 계열에서 자주 보입니다(mysql/error.log 등).
- /var/log/mysqld.log: RHEL/CentOS 계열에서 흔합니다.
- /var/log/mysql/error.log 또는 /var/log/mariadb/mariadb.log: MariaDB 포함 변형.
- 컨테이너(Docker): 파일보다 docker logs가 1차입니다.
실제로는 “내 MySQL이 어떤 서비스 이름으로 떠 있는지”부터 확인하면 로그/상태 확인이 쉬워집니다.
- 서비스 이름 후보: mysql, mysqld, mariadb
- 상태 확인: systemctl status mysql (또는 mysqld/mariadb)
2) 에러 로그를 “실제로 어디에 쓰는지” 확정하는 방법
“기본 경로일 것”이라고 가정하면 헛발을 디디는 경우가 많습니다. 로그 파일 경로는 my.cnf에서 바뀌어 있을 수 있고, 아예 journal만 쓰도록 되어 있을 수도 있습니다.
아래 항목을 순서대로 확인해서, 이 서버에서 MySQL이 현재 쓰는 로그 경로를 확정하세요.
- systemd journal 확인: journalctl -u mysql -xe (서비스명이 다르면 바꿔서)
- mysqld 실행 인자: systemctl cat mysql 로 ExecStart 라인을 보고 --defaults-file, --log-error 여부 확인
- 설정 파일 계층: /etc/my.cnf, /etc/mysql/my.cnf, /etc/mysql/conf.d/, /etc/mysql/mysql.conf.d/ 등을 확인(Include 디렉터리 포함)
- 런타임 변수: 가능하면 mysql 접속 후 SHOW VARIABLES LIKE 'log_error'; 로 실제 값 확인
특히 SHOW VARIABLES의 결과가 나오면 그 값이 “현재 MySQL이 믿고 있는 로그 경로”라서 가장 확실합니다(접속이 가능한 상태라면요).
3) 자주 보는 문제 유형별: 로그에서 무엇을 찾나
로그를 찾았으면, 이제 “원인 카테고리”를 분류합니다. 여기서 갈림길이 생기기 때문에, 로그에서 아래 패턴을 먼저 훑는 게 효율적입니다.
- 스토리지/디스크: No space left on device, Read-only file system, Disk quota exceeded
- 권한/경로: Permission denied, Can’t create/write to file, datadir 접근 불가
- 포트/바인딩: Bind on TCP/IP port: Address already in use
- InnoDB/크래시 복구: InnoDB: corruption, redo log, crash recovery, page checksum mismatch
- 커넥션 폭증: Too many connections, aborted connection, thread cache 관련 메시지
- 성능 저하: slow query, lock wait timeout, deadlock, tmp table to disk
이 단계에서는 “해결책을 당장 적용”하기보다, 재현 조건(언제부터, 어떤 배포 작업 이후, 디스크 사용량 변화, 트래픽 변화)과 함께 로그의 시간대를 맞춰보는 게 중요합니다.
4) my.cnf 설정 예시(로그/진단 중심) + 안전한 적용 포인트
아래는 “문제 원인을 좁히기 위한” 로그/진단 설정 예시입니다. 운영 환경에서는 디스크 용량과 개인정보/쿼리 노출 이슈를 고려해야 하니, 필요한 것만 최소로 켜고 문제 해결 후 끄는 것을 권장합니다.
예시: /etc/mysql/mysql.conf.d/mysqld.cnf (경로는 배포판마다 다를 수 있음)
필수(에러 로그 명확화):
- log_error = /var/log/mysql/error.log (파일로 남길 때)
- log_error_verbosity = 3 (가능하면 상세 로그)
성능 문제 추적(필요 시만):
- slow_query_log = 1
- slow_query_log_file = /var/log/mysql/slow.log
- long_query_time = 1 (상황에 따라 0.5~2 사이 조정)
- log_queries_not_using_indexes = 0 (기본은 꺼두고, 꼭 필요할 때만)
잠금/데드락 단서(엔진/버전에 따라 다름):
- InnoDB 관련 로그/상태 출력 옵션은 버전별 차이가 큼(무리하게 많이 켜기보다, 먼저 error log와 slow log로 범위를 좁히는 편이 안전)
주의: 로그 파일을 파일로 남기려면, 해당 디렉터리 권한과 소유자(보통 mysql)가 맞아야 합니다. 권한이 틀리면 “로그를 쓰려다 mysqld가 기동 실패”로 이어지기도 합니다.
5) 설정 변경 전/후 체크리스트(검증 → 재시작 → 확인)
여기부터가 실제 운영에서 사고를 줄이는 핵심 루틴입니다. 설정 변경은 항상 “검증 가능한 형태”로 적용하세요.
- 1) 변경 파일 위치 확정: Include 구조에서 실제로 읽히는 파일인지 확인
- 2) 문법/옵션 유효성 확인: 버전에 없는 옵션을 넣지 않았는지(특히 MySQL vs MariaDB)
- 3) 로그 디렉터리 준비: /var/log/mysql/ 존재 여부, 소유자 mysql, 쓰기 권한 확인
- 4) 재시작 전 현재 상태 저장: 에러 로그 마지막 200줄, 디스크 사용량(df -h), 메모리 상황(free -m) 정도는 캡처
- 5) 재시작은 짧게: systemctl restart mysql 후 즉시 systemctl status mysql, journalctl -u mysql -xe 확인
- 6) 재시작 후 검증: 포트 리슨 여부, 애플리케이션 연결, SHOW VARIABLES로 설정 반영 확인
가능하면 재시작 대신 reload를 고려하고 싶지만, MySQL은 많은 설정이 재기동을 요구합니다. 따라서 “재시작 직후 로그 확인”을 습관처럼 붙여 두는 게 좋습니다.
6) 재시작 실패/반복 크래시일 때 최소한의 복구 흐름
MySQL이 재시작에서 바로 실패하거나, 떠도 곧바로 죽는다면 아래 흐름으로 접근하면 시간을 아낄 수 있습니다.
- 1) 최근 변경사항부터 롤백: 방금 수정한 my.cnf 조각을 원복(또는 별도 파일이면 비활성화) 후 재시작
- 2) 에러 로그에서 “첫 번째 치명 오류” 찾기: 뒤쪽 연쇄 에러보다, 위쪽에 처음 찍힌 Fatal/ERROR가 원인인 경우가 많음
- 3) 디스크/권한/포트 같은 기초부터 확인: 의외로 여기서 끝나는 일이 많음
- 4) InnoDB 관련이면: 즉흥적으로 옵션을 추가하기보다, 로그 메시지(테이블스페이스/redo/ibdata 관련)를 기반으로 대응 범위를 결정
특히 InnoDB 손상 의심 상황은 데이터 보존이 최우선이라, 성급한 조치가 피해를 키울 수 있습니다. 이 경우에는 로그를 확보하고(파일+journal), 디스크 상태와 백업 상태를 함께 점검한 다음 단계적으로 진행하는 편이 안전합니다.
마무리
MySQL 트러블슈팅은 “설정부터 만지기”보다 로그 위치를 확정하고, 로그가 말하는 방향으로만 움직이는 것이 가장 빠르고 안전합니다.
에러 로그/journal로 원인을 좁힌 다음, my.cnf는 최소 변경으로 적용하고, 반드시 검증→재시작→즉시 로그 확인 루틴을 붙여두면 재발 방지에도 도움이 됩니다.