Warum sind gleichzeitige Schreibvorgänge in einer SQLite-Datenbank nicht zulässig?

79

Ich mache Datenbankprogrammierung mit Java mit SQLite.

Ich habe festgestellt, dass jeweils nur eine Verbindung zur Datenbank Schreibfunktionen hat, während viele Verbindungen gleichzeitig Lesefunktionen haben.

Warum wurde die Architektur von SQLite so entworfen? Warum können nicht zwei Schreibvorgänge gleichzeitig ausgeführt werden, solange die beiden zu schreibenden Objekte nicht an derselben Stelle in der Datenbank gespeichert werden?

SteelToe
quelle
5
Weil SQLite so konzipiert wurde, dass es "lite" ist. Geringer Arbeitsspeicher und geringe Verarbeitung mit Leistung. Überlegen Sie, wie SQLite mehrere Schreibvorgänge in dieselbe Datei ausführen soll. Das aktuelle Design ist einfach zu implementieren - die gesamte Datei ist gesperrt und andere müssen warten. Um die gleichzeitige Verwendung von Schreibvorgängen auf einer niedrigeren Granularitätsstufe zu handhaben, ist eine Zeilen- / Seitensperrung erforderlich, die Sie von den RDMS erhalten. Wenn die Anforderung Schreib-Parallelität erfordert, ist SQLite kein Kandidat. Stattdessen sollten Sie sich für ein leichtgewichtiges RDBMS entscheiden: de.wikipedia.org/wiki/…
Thomas Carlisle

Antworten:

157

Da "mehrere gleichzeitige Schreibvorgänge" in der Kerndatenbank-Engine sehr viel schwieriger durchzuführen sind als bei einem einzelnen Schreiber und mehreren Lesern. Es geht über die Designparameter von SQLite hinaus und würde wahrscheinlich die erfreulich kleine Größe und Einfachheit von SQLite untergraben.

Die Unterstützung eines hohen Grads an Parallelität beim Schreiben ist ein Kennzeichen großer Datenbankmodule wie DB2, Oracle, SQL Server, MySQL, PostgreSQL, NonStop SQL und Sybase. Technisch ist dies jedoch schwierig, da umfangreiche Strategien zur Steuerung und Optimierung der Parallelität wie Datenbank-, Tabellen- und Zeilensperrung oder in moderneren Implementierungen die Steuerung der Parallelität für mehrere Versionen erforderlich sind . Die Forschung zu diesem Problem / dieser Anforderung ist umfangreich und reicht Jahrzehnte zurück .

SQLite hat eine ganz andere Designphilosophie als die meisten serverzentrierten DBMS, die mehrere Writer unterstützen. Es wurde entwickelt, um die Leistungsfähigkeit von SQL und des relationalen Modells für einzelne Anwendungen zu nutzen und um tatsächlich in jede Anwendung eingebettet zu werden. Dieses Ziel erfordert erhebliche Kompromisse. Dazu gehört auch, dass nicht die für die Verarbeitung mehrerer gleichzeitiger Writer erforderliche Infrastruktur und der Overhead hinzugefügt werden müssen.

Die Philosophie kann durch eine Erklärung auf der entsprechenden Verwendungsseite von SQLite zusammengefasst werden :

SQLite konkurriert nicht mit Client / Server-Datenbanken. SQLite konkurriert mit fopen ().

