Kopieren von Daten von einer DB in eine andere DB

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

Hamburgo
Beiträge: 125
Registriert: Di 28. Mai 2019, 17:28

Hallo zusammen,

in den letzten Wochen habe ich so Einiges gelernt, u.a. wie man komplete
Tabellen-Schematas von einer DB in eine andere kopiert.

Unter SQL-Server gibt es auch ein Befehl mit man auch die Daten in einem
Rutsch von einer DB in eine andere kopieren/clonen kann (sogar mit samt
Tabelle-Schema, was ich ja nicht mehr brauche.).

Gibt es für FireBird auch so einen Befehl, rein für die Daten, sodass man nicht
jeden einzelnen Record manuell "pumpen" muss ?

Danke und viele Grüße
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Jein.
Den Create Table muss man leider selber ausführen, auch das Auslesen der DDL für die Create gestaltet sich eben schwierig.
Du kannst hal per External Table Daten in eine CSV ausgeben und in einer anderen DB wieder einlesen.
Allerdings dauert dies eben länger, als die direkte Verbindung.
Auch der SQL-Server macht das ja nicht von Hause aus.
Fall 1:
Der SQL-Server unterstützt native gleich mehrere DB's parallel.
Da die Syntax des SQL's komplett eben "database.schema.table" lautet, kann man den (nicht zum Standard) geheörenden "select into " verwenden, der von DB1 in DB2 kopiert.
Ist die DB auf einem anderen Server, benötigst du da auch den Linked-Server um die Tabelle zu kopieren. Allerdings muss die Tabelle vorher erstellt sein.
Beim SQL-Server kann man sich halt alle benötigten DDL's generieren lassen um dies zu tun.
Allerdings gibt es da sogar schnellere Methoden:
Export in CSV und Bulkload in die Ziel-DB. Per Bulkoperation können mehrere 10.000 Zeilen importiert werden, während Einzelinserts auch da nicht schneller sind als in die FB.

Und dann gibts da einen wesentlichen Unterschied:
Den SQL-Server musst du lizensieren und da bist du eben schnell mal bei meheren 10.000€. Da erwartet man halt auch ein wenig mehr.
Bei diesen Einnahmen kann man durchaus auch ein Heer von Entwicklern bezahlen, die nichts anderes machen.
Beim FB kann ich mich nicht erinnern jemals von €/$ gelesen zu haben.
Obwohl: du darfst da wohl auch spenden.

Trotz der vielen Entwickler hat aber der SQL-Server immer noch das Problem der Lock-Escalation (kennt die FB nicht).
Wenn du einen komplette Ladevorgang einer Tabelle mit mehreren Millionen Sätzen in ein Power-BI-Dokument mit Transaktion durchführst (um konistente Daten zu erhalten), kannst du während dieser Zeit keine Veränderungen an der Tabelle vornehmen bis dein Lesevorgang beendet ist.
Nicht dass die anderen etwa informiert werden. Nein, die anderen Transaktionen warten solange bis du mit dem Import fertig bist.
Das nenne ich mal eine Bevorzuung :lol:.
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Wenn du die Daten zeitnah auf dem Zielsystem haben möchtest, gäbe es noch die Replikation. Dann werden alle Daten aus dem Hauptsystem fast in Echtzeit (je nach Konfiguration) in das Ziel geschrieben. Man hat hier etwas Overhead und sinnigerweise sollten die Datenbanken im gleichen Netz liegen, da es sonst zu hohen Latenzen kommen kann.

Kommt eben auf die Bedürfnisse an.

Gruß
Martin
Martin Köditz
it & synergy GmbH
vr2
Beiträge: 214
Registriert: Fr 13. Apr 2018, 00:13

Hallo Hamburgo,

es gibt einige Möglichkeiten, Daten zwischen DBs zu transferieren.

- Tools wie bspw https://www.firebirdfaq.org/fbcopy.php
- Eine SP, die Daten mittels external execute statement kopiert und sich die Spaltentypen von der Zieltabelle besorgt (TYPE OF COLUMN)
- UDRs mit oder ohne batchAPI (FB4)
- Replikation (FB4) - hat Martin schon erwähnt

Grüße vr
Hamburgo
Beiträge: 125
Registriert: Di 28. Mai 2019, 17:28

Hallo zusammen,

Danke für die Antworten.

