Nico R.: "Backup-Verwaltung" für DB

Hallo allerseits,

ich baue gerade für mein Projekt eine kleine Backup-Verwaltung, um bei Bedarf für ein Unterprojekt Daten zu jedem beliebigen Zeitpunkt wieder herstellen zu können, ohne alle Daten der DB (MariaDB) mit ggf. dann schon wieder veralteten Daten zu überschreiben.

Das ist der Sicherheitsteil, den ich auf jeden Fall brauche und der auch schon funktioniert. Jetzt überlege ich in dem Zuge, auch eine Archivieren-Funktion einzubauen, um Platz in der DB freizugeben bzw. den Zugriff schnell zu halten.

Sagen wir mal hypothetisch, ich habe in einer betreffenden Tabelle 100.000 Einträge mit fortlaufender AI-ID und "archiviere", also lösche, die IDs 0-20.000. Liege ich richtig, wenn ich davon ausgehe, dass diese ersten 20.000 bei Abfragen wegfallen, die Abfragen also etwas schneller ausfallen müssten? Klingt erstmal logisch, aber vielleicht übersehe ich ja irgendetwas...

Ich könnte theoretisch ja irgendwann bei sagen wir mal ID 1.780.000 landen, was wohl auch für eine DB sehr viel wäre. Aber nicht mehr, wenn nur 80.000 IDs einen Eintrag hätten, oder?

