SQLite con dos procesos de Python accediendo a él: una lectura, una escritura

22

Estoy desarrollando un sistema pequeño con dos componentes: uno sondea datos de un recurso de internet y los traduce a datos sql para conservarlos localmente; el segundo lee los datos sql de la instancia local y los sirve a través de json y una api relajante.

Originalmente planeaba conservar los datos con postgresql, pero debido a que la aplicación tendrá un volumen muy bajo de datos para almacenar y tráfico para servir, pensé que era excesivo. ¿SQLite está a la altura? Me encanta la idea de la pequeña huella y no es necesario mantener otro servidor sql para esta tarea, pero estoy preocupado por la concurrencia.

Parece que con el registro de escritura anticipada habilitado, simultáneamente puede leer y escribir una base de datos SQLite sin bloquear ninguno de los procesos de la base de datos.

¿Puede una sola instancia de SQLite sostener dos procesos concurrentes que acceden a ella, si solo uno lee y el otro escribe? Empecé a escribir el código, pero me preguntaba si esta es una aplicación incorrecta de SQLite.

cama y desayuno
fuente
3
@gnat Cool. ¿Puede una sola instancia de SQLite sostener dos procesos concurrentes que acceden a ella, si solo uno lee y el otro escribe? Empecé a escribir el código, pero me preguntaba si esta es una aplicación incorrecta de SQLite.
bb
Solo un aviso. En mi empresa anterior, estábamos usando SQL (tanto MS como Oracle Express) para algo de almacenamiento y siempre sentimos que con lo poco que almacenamos, no necesitábamos una base de datos completa. Entonces, en uno de los lanzamientos, decidimos hacer exactamente lo que está haciendo. Reemplace esos productos con SQLite. Teníamos exactamente lo mismo, un escritor que depositaría datos en el disco y actualizaría el TOC basado en SQL y el proceso de lectura (múltiples hilos) que leerían TOC para determinar qué datos recuperar. No sé sobre SQLite en estos días, pero la poca concurrencia con la que nos encontramos resultó ser un gran dolor en ...
DXM
... el trasero. No recuerdo todos los detalles, pero creo que cuando un proceso intentó obtener un bloqueo y no pudo porque otro estaba leyendo, DORMIRÍA por algo loco como 20-30 segundos. Terminamos creando un subproceso dedicado que era responsable del acceso a SQLite y luego tuvimos nuestros procesos y todos los subprocesos en ellos, serializar sus solicitudes de base de datos a ese único subproceso. En retrospectiva, probablemente no habría vuelto a usar SQLite.
DXM
1
@DXM gracias por la advertencia, pero después de ejecutar algunas pruebas, no me he encontrado con nada similar. Sé que sqlite tuvo una revisión importante con la versión 3, que fue alrededor de 2004, por lo que me pregunto si su experiencia negativa se remonta antes de ese momento.
bb
1
... usted mismo, en lugar de confiar en los esquemas de bloqueo de SQLite. No hice el trabajo yo mismo, era otro equipo más, pero me mantuve al tanto principalmente para proporcionar comentarios y por curiosidad. También me conecté en línea e hice algunas lecturas independientes y encontré la página original del autor. Al leer eso, tuve la impresión de que el inventor de SQLite simplemente odiaba los hilos y no veía por qué alguien los usaría, por lo que a) el DB no fue diseñado pensando en ellos yb) se agregaron bloqueos / protección / pirateado como una ocurrencia tardía porque mucha gente lo pidió.
DXM

Respuestas:

25

Está buscando la documentación de bloqueo y concurrencia de archivos.

Los procesos SQLite usan una serie de bloqueos para manejar la concurrencia; para leer, varios procesos pueden obtener un SHAREDbloqueo.

Un proceso que escribe, necesitará obtener un RESERVEDbloqueo, y solo cuando realmente tenga que vaciar los cambios en el disco, pasará al PENDINGestado. Cualquier proceso de lectura tendrá que desbloquear el archivo, después de lo cual el proceso de escritura podrá moverse EXCLUSIVEpara escribir en el archivo de base de datos real.

Debido a que el proceso de escritura solo necesita bloquear el archivo de la base de datos para las escrituras reales (borrados de memoria, confirmaciones), una configuración con solo un lector y solo un escritor funcionará bastante bien. Esperaría que funcione igual de bien, si no mejor, como una configuración con solo un proceso haciendo toda la lectura y escritura.

SQLite es menos adecuado cuando tiene múltiples procesos que escriben frecuentemente en la misma base de datos, ya que la escritura requiere obtener el PENDINGbloqueo exclusivo para serializar los cambios.

Martijn Pieters
fuente
Gracias por la respuesta completa Martijn! Tengo algunas secuencias de comandos para hacer algunas pruebas y parece que dos procesos leerán y escribirán una sola instancia de SQLite simultáneamente. Estaba haciendo solicitudes simultáneas de lectura y escritura disparando cada 1/100 de segundo y todavía no recibí una excepción db bloqueada. Curiosamente, la única vez que recibí un mensaje de error de "base de datos bloqueada" fue cuando intentaba manualmente (con el cliente de línea de comando sqlite3) eliminar algunas filas mientras las solicitudes de lectura se disparaban desde mi script a 1/100 de segundo. Me pregunto si pysql reintenta automáticamente una escritura después de tal error.
bb
10

Solo quería hacer un seguimiento y hacerles saber a todos que la implementación fue exitosa. Trabajar con SQLite fue un verdadero placer, y con solo un proceso escribiéndolo a la vez, nunca tuvimos problemas con el bloqueo ... incluso con lecturas concurrentes muy rápidas de un proceso secundario.

cama y desayuno
fuente