mm100: Daten aus mysql im Netz abholen.

Hallo,

ich habe eine lokalen Webserver mit mysql und mysql bei meinem Hoster.
Ich möchte nun hin und wieder die neuesten Daten aus der Datenbank im Netz abholen und in meine lokale DB speichern (synchronisieren).

Wie gehe ich am besten vor?
Vorab, es sind keine riesen Datenmengen, die da zu snchronisieren sind.

Ein Ansatz wäre:
ein lokales Script ruft ein Script im Netz das die Daten ausliest und die Datensätze z.B in CSV darstellt.
Das lokale Script liest die Daten und schiebt sie in die Datenbank.
Klingt einfach, aber irgendwie gefällt mir das nicht.

Was wäre eine elegantere Lösung?

Vor Allem - um nicht jedesmal die ganze DB im Netz lesen zu müssen, müsste ds netzseitige Script in der DB einen Flag setzen.
Was aber, wenn die Übertragung nicht klappt?
Der Flag wäre gesetzt und die Datensätze könnten nicht mehr geholt werden.

????

Wie macht man sowas professionell?

  1. Guten Tag.

    Ich möchte nun hin und wieder die neuesten Daten aus der Datenbank im Netz abholen und in meine lokale DB speichern (synchronisieren).

    Wie gehe ich am besten vor?

    ein lokales Script ruft ein Script im Netz das die Daten ausliest und die Datensätze z.B in CSV darstellt.
    Das lokale Script liest die Daten und schiebt sie in die Datenbank.
    Klingt einfach, aber irgendwie gefällt mir das nicht.

    Warum nicht? Verursacht es dir Blähungen oder was steckt hinter "irgendwie"?

    Vor Allem - um nicht jedesmal die ganze DB im Netz lesen zu müssen, müsste ds netzseitige Script in der DB einen Flag setzen.
    Was aber, wenn die Übertragung nicht klappt?
    Der Flag wäre gesetzt und die Datensätze könnten nicht mehr geholt werden.

    Du solltest eine Aktion auch nicht als erfolgreich beendet kennzeichen, wenn noch gar nicht klar ist, dass die Aktion erfolgreich beendet wurde. Übertrage die Daten, prüfe deren Stimmigkeit und melde erst dann dem Server den Erfolg.

    Eine bessere Alternative: MySQL bietet (wie auch andere Datenbanken) dir die Möglichkeit, jeden Datensatz mit einem Zeitstempel zu versehen. In dieser Spalte vom Typ timestamp wird von der Datenbank bei Neuanlage und auch jeder Änderung automatisch die aktuelle Zeit eingetragen.
    Eine einfache, aufbauende Synchronisation bräuchte lediglich den Zeitpunkt der letzten Änderung in beiden Datenbanken (lokal und Server, letzterer kleiner now(), um in dieser Sekunde noch hinzukommende Änderungen auszuschließen) abfragen und anschließend alle Datensätze zwischen den beiden Zeitpunkten auslesen (… where stamp > lokal and stamp <= Server).

    Gravierender Nachteil bei beiden Ansätzen: Gelöschte Datensätze werden übersehen, denn sie existieren ja nicht mehr, haben also auch kein Merkmal, das sich vergleichen ließe und dann wild winkt "Ich muss weg!".
    Du wirst entweder das Löschen verbieten und gelöschte Datensätze anderweitig als gelöscht kennzeichnen müssen, damit sie den normalen Betrieb nicht stören, oder eine separate Tabelle führen müssen, in der Hinweise auf gelöschte Datensätze abgelegt werden. Trägst du in letzterer Tabelle sämtliche Änderungen ein, könntest du auch auf die zusätzliche timestamp-Spalte bei den Datensätzen verzichten.

    Ob sich dieser Aufwand gegenüber einer simplen Komplettkopie der Datenbank lohnt, musst du selbst abschätzen. Du schriebst davon, dass es keine Riesenmengen wären; ich täte dann zur Komplettkopie tendieren, zumal sowas mit gzip oder bz2 komprimiert bisweilen erstaunlich in sich zusammenschrumpft und entsprechend ratzfatz übertragen ist.

    Wie macht man sowas professionell?

    Ach, "professionell" … wenn irgendwo "professionell" draufsteht, kannst du davon ausgehen, dass da ganz grausiger Murks drinsteckt :->

  2. Ich möchte nun hin und wieder die neuesten Daten aus der Datenbank im Netz abholen und in meine lokale DB speichern (synchronisieren).

    Moin!

    (Achte nach den Klicks auf die Links zur MySQL-Doc auf die richtige Version!)

    Ist denn der MySQL-Server über das Netz erreichbar? Das ist nicht bei allen Hostern so - bei vielen eher gar nicht.

    Profis machen derlei, in dem diese den Server replizieren. Ich fürchte aber, dieses wird bei Dir nicht möglich sein.

    Die Holper-Stolper-Lösung für Linux/Unixoide

    Also: Datenbank -> dump.neu
    diff --from-file=dump.alt --to-file=dump.neu > dump.diff -> diese abholen.
    rm dump.alt
    mv dump.neu dump.alt

    @home:

    patch dump.old dump.diff > dump.neu
    *edit dump.neu*
    dump.neu -> datenbank
    rm dump.alt
    mv dump.neu dump.alt

    *edit dump.neu* :

    Variante 1)
    sind es viele neue/geänderte Datensätze, dann eventuell Indizierung in der dump.neu abschalten, alle Daten löschen, alle neu einlesen, Indizierung neu starten.

    sind die neuen, geänderten Daten in der Minderzahl und ist die Datenbank klug indiziert:

    http://dev.mysql.com/doc/refman/5.1/de/insert-on-duplicate.html

    Jörg Reinholz

    1. Ferdinand hat nicht ganz unrecht. Es geht auch mit Logfiles. Aber auf die musst Du Zugriff haben.

      https://dev.mysql.com/doc/refman/5.1/de/query-log.html

      oder durch Deine Skripte alle Änderungen als Log in einer Textdatei aufzeichnen.
      (die aber vor dem Abholen umbenennen!)

      also
      <?php
      $sql="Foo Bar Baz";

      Log this:

      file_put_contents('mysql_logfile.dat', $sql, FILE_APPEND | LOCK_EX);
      mysql_query($sql); # oder besser
      ?>

      abholen:
      ssh user@server "mv mysql_logfile.dat mysql_logfile.txt && cat mysql_logfile.txt" > mysql_logfile.txt

      Das ggf. noch mit regex (sed s///) bearbeiten und an die Datenbank senden.

  3. Hello,

    darfst Du den Datenbankserver starten und stoppen?
    Kommst Du an die Datenfiles der Datenbank direkt heran?

    Die sicherste Möglichkeit wäre dann:
    Datenbank disable Login, bestehende Connections "kappen"
    Datenbank flush buffers
    Datenbanserver runterfahren.

    Tabellen komplett in ein anderes Verzeichnis kopieren, möglichst Host-Intern.

    Datenbankserver wieder hochfahren.

    Sicherungsverzeichnis mit targz behandeln, das schrumpt dann enorm.
    Tabellen runterladen und beim Backupserver wieder auspacken und montieren
    Backupserver starten, alles wundrbar!
    Den darfst Du dann aber auch nur lesender Weise benutzen.

    Das nennt sich dann Vollsicherung.

    Das Problem bei dieser ganzen Backuperei ist immer die Erhaltung der refenziellen Integrität und der Datenkonsostenz. Während Du sichserst, darf keiner weitere Veränderungen an der Datenbank vornehmen.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bikers-lodge.com
  4. Tach!

    ich habe eine lokalen Webserver mit mysql und mysql bei meinem Hoster.
    Ich möchte nun hin und wieder die neuesten Daten aus der Datenbank im Netz abholen und in meine lokale DB speichern (synchronisieren).

    Für den Hausgebrauch könnte die Funktion "Gleiche ab" im phpMyAdmin helfen. Allerdings muss dieser dazu zu beiden Systemen eine Verbindung aufbauen können. Das ist vermutlich in deiner Konstellation nicht möglich, weil man ungern Datenbankports aus dem Internet erreichbar offen lässt.

    Vorab, es sind keine riesen Datenmengen, die da zu snchronisieren sind.

    Dann Export und Import.

    Vor Allem - um nicht jedesmal die ganze DB im Netz lesen zu müssen,

    Von welcher Datenmenge sprechen wir denn überhaupt?

    Wie macht man sowas professionell?

    Da herrschen vermutlich ganz andere Anforderungen und man nimmt die im DBMS vorhandene Replikation. Geht ebenfalls bei nicht bei dir, wenn sich die Server nicht sehen und du auch keinen administrativen Zugang zu beiden hast.

    dedlfix.

    1. Nein, ich kann nicht direkt auf die Datenbank zugreifen.
      Ich kann lediglich ein Script beim Hoster anschupsen, das die Daten ausliest.

      Das wäre auch nicht das Problem.
      Die Frage ist eigentlich, wie kriege ich die Daten elegant übertragen.

      Ich hatte mir das so gedacht:

      lokales Script ruft das Script im Netz
      Das netzseitige Script liest die Datenbank und formatiert die Daten z.B im CSV Format und antwortet, indem die Datensätze mit print dargestellt werden.

      Das lokale Script kann das lesen und in die lokale DB schieben.

      Nach getaner Arbeit wird ein weiteres Script im Netz angeschubst, das den gelesen Flag setzt.

      1. Hello,

        Nein, ich kann nicht direkt auf die Datenbank zugreifen.
        Ich kann lediglich ein Script beim Hoster anschupsen, das die Daten ausliest.

        Wie lautet der Name des Scriptes? Ist es oder beinhaltet es ein original MySQL-Script?

        Die Frage ist eigentlich, wie kriege ich die Daten elegant übertragen.

        Wenn Du den Server nicht runterfahen kannst, dann:

        * Lock Tables (entsprechende Priviledges erforderlich)
        * Flush Buffers

        * Dump der Tabellen in ein separatens Verzeichnis
          ggf. inclusive Create-Tables und Insert-Statements

        * targz

        * Lock freigeben

        * Authorisierten Download aus dem Sicherungsverzeichnis durchführen.
          Scriptlaufzeit muss lang genug sein.

        ** Rest kannst Du auf dem Client experimentell erforschen.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bikers-lodge.com
      2. Tach!

        lokales Script ruft das Script im Netz
        Das netzseitige Script liest die Datenbank und formatiert die Daten z.B im CSV Format und antwortet, indem die Datensätze mit print dargestellt werden.

        Serialisieren wäre einfacher. Wenn die Datenmenge überschaubar ist, dann würde ich ein Array mit den Datensatz-Arrays als Elementen aufbauen, das Ding serialisieren und übertragen.

        Das lokale Script kann das lesen und in die lokale DB schieben.
        Nach getaner Arbeit wird ein weiteres Script im Netz angeschubst, das den gelesen Flag setzt.

        Das mag für einfache Fälle gehen, bei denen zum Synchronisationszeitpunkt kein Betrieb herrscht. Sonst hast du zwischendrin Änderungen, die unberücksichtigt bleiben. Wenn es komplexer und sicherer sein darf, dann kann der Slave von seinen Datensätzen ID und Zeitstempel (oder einen anderen eindeutigen Wert) hinsenden und der Master sendet alles was hinzugefügt wurde, zudem das wo ID und Zeitstempel nicht übereinstimmen und außerdem die im Gegensatz zum Slave nicht mehr vorhandenen ID. Das sind also Creates, Changes und Deletes. Diese drei liest du dann auf dem Slave ein und es ist keine Änderung oder Markierung auf dem Master notwendig.

        Aber mal was anderes, mit solch einem Anliegen bist du ja nicht der erste. Hast du mal geschaut, was für Synchronisationstools es bereits gibt?

        dedlfix.