2010-04-08 8 views
6

Ich bin sicher, dass ich etwas ziemlich offensichtlich vermisse, aber ich kann nicht für das Leben von mir aufhören meine Pysqlite-Skripte mit einer Datenbank ist gesperrt Fehler aus. Ich habe zwei Skripte, eines zum Laden von Daten in die Datenbank und eines zum Lesen von Daten, aber beide werden häufig und sofort abstürzen, abhängig davon, was der andere gerade mit der Datenbank macht.Python/SQLite - Datenbank gesperrt trotz großer Timeouts

cx = sqlite.connect("database.sql", timeout=30.0) 

Und ich denke, einige Beweise für die Timeouts in das sehe ich bekommen, was ein Zeittempel zu sein scheint (zB 0.12343827e-06 0,1 -: Ich habe das Timeout auf beiden Skripte auf 30 Sekunden eingestellt bekam und wie höre ich damit auf, gedruckt zu werden?) gelegentlich in der Mitte meines formatierten Curse-Ausgabebildschirms ausgegeben, aber keine Verzögerung, die jemals entfernt nahe dem 30-Sekunden-Timeout kommt, aber immer noch stürzt einer der anderen immer wieder ab. Ich laufe RHEL 5.4 auf einem 64-Bit 4 CPU HS21 IBM Blade, und habe einige Erwähnung über Probleme über Multithreading gehört und bin nicht sicher, ob dies relevant sein könnte. Die verwendeten Pakete sind sqlite-3.3.6-5 und python-sqlite-1.1.7-1.2.1, und ein Upgrade auf neuere Versionen außerhalb der offiziellen Bestimmungen von Red Hat ist für mich keine gute Option. Möglich, aber aufgrund der Umwelt im Allgemeinen nicht wünschenswert.

Ich hatte autocommit=1 zuvor in beiden Skripten, aber seit beide auf deaktiviert haben, und ich bin jetzt ing auf das Einfügen von Skript und nicht auf dem Select-Skript zu committieren. Letztendlich, da ich immer nur ein Skript habe, das tatsächlich Änderungen vornimmt, sehe ich nicht wirklich, warum dieses Locking jemals passieren sollte. Ich habe festgestellt, dass dies im Laufe der Zeit deutlich schlechter ist, wenn die Datenbank größer geworden ist. Es war vor kurzem bei 13 MB mit 3 gleichgroßen Tabellen, die etwa 1 Tag Daten waren. Das Erstellen einer neuen Datei hat dies deutlich verbessert, was verständlich erscheint, aber die Zeitüberschreitung scheint letztendlich nicht eingehalten zu werden.

Alle Hinweise sehr geschätzt.

EDIT: seit Nachfrage Ich konnte meinen Code leicht restrukturieren und ein Signal verwenden, um periodisch zwischen 0 und 150 Updates in einer Transaktion alle 5 Sekunden zu schreiben. Dies hat das Auftreten der Verriegelung auf weniger als eine Stunde im Gegensatz zu einmal in jeder Minute signifikant reduziert. Ich denke, ich könnte noch weiter gehen und sicherstellen, dass die Daten, die ich schreibe, um ein paar Sekunden versetzt sind, während ich Daten im anderen Skript lese, aber im Grunde arbeite ich an einem Problem, so wie ich es wahrnehme Es scheint immer noch nicht so. Ta.

Antwort

0

SQLite verwendet für jedes Schreiben eine Datenbanksperrung (update/insert/delete/...). IMHO, diese Sperre wird gehalten, bis die Transaktion endet. Dies ist eine einzelne Sperre, die über Threads/Prozesse gehalten wird, AFAIK.

Also, ich würde versuchen, explizit sowohl Transaktion und Verbindung zum Schreiben von Skript zu beenden und explizit auch im Leseskript festschreiben und versuchen, Nebenläufigkeitsprobleme zu debuggen.

+0

Sie wollen die gesamte Datenbank schließen? Es ist in Ordnung, wenn ein Schloss gehalten wird, aber keines der Skripts wartet so lange, bis das Schloss freigegeben wird. –

+0

Ja, ich meine eine enge Verbindung zur Datenbank von der Verbindung, die schreibt. – Almad

+1

Nun, ich schreibe alle paar Sekunden in die Datenbank, und wenn ich es schließe, ändert das nichts wirklich? Es gibt zusätzliche Arbeit beim Öffnen und Schließen, also würde das nicht schlimmer machen? Und wenn ich die Änderungen vor dem Schließen festlege, hat es auch keinen Vorteil, sie zu schließen, da sie nicht mehr gesperrt sind. –

0

SQLite ist einfach nicht für schreibintensive Workloads optimiert und tut auch nicht so (aber es macht nichts, in einer Transaktion ziemlich viel zu schreiben). Es klingt für mich, als ob Sie zu dem Punkt kommen, an dem Sie zu einer anderen Datenbank wie MySQL, PostgreSQL, Oracle oder DB2 wechseln müssen. Einige dieser Optionen sind in der Tat teuer, aber für einige Workloads ist das genau das, was Sie brauchen. (Beachten Sie auch, dass der Schreib hohe Arbeitsbelastung tendenziell besser mit einer dedizierten Datenbank-Server-Lösung zu tun, trotz der Tatsache, dass die Bereitstellungskosten und die Komplexität nach oben drückt. Manches nur kosten.)

+0

Ich würde sicherlich viel lieber eine richtige Datenbank verwenden, aber es ist einfach nicht verfügbar für verschiedene Gründe. –

+0

Nun, dann seien Sie darauf vorbereitet, dass einige Dinge langsam sind. Es kann einfach nicht geholfen werden. –

2

In früheren Versionen von pysqlite Der timeout Parameter zu sqlite.connect wird offensichtlich als Millisekunden interpretiert. So sollte Ihre timeout=30.0timeout=30000 sein.