SQLite con due processi Python accedendo ad esso: una lettura, una scrittura


22

Sto sviluppando un piccolo sistema con due componenti: uno esegue il polling dei dati da una risorsa Internet e li traduce in dati sql per mantenerli localmente; il secondo legge i dati sql dall'istanza locale e li fornisce tramite json e un API riposante.

Inizialmente avevo intenzione di conservare i dati con postgresql, ma poiché l'applicazione avrà un volume molto basso di dati da archiviare e traffico da servire, ho pensato che fosse eccessivo. SQLite è all'altezza del lavoro? Adoro l'idea del footprint ridotto e non ho bisogno di mantenere ancora un altro server sql per questo compito, ma sono preoccupato per la concorrenza.

Sembra che con la registrazione in anticipo abilitata, la lettura e la scrittura simultanee di un database SQLite possano avvenire senza bloccare nessuno dei processi fuori dal database.

Una singola istanza di SQLite può supportare due processi simultanei accedendo ad essa, se solo una legge e l'altra scrive? Ho iniziato a scrivere il codice ma mi chiedevo se si tratta di un'applicazione errata di SQLite.


3
@gnat Cool. Una singola istanza di SQLite può supportare due processi simultanei accedendo ad essa, se solo una legge e l'altra scrive? Ho iniziato a scrivere il codice ma mi chiedevo se si tratta di un'applicazione errata di SQLite.
bb

Solo un avviso. Nella mia azienda precedente, usavamo SQL (sia MS che Oracle Express) per un po 'di spazio di archiviazione e abbiamo sempre pensato che con quel poco che abbiamo archiviato, non avessimo bisogno di un DB completo. Quindi in una delle versioni abbiamo deciso di fare esattamente quello che stai facendo. Sostituisci quei prodotti con SQLite. Avevamo esattamente la stessa cosa, uno scrittore che avrebbe depositato i dati su disco e aggiornato il processo TOC basato su SQL e il processo di lettura (thread multipli) che avrebbe letto il TOC per determinare quali dati recuperare. Non conosco SQLite in questi giorni, ma quale poca concorrenza ci siamo imbattuti si è rivelato un grande dolore in ...
DXM

... il dietro. Non ricordo tutti i dettagli, ma penso che quando un processo ha cercato di ottenere un blocco e non è riuscito perché un altro stava leggendo, DORMIRE per qualcosa di folle come 20-30 secondi. Abbiamo finito per creare un thread dedicato che era responsabile dell'accesso a SQLite e quindi avevamo entrambi i nostri processi e tutti i thread in essi, serializzare le loro richieste di DB su quel thread. Col senno di poi, probabilmente non sarei andato di nuovo con SQLite.
DXM,

1
@DXM grazie per l'avvertimento, ma dopo aver eseguito alcuni test non ho riscontrato nulla di simile. So che sqlite ha subito una profonda revisione con la versione 3, che era intorno al 2004, quindi mi chiedo se la tua esperienza negativa risale a quel tempo.
bb

1
... te stesso, piuttosto che fare affidamento sugli schemi di blocco di SQLite. Non ho fatto il lavoro da solo, era un altro team, ma mi sono tenuto in contatto principalmente per fornire feedback e per curiosità. Sono anche andato online e ho fatto delle letture indipendenti e ho trovato la pagina dell'autore originale. Dalla lettura di questo, ho avuto l'impressione che l'inventore di SQLite semplicemente odiasse i thread e non vedesse perché qualcuno li avrebbe usati, quindi a) il DB non è stato progettato pensando a loro eb) i blocchi / la protezione sono stati aggiunti / inserito come ripensamento perché troppe persone lo hanno chiesto.
DXM,

Risposte:


25

Stai cercando la documentazione relativa a blocco dei file e concorrenza .

I processi SQLite utilizzano una serie di blocchi per gestire la concorrenza; per leggere, diversi processi possono ottenere un SHAREDblocco.

Un processo che scrive, dovrà ottenere un RESERVEDblocco, e solo quando effettivamente scaricare le modifiche sul disco si sposta sullo PENDINGstato. Qualsiasi processo di lettura dovrà quindi sbloccare il file, dopodiché il processo di scrittura sarà in grado di passare EXCLUSIVEper la scrittura nel file di database effettivo.

Poiché il processo del writer deve solo bloccare il file del database per le scritture effettive (svuotamenti della memoria, commit), una configurazione con un solo lettore e un solo writer funzionerà abbastanza bene. Mi aspetterei che funzioni altrettanto bene, se non meglio, come una configurazione con un solo processo che fa tutta la lettura e la scrittura.

SQLite è meno adatto quando si hanno più processi che scrivono spesso nello stesso database, poiché la scrittura richiede l'ottenimento del PENDINGblocco esclusivo per serializzare le modifiche.


Grazie per la risposta approfondita Martijn! Ho alcuni script per fare alcuni test e sembra che due processi possano leggere e scrivere felicemente una singola istanza sqlite contemporaneamente. Stavo facendo richieste di lettura e scrittura simultanee che si attivavano ogni 1/100 di secondo e non ricevevo ancora un'eccezione db bloccata. Stranamente, l'unica volta che ho ricevuto un messaggio di errore "database bloccato" è stato quando ho tentato manualmente (con il client della riga di comando sqlite3) di eliminare alcune righe mentre le richieste di lettura venivano attivate dal mio script a 1/100 di secondo. Mi chiedo se pysql ritenta automaticamente una scrittura dopo un tale errore.
bb

10

Volevo solo dare seguito e far sapere a tutti che l'implementazione ha avuto successo. Lavorare con SQLite è stato un vero piacere, e con un solo processo scritto alla volta non abbiamo mai avuto problemi con il lock-up ... anche con letture simultanee molto rapide da un processo secondario.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.