Sqlite3 데이터 밀어넣다가 생긴 일

수정일: 2025. 6. 3.

insert into는 모두 멈춘 후에 하는걸 추천드립니다.

insert into를 그냥 해서 생긴 일

필자는 sqlite3와 같은 가벼운 기술들을 선호합니다.

작은 프로젝트를 진행하던 중 평소 다루던 sqlite3에 테이블을 생성하고, 데이터를 밀어넣을 일이 생겼습니다.

데이터는 그리 많지 않아 별 생각없이 운영중이던 sqlite3에 그대로 쿼리를 진행시켰고, 보기 좋게 터졌습니다. (이게 원인입니다.)

어떤 일이 벌어지는 것인가

저같은 경우 sqlite3 내부에서 db를 이루는 B-Tree의 참조 구조가 깨졌습니다. B-Tree가 참조를 이상하게 하다보니 데이터가 섞여 보이게 됩니다.

예를 들어…

메뉴판이라고 한다면

항목 가격/설명
백반 1 만원
계란후라이 삼겹살

이런 느낌입니다.

문제의 진단

sqlite3에서 문제를 진단하는 방법은 아래의 script를 실행해주면 됩니다.

sqlite3 your.db
PRAGMA integrity_check;
// ok | 심각한 이슈

이 때 심각한 이슈인 경우 아주 긴 로그를 확인할 수 있습니다.

에러 로그

Tree 7 page 51 cell 0: invalid page number 83886080
Tree 7 page 61 cell 3: Rowid 23 out of order
Tree 7 page 41 cell 0: 2nd reference to page 63
Tree 7 page 49 cell 3: invalid page number 218103808
Tree 26 page 27 cell 3: overflow list length is 1 but should be 2
Tree 26 page 27 cell 2: 2nd reference to page 43
Tree 26 page 27 cell 0: 2nd reference to page 46
2nd reference to page 42
Page 9: never used
Page 48: never used
Page 58: never used
Page 59: never used
Page 73: never used
Page 77: never used
Page 78: never used
Page 79: never used

에러 로그 분석

Tree 7 page 51 cell 0: invalid page number 83886080

이 내용은

B-Tree의 일곱 번째 트리, 해당 트리의 51번째 페이지, 0번째 셀 이 셀이 참조한 페이지 번호가 invalid page이다 83886080이 페이지 번호를 참조하려 했다.

참고로 매우 작은 사이즈의 DB에서 어색한 숫자가 튀어나와 저도 당황했습니다.

문제의 해결…

전 이렇게 DB를 날려버린 적이 몇번 있어 백업을 만들어 둔 것이 있습니다. 물론 모든 데이터가 온전히 백업되어 있지는 않지만 적당히 백업되어 있었습니다.

sqlite3는 경량으로 매우 빠르고 비용 친화적이긴 합니다만, 이런 복구에 관해서는 대부분 백업에 의존합니다.

그래서 백업을 추천드립니다.

sqlite3 your.db ".backup 'backup.db'"

요약

  1. 백업을 잘하자
  2. sqlite3 your.db ".backup 'backup.db'"
  3. cron tab에 등록해서 알아서 돌게 해두시는걸 추천드립니다.