SQLite avec deux processus python y accédant: une lecture, une écriture

22

Je développe un petit système à deux composants: l'un interroge les données d'une ressource Internet et les traduit en données sql pour les conserver localement; le second lit les données sql de l'instance locale et les sert via json et une api reposante.

Je prévoyais à l'origine de conserver les données avec postgresql, mais parce que l'application aura un très faible volume de données à stocker et du trafic à servir, je pensais que c'était exagéré. SQLite est-il à la hauteur? J'aime l'idée de la petite empreinte et pas besoin de maintenir encore un autre serveur SQL pour cette seule tâche, mais je suis préoccupé par la concurrence.

Il semble que lorsque la journalisation en écriture préalable est activée, la lecture et l'écriture simultanées d'une base de données SQLite peuvent se produire sans verrouiller l'un ou l'autre processus de la base de données.

Une seule instance SQLite peut-elle soutenir deux processus simultanés y accédant, si un seul lit et l'autre écrit? J'ai commencé à écrire le code mais je me demandais s'il s'agissait d'une mauvaise application de SQLite.

bb
la source
3
@gnat Cool. Une seule instance SQLite peut-elle soutenir deux processus simultanés y accédant, si un seul lit et l'autre écrit? J'ai commencé à écrire le code mais je me demandais s'il s'agissait d'une mauvaise application de SQLite.
bb
Juste un avertissement. Dans mon entreprise précédente, nous utilisions SQL (MS et Oracle Express) pour un certain stockage et nous avons toujours pensé qu'avec le peu que nous stockions, nous n'avions pas besoin d'une base de données complète. Donc, dans l'une des versions, nous avons décidé de faire exactement ce que vous faites. Remplacez ces produits par SQLite. Nous avions exactement la même chose, un écrivain qui déposerait des données sur le disque et mettrait à jour la table des matières et le processus de lecture SQL (plusieurs threads) qui liraient la table des matières pour déterminer les données à récupérer. Je ne sais pas à propos de SQLite ces jours-ci, mais le peu de concurrence dans laquelle nous nous sommes heurtés s'est avéré être une douleur majeure en ...
DXM
... derrière. Je ne me souviens pas de tous les détails, mais je pense que lorsqu'un processus a essayé d'obtenir un verrou et ne pouvait pas parce qu'un autre était en train de lire, il dormait pendant quelque chose de fou comme 20-30 secondes. Nous avons fini par créer un thread dédié qui était responsable de l'accès SQLite, puis nous avons eu nos deux processus, et tous les threads qu'ils contiennent, sérialisent leurs demandes de base de données vers ce thread. Avec le recul, je ne serais probablement pas reparti avec SQLite.
DXM
1
@DXM merci pour l'avertissement, mais après avoir exécuté quelques tests, je ne me suis pas heurté à quelque chose de similaire. Je sais que sqlite a subi une refonte majeure avec la version 3, qui était vers 2004, donc je me demande si votre expérience négative remonte à cette époque.
bb
1
... vous-même, plutôt que de vous fier aux schémas de verrouillage de SQLite. Je n'ai pas fait le travail moi-même, c'était une autre équipe mais je suis resté dans la boucle principalement pour fournir des commentaires et par curiosité. Je suis également allé en ligne et j'ai fait une lecture indépendante et j'ai trouvé la page de l'auteur original. En lisant cela, j'ai eu l'impression que l'inventeur de SQLite détestait simplement les threads et ne voyait pas pourquoi quelqu'un les utiliserait, donc a) la base de données n'a pas été conçue en pensant à eux et b) les verrous / protection ont été un peu ajoutés / piraté après coup parce que trop de gens l'ont demandé.
DXM

Réponses:

25

Vous recherchez la documentation File Locking And Concurrency .

Les processus SQLite utilisent une série de verrous pour gérer la concurrence; à lire, plusieurs processus peuvent obtenir un SHAREDverrou.

Un processus qui écrit, devra obtenir un RESERVEDverrou, et ce n'est que lorsqu'il doit réellement vider les modifications sur le disque qu'il passe à l' PENDINGétat. Tout processus de lecture devra ensuite déverrouiller le fichier, après quoi le processus d'écriture pourra se déplacer vers EXCLUSIVEpour écrire dans le fichier de base de données réel.

Étant donné que le processus d'écriture n'a besoin que de verrouiller le fichier de base de données pour les écritures réelles (vidages de mémoire, validations), une configuration avec un seul lecteur et un seul écrivain fonctionnera assez bien. Je m'attends à ce qu'il fonctionne aussi bien, sinon mieux, en tant que configuration avec un seul processus effectuant toutes les tâches de lecture et d'écriture.

SQLite est moins adapté lorsque plusieurs processus écrivent fréquemment dans la même base de données, car l'écriture nécessite l'obtention du PENDINGverrou exclusif pour sérialiser les modifications.

Martijn Pieters
la source
Merci pour la réponse approfondie Martijn! J'ai quelques scripts pour faire des tests et il semble que deux processus liront et écriront une seule instance sqlite simultanément. Je faisais des demandes de lecture et d'écriture simultanées se déclenchant tous les 1 / 100e de seconde et je n'ai toujours pas reçu d'exception de base de données verrouillée. Étrangement, la seule fois où j'ai reçu un message d'erreur «base de données verrouillée», c'était lorsque j'essayais manuellement (avec le client de ligne de commande sqlite3) de supprimer quelques lignes pendant que les demandes de lecture se déclenchaient à partir de mon script au 1 / 100e de seconde. Je me demande si pysql réessaye automatiquement une écriture après une telle erreur.
bb
10

Je voulais juste faire un suivi et faire savoir à tout le monde que la mise en œuvre a réussi. Travailler avec SQLite a été un réel plaisir, et avec un seul processus à l'écrire à la fois, nous n'avons jamais eu de problèmes de verrouillage ... même avec des lectures simultanées très rapides à partir d'un processus secondaire.

bb
la source