여느때와 같이 bug ticket 이 들어왔나 보고 있던 중에, 내 모듈이 SQLite DB 에 저장한 데이터를 읽을 수 없었다는 이슈가 있었다.
log 상으로는 어떠한 문제점도 보이지 않아서 설치된 DB 를 받아서 분석을 해 보았더니, 읽을 수 없었던 PK 를 SELECT 하려고 시도하니 database is malformed 라는 문구가 뜬 적이 있었다.
해당 로그에 대한 자료를 찾아보니 pragma integrity_check 라는 PRAGMA 를 이용해서 DB 가 손상되었는지 확인 할 수 있었지만, 손상되었다는 정보만 얻고 별 소득이 없었다. 결국에 해결해야 되는 것은 내가 구현한 모듈에서 DB 를 손상시킬 수 있는 동작을 하고 있었다는 점이기 때문이다.
우선 모듈은 DB 에 Read/Write 를 수행하고 있었고, 해당 DB 에는 다른 모듈들이 NFS 를 통해서 접근을 하고 있던 상황이었다. SELECT 와 INSERT OR REPLACE Query 만 날리는 단순한 상황이었는데 데이터베이스가 손상되었다고 하니 원인을 도무지 알 수 없었고, 재현테스트를 위해 같은 환경에서 Insert 와 select 를 매우 많이 수행하는 hard test 를 해 보았다.
테스트용 프로그램을 실행하여 재현을 해 본 결과, 마찬가지로 DB 가 손상되는 문제가 있었고 SQLite association 에 도움을 요청했다. 메일로 현재 재현되는 상황을 최대한 자세히 설명 했더니 NFS 로 연결되어있는 DB 를 Read/Write 하면서 DB lock 이 정상적으로 동작을 하지 않기 떄문이라고 하였다.
실제로 동작 과정을 자세히 보니 Write 를 하면서 journal file 이 생성된 상태에서 NFS 를 통해 연결된 다른 컴퓨터에서 Read 를 해버리면, journal file 이 사라지면서 DB 손상이 발생하는 것을 확인할 수 있었다. 아무래도 lock 이 정상동작하지 않아 NFS 로 연결된 다른 컴퓨터에서 journal filed 을 보고 rollback 을 하면서 문제가 생긴게 아닌가 싶었다.
문제는 NFS 환경으로 연결된 SQLite3 DB 를 사용하지 않는 방향으로 수정을 했었다.
사실 완전 처음 보는 증상이라 원인을 찾는데 시간이 좀 걸렸는데, 경험했던 내용들을 정리하다 보니 아래와 같은 페이지가 존재했다.
https://www.sqlite.org/howtocorrupt.html
찾아보니 NFS 에 대한 언급도 있었는데, 그때 이 문서를 봤었다면 예상보다 빨리 문제를 해결할 수 있었지 않았을까.. 싶다.
혹시 모르니 앞으로 SQLite3 를 이용한 개발을 한다면 해당 문서는 한번쯤 보는게 좋을 것 같다.
'개발자의 길 > Database' 카테고리의 다른 글
[MySQL] MySQL 의 Isolation level ( 격리 레벨 ) (1) | 2023.12.31 |
---|---|
[MYSQL] OUTER JOIN 과 INNER JOIN (1) | 2023.12.03 |
[SQLite3][C++] SQLite3 에서 record 를 지워도 DB 용량이 줄어들지 않는 이유는? - page, vacuum, rbu vacuum. (0) | 2021.07.30 |
[SQLite3][C++] Sqlite3 의 journal file 에 대해 (0) | 2021.07.28 |
[SQLite3][C++] SQLite 의 file lock 매커니즘 (0) | 2021.07.18 |