Schöne Grüße Nico

  1. Sagen wir mal hypothetisch, ich habe in einer betreffenden Tabelle 100.000 Einträge mit fortlaufender AI-ID und "archiviere", also lösche, die IDs 0-20.000. Liege ich richtig, wenn ich davon ausgehe, dass diese ersten 20.000 bei Abfragen wegfallen, die Abfragen also etwas schneller ausfallen müssten?

    Wenn Du passend indexiert hast: „Nicht“ - oder genauer „Kaum“.

    Wenn nicht oder nach großen Löschaktionen solltest Du die Tabellen außerdem noch optimieren. Sonst hast Du keinen Effekt.

    Ob Du passend indexiert hast erfährst Du in aktuellen Versionen von MariaDB mit analyze:

    ANALYZE SELECT

    Zu Deinen Zahlen: Indexiert sind das keine Herausfoderungen, weil der Zugriff auf die kleine Datenmenge der Indizes zwar „seriell“ erfolgt (Tatsächlich ist es häufig ein Baum bzw. Tree, was die zu lesende Datenmenge nochmals verkleinert), der Zugriff auf die eigentlichen Daten sodann aber „wahlfrei“. Das sind nette Begriffe, die man in den 80ern noch lernte…

    1. Hallo Raketenwilli,

      weil der Zugriff auf die kleine Datenmenge der Indizes zwar „seriell“ erfolgt

      Nein, immer nur als Baum.

      der Zugriff auf die eigentlichen Daten sodann aber „wahlfrei“

      Was auch ein Problem darstellen kann. Wenn ich viele Sätze in Indexreihenfolge lesen will, die Indexreihenfolge aber nicht der physikalischen Reihenfolge der Rows in der Table entspricht, dann springt er auf der Platte kreuz und quer herum. Bei kleinen Tables ist der Tablespace dann schnell im Buffer und man merkt nichts, bei Millionen von Rows kann das den Lesekopf schnell ins Flattern bringen.

      Wenn die DB auf einer SSD liegt, ist es weniger schlimm, weil da kein Kopf herumhüpft, aber auch dort ist ein sequenzieller Zugriff schneller, als kreuz und quer Sektoren abzuholen.

      Heißt: Wenn man beabsichtigt, via Index größere Mengen an Datensätzen abzuholen, sollte das tunlichst der Primärindex sein. Denn MySQL und sein Datenmariechen verwenden den Primärindex als "Clustering Index". Das bedeutet: Die Daten liegen nicht in Zugangsreihenfolge in der DB-Datei, sondern auch die DB-Datei ist als Baumstruktur organisiert und die Rows liegen in Reihenfolge des Primärschlüssels darin. Weshalb eine Reorganisation auch nützlich ist, denn dann werden die Knoten des Baums auf der Platte so umgeordnet, dass sie in Indexreihenfolge dort abgelegt sind.

      Ob das Datenmariechen bei einer indexsequenziellen Leseoperation, die nicht über den Primärindex geht, dieses Problem automatisch erkennt und Zugriffe optimiert (z.B. durch erstellen einer Temp-Datei, die erst nachträglich sortiert wird), weiß ich nicht. Das ist die Magie des SQL Optimizers. Und die Optimierungsjobs, die über die Tablespaces rennen, dienen auch dazu, Informationen über die Datenverteilung zu gewinnen und dem Optimizer damit Futter zu geben.

      Ein Hinweis noch zu Backups: Billigdatenbanken sind nicht unbedingt dazu gemacht, unterbrechungsfreie Backups zu ziehen. Denn während eines Backups darf aus Konsistenzgründen nichts an der Datenbank verändert werden - was für die DB Engine bedeutet, dass sie entweder die DB brutal gegen Updates sperren muss, oder die Updates, die trotzdem gefordert werden, erstmal irgendwo zwischenspeichern muss, bis das Backup fertig ist. Weißt Du, Raketenwilli, wie sich das beim Datenmariechen verhält?

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Moin Rolf!

        • was für die DB Engine bedeutet, dass sie entweder die DB brutal gegen Updates sperren muss, oder die Updates, die trotzdem gefordert werden, erstmal irgendwo zwischenspeichern muss, bis das Backup fertig ist. Weißt Du, Raketenwilli, wie sich das beim Datenmariechen verhält?

        Vorstellbar, dass, wenn mariabackup läuft, neue oder geänderte Daten auch bei der Schließung von Transaktionen erst mal nur ins Binlog wandern. Letztendlich ist das auch von der Engine abhängig. Das sind viele „Wenn- und Abers“.

        Bei einem Backup via SQL-Dump wird es vorhersehbar Probleme geben. Den würde ich (lassen wir mal Kleinkram wie stillegbare Server außen vor) allenfalls von einem repliziertem, temporär sperrbaren Read-Only-Server machen wollen…

        1. Vielen Dank erstmal für eure Erklärungen. Mit der ANYALYZE-Ausgabe kann ich ehrlich gesagt nicht viel anfangen, dazu müsste ich mich wohl tiefer damit beschäftigen. Ich habe aber in jedem Fall in den betreffenden Tabellen, für die Spalten, über die eine WHERE-Abfrage erfolgt, Indexe angelegt.

          Da auch Rolf von "Millionen von Rows" schreibt, denke ich das Archivieren würde bei mir derzeit eher in den Bereich Spielerei fallen, denn ich werde selbst in zehn Jahren nicht ansatzweise diese Größenordnung erreichen. Im worst, oder viel mehr best case würden in der am stärksten beanspruchten Tabelle maximal 100.000 rows in einem Jahr entstehen. Da ists am Ende dann wohl besser, alle Daten lückenlos bereit zu halten, statt sie erst aus einem Archiv einzulesen und dann wieder zurück zu archivieren.

          Denn während eines Backups darf aus Konsistenzgründen nichts an der Datenbank verändert werden - was für die DB Engine bedeutet, dass sie entweder die DB brutal gegen Updates sperren muss...

          Das wäre für mich ehrlich gesagt in Ordnung. Sofern Maria nicht von alleine sperrt, könnte ich das doch mit LOCK TABLES erzwingen, oder? Die Frage ist natürlich, was passiert in dem Fall, dass sich das Backup und ein INSERT/UPDATE wirklich einmal überschneiden. Würde Maria den Schreibvorgang dann noch einmal wiederholen oder gibts eine spezielle Fehlermeldung? Ich werde das morgen mal testen...

          Bei einem Backup via SQL-Dump wird es vorhersehbar Probleme geben.

          Hmm, was ist denn die Alternative? Meine sql-Sicherungsdatei erstelle ich per Cronjob mit einem eigenen PHP-Script.

          Schöne Grüße

          Nico

          1. Hallo nochmal,

            da ich den Beitrag nicht offen stehen lassen möchte, hier nochmal kurz meine Erkenntnis. Um Datenverluste zu verhindern, werde ich die Haudrauf-Methode verwenden und einen „Wartungsmodus“ einrichten. Solange durch das Erstellen oder Einspielen eines Backups die entsprechende flag gesetzt ist, sind dann einfach keine INSERTs/UPDATEs/DELETEs mehr im betreffenden Unterprojekt möglich und der Nutzer bekommt eine Meldung, dass er es gleich nochmal versuchen soll.

            Bei einer öffentlich zugänglich Seite oder vielen Nutzern wohl eher eine schlechte Wahl, in meinem Fall aber möglich und das, was ich mit meinen Kenntnissen am besten umsetzen kann.

            So kann ich bei Bedarf auch mal von Hand den Wartungsmodus aktivieren und ohne Druck z.B. die Struktur verändern. Wobei man so etwas ja eh in die Nachtstunden legen würde. Da das Erstellen des Backups (derzeit) nur um die 0,16 Sekunden benötigt, ist es eher unwahrscheinlich, dass die Meldung überhaupt jemals erscheint.

            Gruß Nico