Linuchs: DB1 nach DB2 kopieren

Moin,

im Rahmen einer Datensicherung habe ich Tabellen von Server A (myexample.com) nach Server B (dyexample.com) zu kopieren.

Ich nehme an, in einem SQL-Kommando geht das nicht?

Oder kann eine Datenbank per SQL direkt Kontakt zu einer anderen Datenbank aufnehmen?

Bisher hatte ich das recht umständlich gemacht mit Hilfsprogrammen auf den Servern, die dann eine CSV-Datei miteinander austauschten. Wie geht es einfacher?

Linuchs

  1. Tach!

    im Rahmen einer Datensicherung habe ich Tabellen von Server A (myexample.com) nach Server B (dyexample.com) zu kopieren.

    Ich nehme an, in einem SQL-Kommando geht das nicht?

    Nicht direkt.

    Oder kann eine Datenbank per SQL direkt Kontakt zu einer anderen Datenbank aufnehmen?

    Es gibt die FEDERATED Storage Engine, die kann anderen Server kontaktieren und das sieht dann aus, als ob das im eigenen wäre.

    Bisher hatte ich das recht umständlich gemacht mit Hilfsprogrammen auf den Servern, die dann eine CSV-Datei miteinander austauschten. Wie geht es einfacher?

    Mit mysqldump zum Exportieren und mysql (Kommandozeilenprogramm) zum Importieren.

    dedlfix.

    1. Versuch:

    Auf dem remote-Server erstelle ich eine temporäre Tabelle mit den Einträgen, die einen Mandanten betreffen.

    DROP TABLE IF EXISTS tmp;
    
    CREATE  TABLE tmp
    SELECT  *
    FROM    stammsaetze
    WHERE   owner_id = 15;
    

    Nun lese ich die Einträge dieser remote Tabelle und fülle sie einzeln in die zugehörige lokale Tabelle. Ca. 15.000 Datensätze = 15.000 SQL-Kommandos.

    Irgendwie nicht so prickelnd, aber ich schaue mal nach der Durchlaufzeit ...

    Linuchs

    1. Tach!

      CREATE  TABLE tmp
      SELECT  *
      FROM    stammsaetze
      WHERE   owner_id = 15;
      

      Nun lese ich die Einträge dieser remote Tabelle und fülle sie einzeln in die zugehörige lokale Tabelle. Ca. 15.000 Datensätze = 15.000 SQL-Kommandos.

      Hmm? Wenn du das WHERE weglässt, ist das Erstellen und befüllen doch nur ein Kommando für die ganze Tabelle.

      dedlfix.

      1. CREATE  TABLE tmp
        SELECT  *
        FROM    stammsaetze
        WHERE   owner_id = 15;
        

        Hmm? Wenn du das WHERE weglässt, ist das Erstellen und befüllen doch nur ein Kommando für die ganze Tabelle.

        Die Datensicherung erfolgt für einen bestimmten Mandanten (owner_id). Ist doch klar, der Mandant darf nicht die Datensicherung für andere Mandanten machen.

        Auf dem lokalen Server lösche ich nun Tabelle für Tabelle die Einträge des Mandanten und INSERT sie neu aus den remote temporären Tabellen. Klingt vielleicht kompliziert, aber wie sollte ich sonst "gelöschte Sätze" (die remote nicht mehr vorhanden sind) nach lokal übertragen?

        Ist das, was ich da mache, denn so ungewöhnlich? Bei mandantenfähiger Software ist das doch Normalität ...

        Linuchs

        1. Tach!

          Ist das, was ich da mache, denn so ungewöhnlich? Bei mandantenfähiger Software ist das doch Normalität ...

          Ich kann nur aus den Informationen was machen, die in der Fragestellung erwähnt sind. Dass sich die 15000 Datensätze auf etwas anderes beziehen, ging daraus nicht hervor. Dein Tun in dieser Angelegenheit kann ich nicht bewerten, dazu fehlt mir das Wissen um dein System.

          dedlfix.

          1. Moin,

            Ich kann nur aus den Informationen was machen, die in der Fragestellung erwähnt sind.

            Logisch. Es geht um ein Programm, das lokale (linke Seite) und remote Tabellen (rechte Seite) mit gleichem Namen gegenüberstellt. Wenn die Satz-Anzahl oder das größte last_modified differiert, kann eine Checkbox aktiviert werden, um diese lokale Tabelle für diesen Mandanten zu aktualisieren: Bildbeschreibung

            In einer Programm-Schleife werden nun die angeforderten Tabellen durchlaufen. Im aktuellen Beispiel sind es nur zwei, aber es sollen ein dutzend werden. Für jede Tabelle gilt:

            1. remote temporäre Tabelle löschen,
            2. remote temporäre Tabelle mit den Daten des Mandanten füllen,
            3. remote temporäre Tabelle lesen,
            4. Mandant aus lokaler Tabelle löschen,
            5. lokale Tabelle mit Daten aus der remote temporären Tabelle füllen (15.000).

            Die Felder sind identisch. Wie kann das SQL-Kommando aussehen, ohne die Felder zu nennen? Denn die sind ja von Tabelle zu Tabelle unterschiedlich.

            Linuchs

            1. Tach!

              Die Felder sind identisch. Wie kann das SQL-Kommando aussehen, ohne die Felder zu nennen? Denn die sind ja von Tabelle zu Tabelle unterschiedlich.

              So wie du es schon gemacht hast, CREATE ... SELECT oder INSERT ... SELECT, je nachdem ob die Tabelle schon existiert oder nicht. Aber wo die 15000 Statements herkommen, sehe ich nicht. Es ist immer nur eins pro Tabelle.

              dedlfix.

              1. Die Felder sind identisch. Wie kann das SQL-Kommando aussehen, ohne die Felder zu nennen? Denn die sind ja von Tabelle zu Tabelle unterschiedlich.

                So wie du es schon gemacht hast, CREATE ... SELECT oder INSERT ... SELECT, je nachdem ob die Tabelle schon existiert oder nicht.

                Ja, bisher habe ich es manuell gemacht mit phpmyadmin. Das Verfahren soll nun programmgesteuert vom Mandanten selbst erledigt werden. Mein SQL für phpmyadmin:

                # remote
                DROP TABLE IF EXISTS `T_M_3_eventbuchungen`;
                CREATE TABLE T_M_3_eventbuchungen SELECT * FROM bfp_eventbuchungen WHERE owner_id = 15;
                
                # local
                DELETE FROM tm_eventbuchungen         WHERE owner_id=15;
                
                #2016-05-18 11:25
                INSERT INTO `tm_eventbuchungen` (`id`, `owner_id`, `wunsch_event_id`, `prio_1`, `prio_2`, `gebuchte_event_id`, `adress_id`, `gruppen_id`, `von_slot_nr`, `bis_slot_nr`, `loe_kz`, `last_modified`) VALUES
                (37611, 15, 554, 0, 1, 0, 19068, 0, 0, 0, 0, '2016-04-27 14:41:57'),
                (37621, 15, 604, 0, 1, 0, 19068, 0, 0, 0, 0, '2016-05-17 16:03:19'),
                ...
                

                Habe die temporären Dateien manuell mit phpmyadmin exportiert, in meinen Editor geschrieben und local wieder mit INSERT eingefügt.

                Aber wo die 15000 Statements herkommen, sehe ich nicht. Es ist immer nur eins pro Tabelle.

                Ja gerne, wie bekomme ich die 15.000 remote-Sätze als "eins" in die lokale Tabelle?

                Linuchs

                1. Tach!

                  Die Felder sind identisch. Wie kann das SQL-Kommando aussehen, ohne die Felder zu nennen? Denn die sind ja von Tabelle zu Tabelle unterschiedlich.

                  So wie du es schon gemacht hast, CREATE ... SELECT oder INSERT ... SELECT, je nachdem ob die Tabelle schon existiert oder nicht.

                  Ja, bisher habe ich es manuell gemacht mit phpmyadmin. Das Verfahren soll nun programmgesteuert vom Mandanten selbst erledigt werden. Mein SQL für phpmyadmin:

                  Ich meinte, so wie du es vorhin im Thread gezeigt hast. "CREATE ... SELECT" ist die Kombination aus CREATE und SELECT. Und es gibt auch die Kombination von INSERT und SELECT.

                  Ja gerne, wie bekomme ich die 15.000 remote-Sätze als "eins" in die lokale Tabelle?

                  Solange du ein SELECT-Statement formulieren kannst, das alle gewünschten Datensätze liefert, kannst du es mit INSERT kombinieren und hast ein Kopieren in einem Zug.

                  dedlfix.

                  1. Solange du ein SELECT-Statement formulieren kannst, das alle gewünschten Datensätze liefert, kannst du es mit INSERT kombinieren und hast ein Kopieren in einem Zug.

                    Ähh - wie? Die Kombination SELECT bei Domain A und INSERT bei Domain B ist doch in einem SQL-Kommando nicht möglich. Ich habe doch zwei conn_id.

                    Linuchs

                    1. Tach!

                      Ähh - wie? Die Kombination SELECT bei Domain A und INSERT bei Domain B ist doch in einem SQL-Kommando nicht möglich. Ich habe doch zwei conn_id.

                      In meiner ersten Antwort erwähnte ich die Federated Engine. Dazu hast du nichts weiter gesagt. Du hast dann aber ein Create-Select verwendet und so nahm ich an, dass du nun damit arbeitest. Anscheinend war das dann aber doch nur auf demselben Server. Wenn du die Server nicht auf diese Weise verbinden kannst, dann geht es nur über Dumps oder Einzelstatements oder mehr oder weniger einzelnen Multi-Insert-Statements.

                      dedlfix.

                      1. Hallo,

                        In meiner ersten Antwort erwähnte ich die Federated Engine. Dazu hast du nichts weiter gesagt.

                        Ich war etwas in Zeitnot, nicht offen für neue Techniken. Danke für den Tipp. Muss mich ohnehin mal mit mysqli beschäftigen, weil mysql wohl auf der Abschussliste steht.

                        Ist die Federated Engine mit phpmyadmin nutzbar?

                        Du hast dann aber ein Create-Select verwendet und so nahm ich an, dass du nun damit arbeitest. Anscheinend war das dann aber doch nur auf demselben Server.

                        Richtig, mit phpmyadmin.

                        ... Einzelstatements oder mehr oder weniger einzelnen Multi-Insert-Statements.

                        Ich war ja gestern sehr überrascht, dass 15.000 Datensätze in 3,7 sec kopiert wurden. Damit bin ich erstmal mehr als zufrieden.

                        Linuchs

                        1. Hi,

                          Ist die Federated Engine mit phpmyadmin nutzbar?

                          so wie ich dedlfix verstanden habe, ist es eine Tabellen-Engine wie jede andere auch. Sie sitzt logisch gesehen zwischen dem DBMS und der eigentlichen Datenbankdatei, also an einer Schnittstelle, die PMA gar nicht sieht. Also funktioniert das völlig transparent, nur wahrscheinlich deutlich langsamer als eine lokale DB.

                          So long,
                           Martin

                          --
                          Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
                          - Douglas Adams, The Hitchhiker's Guide To The Galaxy
                        2. Tach!

                          Ist die Federated Engine mit phpmyadmin nutzbar?

                          Bei der Federated Engine wird der andere Server so eingebettet, als seien es eigene Datenbanken/Tabellen. Ein phpMyAdmin hat keinen Grund, da einen Fremdkörper zu entdecken, mit dem er nicht arbeiten möchte.

                          dedlfix.

  2. Nochmal nachgefragt:

    Mit einem PHP-Programm möchte ich tausende von Datensätzen aus mehreren remote Tabellen exportieren und in gleichartige lokale Tabellen importieren. Die korrespondierenden remote / lokal Tabellen haben denselben Aufbau. Muss ich da wirklich jeden Satz einzeln anfassen?

    Falls ja, ist es wenigstens möglich, die INSERTs zu machen ohne die Feldnamen (colomns) aufzuzählen?

    # remote Tabelle
    SELECT  *
    FROM    bfp_eventbuchungen
    WHERE   owner_id = 15;
    ...
    
    while ...
      $row = mysql_fetch_array()
    
    # lokale Tabelle
    INSERT $row ???
    INTO    tm_eventbuchungen
    

    Linuchs

    1. Hatte endlich die richtige Idee und wundere mich, dass die Übertragung von 15.000 Datensätzen nur 3,7 sec dauert.

      Die Feldnamen entnehme ich der $row:

      $keys = '';
      $row = mysql_fetch_assoc( $res_remote );  // erster Datensatz, um keys zu bekommen
      foreach ( $row AS $key => $val ) {
        $keys .=  $key.",";
      }
      $keys = trim( $keys, "," ); // letztes Komma entfernen
      echo $keys."<br>";
      mysql_data_seek($res_remote,0);
      

      $vals generiere ich pro Satz entsprechend und das gibt

      INSERT
      INTO   tm_kontakte
      ( id,owner_id,gruppen_id,besucher_id,prioritaet_tln,tel_kz,bemerkung,aussteller_id,aussteller2_id,prioritaet_aus,prio_1,prio_2,prio_3,slot_nr,storno_slot,storno_zeit,storno_grund,loe_kz,last_modified )
      VALUES
      ( '263423','15','0','18772','0','','','18747','0','0','0','0','1','0','0','','','0','2016-04-26 11:23:36' )
      

      Linuchs