von FBcopy habe ich schon gelesen und ist der Grund, warum ich
hier bei Euch überhaupt nachgefragt habe, weil es demnach wohl
irgendwie geht.

Allerdings wird nach meiner Info das Projekt schon lange nicht
mehr gepflegt und ist wohl nur getestet bis FB 2.0. Das ist mir
zu heikel.

Ich bin bei FB 2.5 bzw. 3.0. Folglich sind FB 4.x Features für
mich noch nicht nutzbar.

Hintergrund des Ganzen ist das Update der DB für meine Waren-
Wirtschaft auf Kunden-Servern.

Ich weiss, die DB-Profis machen das mit SQL-Scripten, aber da
ich keiner bin, ist meine Lösung bisher folgende:

Von der Mutter-DB erstelle ich ein DB-Schema, sende das zum
Kunden und "pumpe" einfach die Bestands-Daten des Kunden
in das neue Schema.

Das läuft sein Jahren stabil und ich habe keinen Aufwand für
SQL-Scripte nach DB-Veränderungen.

Bei Kunden mit größeren Datenbestand ist diese Strategie aber
inzwischen zu langsam, weil zuviel Traffic zwischen Update-
Client und FB-Server.

Deshalb suche ich nach einer Möglichkeit die Daten rein server-
seitig von einer DB in die andere zu "pumpen" änlich wie:

Code: Alles auswählen

INSERT INTO table (fields)
     SELECT fields FROM tab_src ...
nur halt das die "tab_src" in einer anderen, der Live-DB des
Kunden, liegt.
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Wenn es nur darum geht, eine DB auf die neue Version zu bringen, kannst du ganz einfach gbak nutzen.
Mit dem 2.5er gbak sichern und dem 3.0er gbak restoren.
10GB in ca. 1 Stunde bei mir auf einem I7 mit 2.6 GHz.
Dabei wird eben alles mitgenommen was vorhanden ist, außer ein paar ganz wenigen Dingen, die in 3.0 nicht mehr erlaubt sind.
Ich mache übrigens in meiner Anwendung 1x die Woche einen Save/Restore automatisch um Journale und Versionen restlos zu entfernen. Dies bringt i.d.R. ca. 25% DB-Verkleinerung und 10% Performancezuwachs.
vr2
Beiträge: 214
Registriert: Fr 13. Apr 2018, 00:13

Hallo Hamburgo,

die letzten 3 von mir genannten Methoden sind rein serverseitig. Skripte sind übrigens nicht mehr das Mittel der Wahl, außer wenn es nicht anders geht, zb weil zwischen Quell- und Zielserver keine Netzwerkverbindung besteht. Du verlässt damit die DB-Ebene, transformierst sämtliche Daten in Textform und nachher wieder zurück. Das geht besser. Aber selbst dann wäre backup - restore eine Option, wie von bfuerchau vorgeschlagen. Damit überträgst Du natürlich auch die gesamte Struktur der QuellDB zum Zielserver.

Wenn das nicht gewünscht ist: Dein Codebeispiel entspricht meinem Vorschlag mit der external execute SP, das geht auch mit FB 25. Du brauchst zum Datenschaufeln eine einzige solche SP, die in der ZielDB deklariert ist und von dort die Daten aus der QuellDB ansaugt. Die agiert dann wie ein Client aus der Perspektive der QuellDB. Hier kommt es aber darauf an, ob zwischen dem Master- und dem Kundenserver die Verbindung brauchbar ist. Wawi kann zwar auch größer sein, aber normalerweise hast Du da keine mehrere GB an Daten, oder die machen irgendwas falsch, zb Rechnungen als pdfs in Blobfeldern der DB speichern. Wenn die Verbindung schlecht ist und backup-restore ok, kannst Du das backup zippen, das sind nochmal grob Faktor 10, dann ist der Transport weniger problematisch.

Was FB3 und FB4 angeht: auch wenn Du sagst, Du bist nicht der Profi, wenn Du bereits einen FB3 betreibst, ist der Schritt zu FB4 nicht groß. FB4 hat mehr noch als FB3 einige nützliche Konfigurationsschalter, die den Umgang mit Altanwendungen erleichtern, Du kannst einen FB4 auch mit alten Clients ansprechen, wenn er entsprechend konfiguriert ist. Aufpassen musst Du nur bei timestamps, da FB4 Zeitzonen eingeführt hat und sowas wie current_timestamp eine andere Bedeutung hat als vorher. Um das zu umgehen, müsstest Du in FB25 Vorkommen von currenrt_timestamp auf localtimestamp umstellen, ab FB 2.5.9 ist das möglich.

