MySQL MySQL Risiken bei Stromausfall minimieren

Hallo zusammen!

Bin aktuell mit mit einem Hausautomations-System beschäftigt, wo u.A. MySQL eingesetzt wird. Nun ist es so, dass dieses nicht auf einem “normalen” Computer läuft sondern auf einem embedded-System. Und dort läuft Linux (auf ext4) sowie MySQL (InnoDB) drauf.

Frage: Wie lässt sich das Risiko minimieren falls der Anwender dem Gerät den Strom entfernt? Es ist dabei nicht vorgesehen dass man einen Zugriff auf das Linux-System hat - weder über “normale” Ein- und Ausgabemöglichkeiten wie Tastatur und Bildschirm (hat sowieso kein Desktop, die Maus ist nicht mal für die Entwickler ein Thema) noch über SSH.

Zwar ist es vorgesehen dass im Web-GUI (für die Administration) ein Button zum Herunterfahren drin sein soll, aber was ist wenn das Gerät “einfach so” vom Stromnetz getrennt wird?

Welche MySQL-Optionen hätte man dafür, um ein solches Risiko möglichst klein zu halten? Mir ist natürlich klar, dass relationale Datenbanken grundsätzlich nicht dafür geeignet sind - insbesondere dann wenn oft geschrieben, und nicht nur hauptsächlich gelesen wird.

  • Alle DB-Operationen welche aus mehreren Schritten nacheinander bestehen als Transaktion auszuführen. Aber was passiert dann, angenommen der Strom wird zwischen mehrerern SQL-Anweisungen in der Art lesen/ändern/löschen gekappt? Ich gehe von einem Rollback aus nach einem Stromausfall, und nicht von einer erneuten Ausführung der ganzen Transaktion?

  • Welche InnoDB-Optionen könnte man zwecks Risiko-Minimierung (NICHT “Verhinderung”) anpassen? https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html

  • Ich habe mir überlegt, sämtliche Caching-Features für InnoDB auszuschalten, aber so einfach ist das leider nicht. Z.B. Macht das Ausschalten der Option “innodb_doublewrite” das Problem nur noch grösser - kann offenbar sogar zum Problem werden wenn das System noch mit Strom versorgt wird. -> https://dba.stackexchange.com/quest...-safe-to-disable-innodb-doublewrite-buffering-> “Only if data are not important. Disabling double write buffer not only breaks ACID compliance, but also can (and eventually will) corrupt InnoDB tablespace”
(Natürlich muss dabei in der Doku für den Endbenutzer ausdrücklich darauf hingewiesen werden dass man UNBEDINGT das System per Web-GUI herunterfahren muss!!)

Danke für eure Tipps!

Mit freundlichen Grüssen,
Jan
 
Sorry, zur eigentlichen Frage kann ich leider nichts beitragen, aber meiner Ansicht nach, wäre es eine sinnvolle Lösung einen Stromausfall hardwaretechnisch zu erkennen und z.B. über einen Akku oder Goldcap zu puffern, so dass das System in einen sicheren Zustand gebracht werden kann.
 
Ich denke im Datenbank-Forum deiner Wahl kommst du besser an Expertenwissen, gerade weil es um die spezielle Konfiguration und das Verhalten der Datenbank geht und nicht wirklich um die Programmierung.
 
Mir ist natürlich klar, dass relationale Datenbanken grundsätzlich nicht dafür geeignet sind
?!?

Alle DB-Operationen welche aus mehreren Schritten nacheinander bestehen als Transaktion auszuführen.
Grundsätzlich finden alle (DML) Statements im Rahmen einer Transaktion statt. Beim "autocommit" wird nach jedem Statement automatisch ein Commit ausgeführt.

Aber was passiert dann, angenommen der Strom wird zwischen mehrerern SQL-Anweisungen in der Art lesen/ändern/löschen gekappt?
Transaktionen sind atomar. Wurden sie erfolgreich abgeschlossen wurden, dann sind die Änderungen dauerhaft gespeichert. Werden sie nicht erfolgreich abgeschlossen, dann sind die Änderungen praktisch nicht existent.

Dabei ist "dauerhaft gespeichert" mit etwas Vorsicht zu genießen, weil man es vom Standpunkt des DBMS aus betrachten muss. Wenn ein anderer Bestandteil des Systems (OS/Hardware) meldet, dass die Daten geschrieben seien obwohl dies nicht der Fall ist, dann kann das DBMS natürlich nichts dagegen tun.

Ich habe mir überlegt, sämtliche Caching-Features für InnoDB auszuschalten
Wozu?

