sqlite> DELETE FROM mails WHERE (`id` = 71);
SQL error: database is locked
Comment puis-je déverrouiller la base de données pour que cela fonctionne ?
sqlite> DELETE FROM mails WHERE (`id` = 71);
SQL error: database is locked
Comment puis-je déverrouiller la base de données pour que cela fonctionne ?
J'ai trouvé le documentation des différents états de verrouillage dans SQLite pour être très utile. Michael, si vous pouvez effectuer des lectures mais ne pouvez pas écrire dans la base de données, cela signifie qu'un processus a obtenu un verrou RESERVÉ sur votre base de données mais n'a pas encore exécuté l'écriture. Si vous utilisez SQLite3, il y a un nouveau verrou appelé PENDING où plus aucun processus n'est autorisé à se connecter mais où les connexions existantes peuvent encore effectuer des lectures, donc si c'est le problème, vous devriez plutôt regarder ça.
Certaines fonctions, comme l'indexation, peuvent prendre beaucoup de temps - et elles verrouillent toute la base de données pendant leur exécution. Dans de tels cas, il se peut que le fichier journal ne soit même pas utilisé !
Ainsi, le meilleur/seul moyen de vérifier si votre base de données est verrouillée parce qu'un processus est en train d'y écrire ACTIVEMENT (et donc vous devez le laisser tranquille jusqu'à ce qu'il ait terminé son opération) est de md5 (ou md5sum sur certains systèmes) le fichier deux fois. Si vous obtenez une somme de contrôle différente, la base de données est en cours d'écriture, et vous n'avez vraiment vraiment VRAIMENT pas envie de tuer ce processus car vous pouvez facilement vous retrouver avec une table/base de données corrompue si vous le faites.
Je vais répéter, parce que c'est important - la solution n'est PAS de trouver le programme de verrouillage et de le tuer - c'est de trouver si la base de données a un verrouillage en écriture pour une bonne raison, et de partir de là. Parfois, la bonne solution consiste simplement à faire une pause café.
Le seul moyen de créer cette situation de verrouillage mais de non-écriture est que votre programme exécute BEGIN EXCLUSIVE
parce qu'il voulait effectuer des modifications de table ou autre chose, puis, pour une raison quelconque, n'envoie jamais de message d'erreur. END
après, et le processus ne se termine jamais . Il est hautement improbable que ces trois conditions soient réunies dans un code correctement écrit. Ainsi, 99 fois sur 100, lorsque quelqu'un veut tuer son processus de verrouillage, ce dernier verrouille en fait votre base de données pour une bonne raison. Les programmeurs n'ajoutent généralement pas l'option BEGIN EXCLUSIVE
sauf s'ils en ont vraiment besoin, car cela empêche la concurrence et augmente les plaintes des utilisateurs. SQLite lui-même ne l'ajoute que lorsqu'il en a vraiment besoin (comme lors de l'indexation).
Enfin, le statut "verrouillé" n'existe pas à l'intérieur du fichier, comme l'ont indiqué plusieurs réponses, mais dans le noyau du système d'exploitation. Le processus qui a exécuté BEGIN EXCLUSIVE
a demandé au système d'exploitation de placer un verrou sur le fichier. Même si votre processus exclusif s'est écrasé, votre système d'exploitation sera capable de déterminer s'il doit maintenir le verrou du fichier ou non ! Il n'est pas possible de se retrouver avec une base de données verrouillée mais qu'aucun processus ne la verrouille activement ! Lorsqu'il s'agit de voir quel processus verrouille le fichier, il est généralement préférable d'utiliser lsof plutôt que fuser (ceci est une bonne démonstration du pourquoi : https://unix.stackexchange.com/questions/94316/fuser-vs-lsof-to-check-files-in-use ). Alternativement, si vous avez DTrace (OSX), vous pouvez utiliser iosnoop sur le fichier.
J'ai un tel problème dans l'application, qui accède à SQLite à partir de 2 connexions - l'une en lecture seule et la seconde en écriture et lecture. Il semble que la connexion en lecture seule bloque l'écriture de la seconde connexion. Enfin, il s'avère qu'il est nécessaire de finaliser ou, au moins, de réinitialiser les déclarations préparées IMMÉDIATEMENT après utilisation. Jusqu'à ce que l'instruction préparée soit ouverte, la base de données était bloquée en écriture.
N'OUBLIEZ PAS D'APPELER :
sqlite_reset(xxx);
ou
sqlite_finalize(xxx);
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Il se peut qu'un autre processus accède au fichier de la base de données - avez-vous vérifié lsof ?
0 votes
J'ai eu le même problème, le problème était dans l'antivirus quand je le désactive mon application fonctionne bien, mais quand je l'active je trouve l'erreur "la base de données est verrouillée", j'espère que cela va vous aider.