Django 프로젝트를 하던 중
django.db.utils.OperationalError: (2006, "MySQL server has gone away")
서버 로그에서 위와 같은 오류가 발생했다.
검색을 해보니
- 트래픽이 몰렸을 때
- 서버가 일정 시간 이상 대기 상태였다가 재접속할 때
- Celery worker가 DB에 오래 연결되어 있었을 때
먼저 OperationalError란?
Django에서 DB와 통신 중 운영 레벨(DB 커넥션, 네트워크, 설정 등)의 문제가 발생하면
OperationalError가 발생한다.
유형 | 설명 |
DB 커넥션 타임아웃 | 일정 시간 사용하지 않으면 DB가 커넥션을 끊어버림 |
DB 커넥션 풀 한도 초과 | 동시에 너무 많은 요청으로 커넥션 부족 |
MySQL 서버 설정 문제 | wait_timeout, max_connections 설정값이 낮음 |
재시도 없이 예외 터짐 | 커넥션 오류를 catch하지 않아서 처리 실패 |
문제 해결 방법
해당 문제를 해결하기 위해서는 첫번째는 DB 설정 최적화 방법이 있습니다.
SHOW VARIABLES LIKE '%timeout%';
SET GLOBAL wait_timeout = 28800;
SET GLOBAL interactive_timeout = 28800;
SET GLOBAL max_connections = 500;
너무 짧은 timeout 또는 낮은 max_connections 값을 피해서 설정하는게 좋습니다.
두번째 방법은 Django DB 커넥션 수명 설정입니다.
CONN_MAX_AGE = 60
# 초 단위: 커넥션 재사용 최대 시간 (0이면 매 요청마다 재연결)
Django의 setting.py에서 CONN_MAX_AGE를 설정해주는 겁니다.
- CONN_MAX_AGE = None : 무제한 사용 -> 위험
- CONN_MAX_AGE = 0 : 요청마다 새 커넥션 생성 -> 느림
- CONN_MAX_AGE = (60 ~ 600) : 60~600 정도가 안정적
그리고 세번째 방법은 커넥션 상태 체크 후 재시도를 처리하는 방법입니다.
from django.db import connection, OperationalError
try:
connection.ensure_connection() # 커넥션 살아있는지 확인
# DB 작업
except OperationalError:
logger.warning("DB 커넥션 끊김.") # 재시도 혹은 fallback 처리 필요.
# fallback 작업 수행
위 방법대로 진행하게 되면 view, celery task 등에서 미리 체크해서 대응이 가능합니다.
네번째 방법은 DB 커넥션 풀 적용입니다.
만일 사용하는 DB가
- PostgreSQL 이라면 pgbouncer
- MySQL 이라면 [ProxySQL, pool_recycle 설정 등]
Django는 커넥션 풀을 직접 제공하지 않기 떄문에, DB 앞단에 커넥션 풀 서버 구성이 필요합니다.
마지막은 Celery로 비동기 처리 시 커넥션 누수 방지방법입니다.
Celery task 내부에서 DB 작업 후, 명시적으로 커넥션 닫아줘야 합니다.
from django.db import connection
@shared_task
def do_something():
...
connection.close() # DB 커넥션 명시적 종료
close를 안하면 Celery 워커가 죽거나 오래 켜져 있다가 오류가 발생하게 됩니다.
왜 이렇게 방지를 해야하나면
- OperationalError는 예방이 가장 중요하다.
- 한번 터지면 복구보다 확산 차단이 더 중요하다.
- 커넥션 풀, timeout 조정, Celery 관리가 핵심이다.
- 실시간 서비스일수록 커넥션 문제 대응 설계가 반드시 필요하다.
그렇기에 커넥션 풀을 도입하면 다중 접속에도 안정성을 확보할 수 있고, Celery와 같은 장기 실행 작업은 반드시
connection.close()를 해야하고, 로그 수집 및 모니터링 도구로 커넥션 오류를 추적해야합니다.
OperationalError는 종종 장애의 시작점이 됩니다.
빠른 감지와 대응이 중요하다는 말이 됩니다.
정리
Django에서 발생하는 OperationalError는 대부분 DB 커넥션 문제로 인해 발생합니다.
설정 최적화, 재연결 처리, 커넥션 풀 도입 등으로 사전에 방지하고, 장애 전파를 막는 대응 전략이 중요합니다.
'python > Django' 카테고리의 다른 글
DoesNotExist vs MultipleObjectsReturned - ORM 예외처리 (0) | 2025.05.08 |
---|---|
transaction.atomic() 트랙잭션 처리하기 (0) | 2025.04.30 |
ValidationError – API/Form 검증 (0) | 2025.04.28 |
IntegrityError – 대량 저장 중 충돌 해결 (0) | 2025.04.28 |
DRF(Django REST Framework) 란? (0) | 2023.08.23 |