Jonathan Eunice
quelle
41
+1. SQLite ist eine In-Process-Datenbank. Es gibt keinen zentralen Arbiter wie in einer serverbasierten Datenbank. Die Autoren müssten direkt miteinander kooperieren und sich gegenseitig vertrauen. Ein einzelner böswilliger Schriftsteller könnte Chaos anrichten, wenn er nicht kooperiert.
Jörg W Mittag
12
Einige der Umgebungen, in denen SQLite ausgeführt wird, unterstützen möglicherweise nicht einmal mehrere Prozesse.
David25272
1
Vermutlich kann ein böswilliger Schreibzugriff bereits Unheil anrichten, wenn er nicht zusammenarbeitet. Sie können den SQLite-Code nicht verwenden, aber sie können ihren eigenen Code haben, was nur ein Aufruf von unlink ()
bdsl sein könnte.
12
In gleichzeitigen Apps gibt es nicht viel Mittelweg. Entweder erhalten Sie die Gleichzeitigkeit, Konsistenz und Datenintegrität im Wesentlichen zu 100%, auch unter schwierigen Bedingungen und Randbedingungen, oder Sie tun dies nicht. Wenn Sie dies nicht tun, ist es zerbrechlich, langsam und sturzanfällig, und die Leute hören sehr schnell auf, ihm zu vertrauen. Aber es routinemäßig richtig zu machen, ist furchtbar schwer. Es gibt nicht so viele Umstände, unter denen Schriftsteller ohne jede Menge Unterstützung verschachtelte Schriften selbstständig koordinieren können.
Jonathan Eunice
8
@bdsl Datenbanken jeglicher Art müssen davon ausgehen, dass sich die Autoren nicht gut benehmen, damit sie keine Daten verlieren. Die SQLite-Autoren positionieren sich als Konkurrent zu fopen(), bedenken Sie also die Haarigkeit, die mit dem gleichzeitigen Schreiben in eine reine Textdatei einhergeht.
Blrfl
12

Weil es keinen Server gibt, der sagen kann, ob Dinge an die gleiche Stelle geschrieben werden sollen oder nicht. Es gibt nur zwei Prozesse, die versuchen, in eine Datei zu schreiben.

Wie in einem Kommentar erwähnt, können gleichzeitige Schreibvorgänge auch von einem internen Thread unterstützt werden. Ich bin mir nicht sicher, wie gut das funktionieren würde (habe auch nicht viel darüber nachgedacht). Wie auch immer, SQLite verwendet hier keine Threads: Dr. Hipp ist der Meinung, dass Threads böse sind.

Die Tatsache, dass DR Hipp der Meinung ist, dass Threads böse sind, ist in den SQLite-FAQ dokumentiert .

Goyo
quelle
2
Dies erklärt den technischen Grund, warum gleichzeitiges Schreiben nicht zulässig ist, aber nicht, warum die Entwurfsentscheidung getroffen wurde.
Robert Harvey
3
Die Entscheidung, SQLite so zu gestalten, dass nur ein Schreibvorgang gleichzeitig verarbeitet wird.
Robert Harvey
7
@Goyo Ein Server ist nicht erforderlich, um gleichzeitige Schreibvorgänge zu verarbeiten. Da ein Datenbankserver ein separater Prozess ist, kann es einen separaten SQLite-internen Thread geben, der denselben Zweck erfüllt. Robert Harvey hat Recht: Das SQLite-Team hat eine Entwurfsentscheidung getroffen, die nichts mit der Fähigkeit einer einzelnen Bibliothek zu tun hat, gleichzeitige Schreibvorgänge durchzuführen (da dies theoretisch möglich ist).
1
Diese Antwort scheint mir in Ordnung zu sein. Um gleichzeitige Schreibvorgänge durchführen zu können, muss entweder ein Server oder eine SQLite-Implementierung mit mehreren Threads vorhanden sein. Da beide durch andere Entwurfsentscheidungen ausgeschlossen wurden, wäre die Implementierung gleichzeitiger Schreibvorgänge äußerst schwierig.
jpa
5
@jpa: SQLite kann das Sperren zwischen mehreren Prozessen / Threads synchronisieren, ohne dass bereits ein "Server" vorhanden ist. Ein "Server" ist nicht erforderlich - die Verwendung von vom Betriebssystem bereitgestelltem Sperren / Synchronisieren / IPC / was auch immer ausreicht, wird jedoch sehr schnell komplex. Der im Beitrag erwähnte "interne Thread" macht keinen Sinn.
Mat