Database 매뉴얼 · Chapter 9

백업 · WAL · 운영 체크포인트

샘플 프로젝트의 DatabaseOption 블록에는 운영에 필요한 옵션들이 함께 들어 있습니다. 스크립트로는 다루지 않지만, 실제 양산 환경에서 가장 큰 문제를 피하게 해주는 설정들이라 별도 챕터로 정리합니다.

DB_Sqlite.xmp 의 운영 옵션

"DatabaseOption": {
  "Connections": [ /* ... */ ],
  "BackupFolder": "XDatabase/Backup",
  "AutoBackupEnabled": false,
  "AutoBackupIntervalHours": 24,
  "BackupKeepLast": 30,
  "JournalMode": "WAL"
}

옵션별로 의미와 권장값을 정리합니다.


1) JournalMode — WAL 권장

SQLite 의 저널 모드는 트랜잭션 데이터를 어떻게 기록하느냐의 차이입니다.

특성추천
DELETE (기본)매 트랜잭션마다 저널 파일 생성/삭제. 단일 사용자 OK작은 도구
WALWrite-Ahead Logging — 쓰기 중에도 다른 프로세스가 읽기 가능양산 권장
MEMORY저널을 메모리에만 — 전원 손실 시 손상 위험임시 캐시
OFF저널 없음 — 위험절대 금지

샘플은 "WAL" 로 설정되어 있습니다. WAL 모드의 효과:

  • 장비 시퀀스는 계속 INSERT 하면서, DB Studio 또는 외부 분석 도구가 동시에 SELECT 가능
  • 트랜잭션 커밋이 빨라져 짧은 트랜잭션이 많은 패턴(샘플처럼) 에서 응답성이 좋아짐
  • 비정상 종료 시 자동 복구

변경은 connections.json / .xmpJournalMode 키만 바꾸면 됩니다. 그 결과는 XDatabase/ 폴더에 LocalDB.db-wal, LocalDB.db-shm 두 보조 파일이 생기는 것으로 확인됩니다.

백업 시 주의 — WAL / SHM 도 함께 복사하거나, 사전에 체크포인트(PRAGMA wal_checkpoint(TRUNCATE)) 로 WAL 의 변경을 본 파일에 흘려넣은 뒤 본 .db 만 복사하세요.


2) BackupFolder + 수동 백업

SQLite 파일은 단일 파일이라 운영 중에도 복사 가 가능합니다 (특히 WAL 체크포인트 후).

샘플은 "XDatabase/Backup" 폴더를 백업 경로로 지정해 두었습니다. 실제로 그 폴더에 백업 파일이 만들어지는 시점은 자동 백업이 켜져 있을 때 또는 도구에서 수동으로 백업을 실행할 때입니다.

옵션권장값의미
BackupFolder"XDatabase/Backup"백업 파일 디렉토리 (프로젝트 상대경로)
AutoBackupEnabled양산: true주기적 자동 백업
AutoBackupIntervalHours24백업 간격(시간)
BackupKeepLast30보관할 백업 수. 초과분 자동 삭제

자동 백업 파일명은 보통 {db이름}_{YYYYMMDD_HHMMSS}.db 형태로 저장됩니다 — 폴더 안의 이름순 정렬이 곧 시간순 정렬이 되도록.

외부 스크립트로 백업하는 패턴

운영체제 차원에서 별도 백업 스케줄을 두는 경우의 권장 흐름입니다.

1. PRAGMA wal_checkpoint(TRUNCATE);   // SQL 탭에서 실행
2. LocalDB.db   →  외부 디스크/네트워크로 복사
3. (필요 시)  파일 무결성 확인

3) ConnectionTimeout / CommandTimeout / Reconnect

Connections 배열의 시간 옵션 4 개:

옵션권장의미
ConnectionTimeout15 secOpen() 이 응답 없을 때 포기하기까지의 시간
CommandTimeout30 sec단일 SQL 실행 타임아웃
PingIntervalSec10 sec연결 살아있는지 주기적 확인 (네트워크 DB 에서 의미)
ReconnectRetries3끊어졌을 때 자동 재시도 횟수

SQLite 단일 파일에서는 대부분 의미가 작지만, MSSQL 로 옮길 때 그대로 살아있는 옵션들이라 샘플에 미리 설정값이 들어 있습니다.


4) 운영 코드의 6 가지 체크포인트

샘플의 모든 DB 함수에 공통으로 들어 있는 방어 코드 6 가지를 정리합니다.

A. IsOpen 가드

if( DB["local"].IsOpen == false )
{
   ShowMessage(EB_Ok, "DB is not open. Press [Open] first.");
   return false;
}

B. 선택 행 가드

if( SelectIndex < 0 || SelectIndex >= DB["local"].RowCount )
{
   ShowMessage(EB_Ok, "Select a row first.");
   return false;
}

C. LastError 로깅

if( DB["local"].RunSqlQueryParam(sql, p) == false )
{
   LogError($"DB_xxx failed : {DB["local"].LastError}");
   ShowMessage(EB_Ok, $"DB xxx failed : {DB["local"].LastError}");
   return false;
}

D. 트랜잭션 실패 시 Rollback

if( DB["local"].RunSqlQueryParam(sql, p) == false )
{
   DB["local"].Rollback();
   // ...
}

E. Open 실패 시 상태 라벨 동기화

if( DB["local"].Open() == false )
{
   DbStatusText = "● CLOSED";
   return false;
}
DbStatusText = "● OPEN";

F. 변경 후 Refresh

return DB_Refresh();

INSERT / UPDATE / DELETE 가 끝나면 항상 Refresh 로 화면을 다시 채워, DB 상태와 화면 상태가 어긋나지 않도록 합니다.


5) 양산 전 체크리스트

항목확인
JournalMode"WAL"
AutoBackupEnabledtrue (운영)
BackupFolder별도 디스크 권장
BackupKeepLast디스크 용량 고려 (보통 14 ~ 60)
LastError 로깅모든 실패 분기에 들어가 있는지
IsOpen 가드모든 DB 함수 첫 줄
변경 함수 끝의 DB_Refresh누락 시 화면이 stale 됨
외부 백업 스케줄OS 차원에서 weekly 풀백업 권장

여기까지가 샘플 DB_Sqlite 가 보여주는 양산 가능 수준의 데이터베이스 통합 의 전부입니다. 실제 양산 프로젝트에 적용할 때는 이 9 개 챕터의 패턴을 그대로 가져오고, 도메인 테이블만 바꿔 주면 됩니다.