Z.B. Macht das Ausschalten der Option “innodb_doublewrite” das Problem nur noch grösser - kann offenbar sogar zum Problem werden wenn das System noch mit Strom versorgt wird.
Soweit ich das verstehe:

Der doublewrite-Buffer ist kein in-memory-Cache zum verzögerten Schreiben sondern ein persistenter Zwischenspeicher für das Crash-Recovery.

Während einer Transaktion werden die Änderungen im Redo- bzw. Undo-Log protokolliert. Spätestens beim Commit werden die Log-Files geschrieben.

Die im Redo-Log festgehaltenen Änderungen werden auf die Seiten der Datendateien übertragen. Eine Seite der Datendatei kann in der Regel nicht atomar geschrieben werden, d. h. es wäre z. B. beim Stromausfall möglich, dass nur ein Teil einer Seite geschrieben wird und somit inkonsistent würde. Daher fügt MySQL die geänderten Seiten erst einmal zum doublewrite-Buffer hinzu. Nachdem dieser weggeschrieben (inkl. sync) wurde, werden die Seiten in die Datendateien übertragen. Wird mysql dabei unerwartet beendet (z. B. Stromausfall) können auch unvollständig geschriebene Seiten dem doublewrite-Buffer entnommen werden. Sind die Daten in der Datendatei wird das Redo-Log korrigiert.

Standardeinstellungen dürften auf größtmögliche ACID-Kompatibilität ausgelegt sein, recht viel mehr wird nicht gehen.
 
@mihe7 hat eig. schon fast alles gesagt.
Grundsätzlich: Du machst dir zu viele Gedanken über Probleme, die so eig. gar nicht relevant sind.
Darüber haben sich schon viele Datenbank Engineers vor dir Gedanken gemacht und entsprechende Technologien entwickelt. z.B. liest MySQL beim Start die Logs ein und kann sich so in gewisser Hinsicht selbst reparieren, falls es notwendig sein sollte.
Mit Transaktionen bist du immer auf der sicheren Seite, da erst beim Abschluss (commit) wirklich persistent gespeichert wird --> entweder werden die Daten vollständig geschrieben, oder gar nicht. Ein teilweises Schreiben gibt es normalerweise nicht und falls doch, merkt das MySQL dank der Logs normalerweise beim nächsten Start und korrigiert dies entsprechend / führt einen rollback aus.
 
@mihe7:

"?!?"

Ich habe die Sache ursprünglich nicht konzipiert, erst als ich in diesem Projekt angestellt wurde habe ich das hinterfragt. Deshalb meine Beiträge...


"Grundsätzlich finden alle (DML) Statements im Rahmen einer Transaktion statt. Beim "autocommit" wird nach jedem Statement automatisch ein Commit ausgeführt."

Es geht mir darum, wenn es einen Stromausfall gibt bei einem Statement mit mehreren delete, update und/oder insert-Anweisungen. Dann all diese besser innerhalb EINER Transaktion ausführen...


"Wozu?"

Weil ich geadacht habe, dass sich der Schreibcache evtl. ausschalten lässt und es so sicherer wird. Aber wie bereits erwähnt, die einzige Sache welche man diesbezüglich ändern (deaktivieren) kann ist "innodb_doublewrite" - und das macht es noch unsicherer: https://dba.stackexchange.com/quest...-safe-to-disable-innodb-doublewrite-buffering ("Only if data are not important. Disabling double write buffer not only breaks ACID compliance, but also can (and eventually will) corrupt InnoDB tablespace")

"Der doublewrite-Buffer ist kein in-memory-Cache zum verzögerten Schreiben sondern ein persistenter Zwischenspeicher für das Crash-Recovery."

"Standardeinstellungen dürften auf größtmögliche ACID-Kompatibilität ausgelegt sein, recht viel mehr wird nicht gehen."

Vielen Dank!
 
@JuKu:

"Grundsätzlich: Du machst dir zu viele Gedanken über Probleme, die so eig. gar nicht relevant sind.
Darüber haben sich schon viele Datenbank Engineers vor dir Gedanken gemacht und entsprechende Technologien entwickelt. z.B. liest MySQL beim Start die Logs ein und kann sich so in gewisser Hinsicht selbst reparieren, falls es notwendig sein sollte.
Mit Transaktionen bist du immer auf der sicheren Seite, da erst beim Abschluss (commit) wirklich persistent gespeichert wird --> entweder werden die Daten vollständig geschrieben, oder gar nicht. Ein teilweises Schreiben gibt es normalerweise nicht und falls doch, merkt das MySQL dank der Logs normalerweise beim nächsten Start und korrigiert dies entsprechend / führt einen rollback aus."


Dir ebenfalls vielen Dank!
 

Neue Themen


Zurück
Oben