본문 바로가기
C.W.K.
Stream
Lesson 04 of 10 · published

파일이 곧 DB야

~14 min · sqlite, file-format, wal, backup

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

파일 하나로 끝나고, 포맷은 2004년부터 그대로야

SQLite DB는 잘 정의돼 있고 오래 안 변하고 플랫폼을 안 가리는 binary 포맷의 파일 하나야. 이 포맷은 3.0.0이 나온 2004년 이후로 그대로고, SQLite 팀은 최소 2050년까지 호환을 지키겠다고 약속했어. macOS에서 만든 파일이 Windows에서도 Linux에서도 Raspberry Pi에서도 Android 폰에서도 byte 하나 안 틀리고 열려.

확장자는 보통 .db.sqlite, .sqlite3를 쓰는데 사실 아무거나 붙여도 돼. SQLite는 파일 이름을 안 봐. 파일 헤더를 읽고 자기 자신을 알아봐.

WAL(Write-Ahead Logging) 모드를 켜면 — 동시에 여러 곳에서 건드리는 워크로드면 거의 항상 켜야 해 — DB 옆에 파일이 두 개 더 생겨.

  • myapp.db-wal — Write-Ahead Log야. 아직 main 파일로 checkpoint되지 않은 최근 변경이 여기 쌓여.
  • myapp.db-shm — 동시에 읽는 reader들을 맞춰주는 shared memory 파일이야.

이 둘은 SQLite가 알아서 관리해. 마지막 connection이 깔끔하게 닫히면 대개 사라지고. WAL 모드 DB를 백업할 때는 세 파일을 같이 복사하거나, 앞뒤 맞는 snapshot을 만들어주는 공식 .backup 명령을 써.

Warning: WAL 모드 DB를 writer가 도는 중에 그냥 cp로 뜨면 깨진 사본이 나올 수 있어. sqlite3 source.db ".backup target.db"나 C-level sqlite3_backup API를 써. cron에 cp 걸어두는 건 '내 백업이 2년 동안 조용히 망가져 있었다' 류 사고의 단골 원인이야.

Code

디스크 위에 뭐가 있나·bash
ls -la myapp.db*
# -rw-r--r--  myapp.db       28672 bytes  (DB)
# -rw-r--r--  myapp.db-wal   45280 bytes  (최근 변경, WAL 모드)
# -rw-r--r--  myapp.db-shm   32768 bytes  (WAL 용 shared-memory index)

# 파일 헤더 확인 — magic string 이 'SQLite format 3\0' 야
head -c 16 myapp.db | xxd
# 00000000: 5351 4c69 7465 2066 6f72 6d61 7420 3300
#           S Q L i t e   f o r m a t   3 .
.backup으로 안전 백업·bash
# Online backup — writer 활성 상태에서도 됨
sqlite3 myapp.db ".backup nightly-$(date -I).db"

# Python 에서 동일 — C-level sqlite3_backup API 사용
python3 -c "
import sqlite3, datetime
src = sqlite3.connect('myapp.db')
dst = sqlite3.connect(f'nightly-{datetime.date.today()}.db')
src.backup(dst)
src.close(); dst.close()
"

External links

Exercise

작은 SQLite DB를 만들고 row를 몇 개 넣은 다음 WAL 모드로 바꿔봐(PRAGMA journal_mode=WAL;). Python 루프로 계속 row를 밀어넣으면서 백업을 세 가지로 떠봐. 그냥 cp, sqlite3 .backup, 그리고 Python의 sqlite3_backup. 세 백업을 각각 열어서 row 수와 integrity가 맞는지 확인하고, 어느 쪽이 앞뒤 맞는 snapshot을 만들었고 어느 쪽이 실패했는지 적어둬.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.