파이썬 python/django

[django] database is locked - 원인파악 | 해결방안

Aytekin 2024. 11. 6. 11:02

1. 원인 파악

Django에서 "database is locked" 오류는 SQLite3 데이터베이스에 현재 다른 프로세스가 잠금을 걸고 있는 상태에서 데이터베이스 작업을 시도할 때 발생합니다. 이 문제는 여러 가지 이유로 발생할 수 있습니다:

  • 동시 접근: SQLite3 데이터베이스는 낮은 트래픽에서 중간 트래픽까지를 처리하도록 설계되었습니다. 높은 수준의 동시 쓰기는 데이터베이스가 잠기는 결과를 초래할 수 있습니다.
  • 장시간 실행되는 트랜잭션: 트랜잭션이 완료되는 데 오랜 시간이 걸리면, 데이터베이스에 잠금을 걸어 다른 트랜잭션이 진행되지 않게 할 수 있습니다.
  • 파일 잠금 문제: SQLite는 동시성을 관리하기 위해 파일 잠금을 사용합니다. 파일 시스템 잠금 메커니즘에 문제가 있으면 데이터베이스가 잠길 수 있습니다.
  • 연결 풀링: SQLite를 사용할 때 연결 풀링을 사용하면 여러 연결이 동시에 데이터베이스에 쓰기 작업을 시도할 수 있습니다.

2. 오류 해결 방안

  • 적절한 데이터베이스 트랜잭션 사용 : 트랜잭션을 가능한 짧게 유지하세요. 트랜잭션을 빠르게 커밋하거나 롤백하여 데이터베이스 잠금을 해제합니다.
from django.db import transaction

with transaction.atomic():
    # 데이터베이스 작업 수행
 
  • 타임아웃 증가 : SQLite3는 잠금을 얻으려고 시도할 때 대기할 시간을 설정할 수 있습니다. 이 설정은 Django 설정에서 구성할 수 있습니다.
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'mydatabase',
        'OPTIONS': {
            'timeout': 20,  # 타임아웃을 20초로 설정, default=5초
        }
    }
}
 
  • 장시간 실행되는 쿼리 피하기 : 쿼리를 최적화하여 빠르게 실행되도록 합니다. 인덱싱과 쿼리 최적화 기술을 사용하여 성능을 향상시킵니다.
  • 다른 데이터베이스 백엔드 사용 : 애플리케이션이 높은 트래픽을 경험하거나 강력한 동시성 지원이 필요한 경우, PostgreSQL 또는 MySQL과 같은 더 나은 동시성 지원을 제공하는 다른 데이터베이스 백엔드를 사용하는 것을 고려하세요.
  • 파일 기반 잠금 사용 : 운영 체제와 파일 시스템이 SQLite에서 요구하는 파일 기반 잠금 메커니즘을 지원하는지 확인하세요.
  • 연결 풀링 관리 : SQLite와 연결 풀링 메커니즘을 사용할 때는, 하나의 쓰기 작업만 수행될 수 있도록 설정하거나 연결 풀링을 피하세요.

결론

원인

  • Sqlite3가 동시작업(concurrency)이 불가하여 앞선 작업이 진행중일 땐, 데이터베이스를 잠궈(lock)놓습니다.
  • 이 때문에 sqlite3에는 time-lock이라는 설정값이 있다.
  • 설정된 time-lock 시간을 넘어갈동안 앞선 작업이 끝나지 않을 경우 "database is locked"의 오류를 던지게 됩니다.

 

해결방안

  • timeout 설정값 변경(default=5초)
  • 장시간 쿼리 최적화
  • (최후의 방법)대체 데이터베이스 백엔드로 교체(ex. MySQL, PostgreSQL, Oracle, MongoDB...)

DB를 교체하는건 큰 작업이므로 처음 프로젝트를 설계할 시 DB 선정에도 신중에 신중을 가해야 합니다.


[참고]

 

Databases | Django documentation

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

728x90