Ich würde aber versuchen, von FB25 wegzukommen, weil diese Version endgültig aus der Wartung raus ist und weil FB3 und FB4 reihenweise nützliche neue Features haben. Muss nicht hektisch passieren, wäre aber allmählich angesagt. Klar, es gibt noch kaum DB-Admintools, die FB4 vollständig unterstützen. Aber mit Flamerobin oder RedSoft kommst Du schon weit.

Wenn Du Hilfe bei der Umstellung brauchst, kann Dir hier sicher geholfen werden.

Grüße, Volker
Hamburgo
Beiträge: 125
Registriert: Di 28. Mai 2019, 17:28

@bfuerchau:

Vielleicht habe ich mich missverständlich ausgedrückt.

Es geht NICHT darum eine DB von einer älteren FB-Version in eine
neuere zu konvertieren.

Wie Du korrekt beschreibst, funktioniert das mit gbak problemlos.

Das habe ich, dank Eurer Unterstützung bei der Beseitung kleinerer Problemchen,
inzwischen gut im Griff.

Jetzt geht es aber darum den Bestands-Daten eines Kunden eine in Teilen neue/veränderte
DB-Struktur zu verpassen, z.B. neue komplette Tabellen oder modifizierte Felder in vorhandenen Tabellen, gelöschte Felder usw.

Die Version des FB-Servers ändert sich nicht.

Leider hat nach meinen Informationen aber gbak keinen Parameter, der entweder beim Export dafür sorgt,
dass nur die Daten gesichert werden oder beim Import dafür sorgt, dass die Daten in ein bereits vorhandenes DB-Schema/-Struktur importiert werden.

Das wäre genau das, was ich brauche, alte vorhandene Daten in eine neue/veränderte DB-Struktur zu übertragen.
Hamburgo
Beiträge: 125
Registriert: Di 28. Mai 2019, 17:28

@Volker:

Das mit der "external execute SP" hört sich sehr vielversprechend an. ;))

Allerdings habe ich null Ahnung von Stored Procedures, geschweige denn von "external"

Mir wäre sehr geholfen, wenn Du mir Muster-Codes für zwei Szenarien geben könntest.

1. Kopiere alle Daten-Sätze "aller" Spalten z.B. der Tabelle "Kunden" von Source-DB.

2. Kopiere aus allen Daten-Sätzen z.B. die Spalten Anrede, Vorname und Nachname aus Tabelle "Kunden"
von Source-DB in Tabelle "Alt_Kunden".

Aus diesen zwei Beipielen würde ich mir schon zutrauen alle Varianten, die ich dann wirklich
brauche Deine Muster anzupassen bzw. weiter zu entwickeln.

Speicher-Ort und Name der Source-DB sowie Admin-Name, -Password sind mir natürlich
bekannt bzw. kann ich auslesen.

Danke und viele Grüße
Hamburgo

p.s.: Der Vollständigkeit halber die Info, ich nutze unter PHP die FireBird- und die PDO-Extension,
was aber, so glaube ich, hier keine Rolle spielt oder ?
Zuletzt geändert von Hamburgo am Fr 8. Apr 2022, 12:06, insgesamt 1-mal geändert.
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Das heißt, du musst zwei Schritte berücksichtigen
1. Struktur in Ziel-DB anpassen
2. Neue und modifizierte Daten einspielen

Das wird mit gbak nicht funktionieren. Mit dem Schalter -M[ETA_DATA] kannst du angeben, ob du nur die Datenbankstruktur sichern bzw. wiederherstellen möchtest. Dann hättest du zumindest die Zielstruktur. Natürlich wäre die DB leer.
Zusätzlich gibt es den Schalter -SKIP_D[ATA], womit Tabellen ausgelassen werden können. Problem bleiben in jedem Falle die geänderten und neuen Daten. Dies geht nur über z.B. Prozeduren (siehe Volker) oder Drittanbieter-Tools.

Können die DBs netzwerktechnisch miteinander kommunizieren?

Gruß
Martin
Martin Köditz
it & synergy GmbH
Antworten