-
[EFCore] SQLite .db 사용시 CloseC#/EFCore 2023. 8. 29. 11:42
Sqlite .db 사용 시 어플리케이션 종료할 때 까지
위 3개의 파일이 생성 되는데 .db 는 비어 있고 실제 파일은 .db-wal파일에 쓰인다.
WAL
-
3.7.0 에는 WAL ( Write Ahead to Log ) 방식이 새로 도입되었다.
이 녀석도 journal 과 마찬가지로 atomic commit 과 rollback 을 지원하기 위함이다.
이 녀석은 <originalDBFileName>-wal 형태를 갖는다.
-
WAL file 은 DB connection 이 처음 이뤄질 때 생성되고, last connection 이 close 될 때 제거된다.
그러나 예외상황이 발생하면 (정상종료하지 않으면) WAL 파일은 남게 되고, 다음에 DB open 시 이 정보를 이용해 DB 를 원상복구 한다.
-
모든 process 의 SQLite DB connection 은 memory share 가 필요한다.
WAL mode 에서는 WAL file 의 index 로 사용하는 share memory 공유가 필요하며 mmap() 으로 구현된 shared-memory file 이 쓰인다.
이 파일은 <originalDBFileName>-shm 의 파일명을 가지며, WAL mode 로 동작할 때에만 존재한다. 그래서 file 의 life time 도 동일하다.
shared-memory file 은 multi process 가 WAL mode 로 DB 를 접근할 때 shared memory block 을 제공하기 위한 목적으로만 쓰인다.
VFS 가 shared memory 에 접근하는 대체방법을 제공하면 이 파일 대신 그 방법이 쓰일 수 있다.
예를 들어 PRAGMA locking_mode=EXCLUSIVE 라면 (한 process 만 DB 에 접근할 수 있다) shared memory 는 heap 에 할당되고 shm 파일은 생성되지 않는다.
-
WAL 은 쓰기 요청이 들어오면 먼저 변경 사항을 WAL-Log 파일에 기록한다.
로그에 기록하는 것은 파일에 직접 기록하는 것보다 훨씬 빠르고 가벼운 요청이다.
그리고 WAL-Log 파일이 1000Page(Default)가 넘으면 일괄 commit 한다.
( 리눅스는 1Page = 4K 정도 되므로 대략 4MB 에 일괄 commit 한다. )
읽기 요청은 현재의 로그 파일과 DB 파일을 참조하여 처리한다.
기존의 DB 에서 direct 로 읽는 방식보다 성능이 약간 떨어질 수 있지만, 일반적으로 성능 차이가 거의 없다고 봐도 무관하다고 한다.
Write 와 Read 를 섞어 성능 테스트해보면 WAL 이 journal mode 보다 퍼포먼스가 좋게 나온다 한다.
https://aroundck.tistory.com/5948
[Database] -journal 파일의 정체는 뭘까? ( + WAL, temp files )
[Database] -journal 파일의 정체는 뭘까? ( + WAL, temp files ) http://gywn.net/2013/08/let-me-intorduce-sqlite/http://www.sqlite.org/tempfiles.html Journal --journal 은 rollback journal 이다.이는 SQLite 에서 atomic commit & rollback 을 지
aroundck.tistory.com
위 .db 파일 생성 후 어플리케이션 종료 전에 .db 파일을 (이동, 복사 및 etc ) 처리해야 하는 경우
SqliteConnection.ClearPool(conn); 을 해주면 커밋 하고 .db 클로즈 함.
이 후에 .db 에 추가 및 수정을 하고자 할 때
using var tagContext = new TagContext(TagDbName); using var bt = tagContext.Database.BeginTransaction(); ... tagContext.Tags.Add(tagInfo); bt.CommitAsync(); tagContext.SaveChangesAsync(); if (tagContext.Database.GetDbConnection() is SqliteConnection conn) { SqliteConnection.ClearPool(conn); }
Commit을 해줘야 제대로 들어감.
Async아니어도 동작.
https://github.com/dotnet/efcore/issues/26845
Db.db-shm and db.db-wal cannot be cleaned up automatically · Issue #26845 · dotnet/efcore
class public class Table1 { public long Id { get; set; } public string? Value { get; set; } } public class DbContext : Microsoft.EntityFrameworkCore.DbContext { public DbSet<Table1>? Tables { get; ...
github.com
https://github.com/dotnet/efcore/issues/26422
RC2 Sqlite provider no longer clears temporary files on exit · Issue #26422 · dotnet/efcore
Since RC2 update scoped sqlite dbcontext no longer deletes *-shm and *-wal files on app exit. Maybe I am missing some clean up behavior settings but it worked without apparent tweaks in previous ve...
github.com
728x90'C# > EFCore' 카테고리의 다른 글
[EFCore] reset sqlite_sequence (0) 2023.10.12 [EFCore] Key 값 넣을 때 (1) 2023.10.06 [EFCore] Grpc Data Parsing (0) 2023.09.21 [EFCore] 시작하기 (0) 2022.11.09 댓글