
Automatisiertes Testen zur Erkennung von Logik- und Performance-Fehlern in Datenbanksystemen

SQLancer ist ein Werkzeug zum automatisierten Testen von Datenbankmanagementsystemen (DBMS), um Fehler in deren Implementierung zu finden. Das heißt, es findet Fehler im Code der DBMS-Implementierung, nicht in vom Benutzer geschriebenen Abfragen. SQLancer hat Hunderte von Fehlern in ausgereiften und weit verbreiteten DBMS gefunden.
SQLancer bewältigt zwei wesentliche Herausforderungen beim automatisierten Testen von DBMS:
Community. Wir haben einen Slack-Workspace, um über SQLancer und DBMS-Testing im Allgemeinen zu diskutieren. Zuvor hatte SQLancer einen Account auf Twitter/X @sqlancer_dbms, der nicht mehr gepflegt wird. Wir haben einen Blog, der derzeit nur Beiträge von Mitwirkenden des Google Summer of Code-Projekts enthält.
Mindestanforderungen:
Die folgenden Befehle klonen SQLancer, erstellen ein JAR und starten SQLancer, um SQLite mit Non-optimizing Reference Engine Construction (NoREC) zu testen:
git clone https://github.com/sqlancer/sqlancer
cd sqlancer
mvn package -DskipTests
cd target
java -jar sqlancer-*.jar --num-threads 4 sqlite3 --oracle NoREC
Ausführen und Beenden. Wenn die Ausführung alle fünf Sekunden Fortschrittsinformationen ausgibt, funktioniert das Tool wie erwartet. Mit der Tastenkombination STRG+C kann SQLancer manuell beendet werden. Wenn SQLancer keine Fehler findet, läuft es unendlich weiter. Mit der Option --num-tries kann gesteuert werden, nach wie vielen Fehlern SQLancer beendet wird. Alternativ kann mit der Option --timeout-seconds die maximale Laufzeit angegeben werden, die SQLancer ausgeführt werden darf.
Parameter. Wenn Sie SQLancer ohne Parameter starten, werden die verfügbaren Optionen und Befehle angezeigt. Beachten Sie, dass allgemeine Optionen, die von allen DBMS-Testimplementierungen unterstützt werden (z. B. --num-threads), vor dem Namen des zu testenden DBMS (z. B. sqlite3) stehen müssen. Optionen, die nur für bestimmte DBMS unterstützt werden (z. B. --test-rtree für SQLite3), oder Optionen, für die jede Testimplementierung unterschiedliche Werte bereitstellt (z. B. --oracle NoREC), müssen nach dem DBMS-Namen stehen.
DBMSs. Um SQLancer auf SQLite auszuführen, war es nicht notwendig, ein DBMS zu installieren und einzurichten. Der Grund dafür ist, dass eingebettete DBMSs im selben Prozess wie die Anwendung laufen und daher keine separate Installation oder Einrichtung erfordern. Von SQLancer unterstützte eingebettete DBMSs sind DuckDB, H2 und SQLite. Ihre Binärdateien sind als JAR-Abhängigkeiten enthalten. Beachten Sie, dass Abstürze in diesen Systemen auch einen Absturz der JVM verursachen, auf der SQLancer läuft.
Protokolle. SQLancer speichert Protokolle im Unterverzeichnis target/logs. Standardmäßig ist die Option --log-each-select aktiviert, wodurch jede SQL-Anweisung, die an das DBMS gesendet wird, protokolliert wird. Die entsprechenden Dateinamen erhalten das Suffix -cur.log. Darüber hinaus erstellt SQLancer, wenn es einen Logikfehler erkennt, eine Datei mit der Erweiterung .log, in der die Anweisungen zur Reproduktion des Fehlers protokolliert werden, einschließlich nur der zuletzt ausgeführten Abfrage zusammen mit den anderen Anweisungen zum Einrichten des Datenbankzustands.
Fehler reduzieren. Nachdem eine fehlerverursachende Testeingabe gefunden wurde, muss die Eingabe in der Regel reduziert werden, um weiter analysiert werden zu können, da sie viele SQL-Anweisungen enthalten kann, die für die Reproduktion des Fehlers redundant sind. Eine Möglichkeit ist, dies manuell zu tun, indem jeweils eine Anweisung oder ein Feature entfernt, die fehlerverursachenden Anweisungen erneut ausgeführt und das Testorakel angewendet wird (z. B. für Testorakel wie TLP oder NoREC würde dies erfordern, zu überprüfen, dass beide Abfragen weiterhin ein unterschiedliches Ergebnis liefern). Dieser Prozess kann mithilfe eines sogenannten Delta-Debugging-Ansatzes automatisiert werden. SQLancer enthält eine experimentelle Implementierung eines Delta-Debugging-Ansatzes, die mit --use-reducer aktiviert werden kann. In der Vergangenheit haben wir erfolgreich C-Reduce verwendet, was erfordert, das Testorakel in einem Skript anzugeben, das von C-Reduce ausgeführt werden kann.