두 개의 파이썬 프로세스가있는 SQLite : 하나의 읽기, 하나의 쓰기


22

두 가지 구성 요소가있는 작은 시스템을 개발 중입니다. 하나는 인터넷 리소스에서 데이터를 폴링하고 로컬로 유지하기 위해 SQL 데이터로 변환합니다. 두 번째는 로컬 인스턴스에서 해당 SQL 데이터를 읽고 json과 편안한 API를 통해 제공합니다.

원래 postgresql을 사용하여 데이터를 유지하려고 계획했지만 응용 프로그램에 저장할 데이터 및 트래픽 양이 매우 적기 때문에 과잉이라고 생각했습니다. SQLite가 업무에 달려 있습니까? 나는 작은 발자국에 대한 아이디어를 좋아 하고이 하나의 작업을 위해 또 다른 SQL 서버를 유지할 필요는 없지만 동시성에 대해 걱정하고 있습니다.

미리 쓰기 로깅을 사용하면 데이터베이스에서 프로세스를 잠그지 않고도 SQLite 데이터베이스를 동시에 읽고 쓸 수 있습니다.

하나의 SQLite 인스턴스가 하나만 읽고 다른 하나만 쓰는 경우 두 개의 동시 프로세스에 액세스 할 수 있습니까? 코드 작성을 시작했지만 이것이 SQLite의 오용인지 궁금합니다.


3
@gnat 쿨. 하나의 SQLite 인스턴스가 하나만 읽고 다른 하나만 쓰는 경우 두 개의 동시 프로세스에 액세스 할 수 있습니까? 코드 작성을 시작했지만 이것이 SQLite의 오용인지 궁금합니다.
bb

그냥 머리 위로. 이전 회사에서는 일부 스토리지에 SQL (MS 및 Oracle Express 모두)을 사용하고 있었으며 항상 적은 양의 스토리지로 전체 DB가 필요하지 않다고 느꼈습니다. 그래서 릴리스 중 하나에서 우리는 당신이하고있는 것을 정확하게하기로 결정했습니다. 해당 제품을 SQLite로 교체하십시오. 디스크에 데이터를 저장하고 검색 할 데이터를 결정하기 위해 TOC를 읽는 SQL 기반 TOC 및 판독기 프로세스 (다중 스레드)를 업데이트하는 하나의 기록기가 정확히 똑 같았습니다. 요즘 SQLite에 대해 몰라, 그러나 우리가 겪은 작은 동시성으로 인해 큰 고통으로 판명되었습니다.
DXM

... 뒤. 모든 세부 사항을 기억하지는 못하지만 한 프로세스가 잠금을 얻으려고 시도했지만 다른 프로세스가 읽기 때문에 읽을 수 없었을 때 20-30 초와 같은 미쳐 버릴 것이라고 생각합니다. 결국 SQLite 액세스를 담당하는 전용 스레드를 만든 다음 프로세스와 모든 스레드를 모두 보유하고 DB 요청을 해당 스레드로 직렬화합니다. 가늠자로, 아마도 SQLite를 다시 사용하지 않았을 것입니다.
DXM

1
@DXM은 경고에 감사하지만 몇 가지 테스트를 실행 한 후에 비슷한 것에 대해 실행하지 않았습니다. sqlite는 2004 년경 3 버전으로 크게 개선되었습니다. 따라서 부정적인 경험이 그 이전으로 거슬러 올라가는 지 궁금합니다.
bb

1
... SQLite의 잠금 체계에 의존하기보다는 자신. 나는 스스로 일을하지 않았고 다른 팀이었다. 그러나 나는 피드백을 제공하고 호기심에서 벗어나기 위해 루프를 유지했다. 나는 또한 온라인으로 가서 독자적인 독서를하고 원저자 페이지를 발견했다. 그것을 읽음으로써, 나는 SQLite의 발명가가 단순히 스레드를 싫어하고 누군가가 왜 그것을 사용할지 알지 못했다는 인상을 얻었습니다. 너무 많은 사람들이 그것을 요구했기 때문에 나중에 생각으로 해킹.
DXM

답변:


25

File Locking And Concurrency 설명서를 찾고 있습니다.

SQLite 프로세스는 일련의 잠금을 사용하여 동시성을 처리합니다. 읽기 위해 여러 프로세스가 SHARED잠금을 얻을 수 있습니다 .

쓰는 프로세스는 RESERVED잠금 을 얻어야하며 실제로 디스크의 변경 사항을 플러시 해야 할 때만 PENDING상태 로 이동합니다 . 그런 다음 모든 읽기 프로세스에서 파일 잠금을 해제해야하며, 그 후 쓰기 프로세스는 EXCLUSIVE실제 데이터베이스 파일에 쓰기 위해 이동할 수 있습니다.

라이터 프로세스는 실제 쓰기 (메모리 플러시, 커밋)를 위해 데이터베이스 파일을 잠그기 만하면되기 때문에 리더가 한 명이고 라이터가 한 명인 설정이 아주 잘 수행됩니다. 한 번의 프로세스로 모든 읽기 및 쓰기를 수행하는 설정으로 더 나쁘지 않더라도 성능이 좋을 것으로 기대합니다.

쓰기는 PENDING변경 사항을 직렬화하기 위해 독점 잠금을 확보해야하기 때문에 여러 데이터베이스가 동일한 데이터베이스에 자주 쓰는 경우 SQLite는 적합하지 않습니다 .


철저한 답변 Martijn에 감사드립니다! 몇 가지 테스트를 수행하는 스크립트가 있으며 두 프로세스가 하나의 sqlite 인스턴스를 동시에 읽고 쓸 것 같습니다. 1/100 초마다 발생하는 동시 읽기 및 쓰기 요청을 수행했지만 여전히 잠긴 DB 예외가 발생하지 않았습니다. 이상하게도, "데이터베이스가 잠겼습니다"오류 메시지가 나타나는 유일한 시간은 읽기 요청이 스크립트에서 1/100 초에 발생하는 동안 수동으로 (sqlite3 명령 행 클라이언트로) 몇 개의 행을 삭제하려고 시도했을 때였습니다. 그런 오류 후에 pysql이 자동으로 쓰기를 재 시도하는지 궁금합니다.
bb

10

후속 조치를 취하고 모든 사람에게 구현이 성공했음을 알리고 싶었습니다. SQLite로 작업하는 것은 정말 즐거웠으며 한 번에 하나의 프로세스 만 작성하면 보조 프로세스에서 매우 빠른 동시 읽기를 수행하더라도 잠금 문제가 발생하지 않았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.