Postgres-Dump von nur Teilen von Tabellen für einen Dev-Snapshot

95

In der Produktion ist unsere Datenbank einige hundert Gigabyte groß. Für die Entwicklung und das Testen müssen wir Snapshots dieser Datenbank erstellen, die funktional gleichwertig sind, aber nur 10 oder 20 Gigs groß sind.

Die Herausforderung besteht darin, dass die Daten für unsere Geschäftseinheiten auf viele Tabellen verteilt sind. Wir möchten eine Art gefilterten Snapshot erstellen, damit nur einige der Entitäten im Dump enthalten sind. Auf diese Weise können wir jeden Monat neue Schnappschüsse für Entwickler und Tests erhalten.

Angenommen, wir haben Entitäten mit diesen vielen-zu-vielen-Beziehungen:

  • Das Unternehmen hat N Abteilungen
  • Abteilung hat N Mitarbeiter
  • Mitarbeiter hat N Anwesenheitslisten

Es gibt vielleicht 1000 Unternehmen, 2500 Abteilungen, 175000 Mitarbeiter und zig Millionen Anwesenheitslisten. Wir möchten eine reproduzierbare Methode, um beispielsweise die ersten 100 Unternehmen und alle ihre Unternehmensbereiche, Mitarbeiter und Anwesenheitslisten abzurufen .

Derzeit verwenden wir pg_dump für das Schema und führen dann pg_dump mit --disable-triggers und --data-only aus, um alle Daten aus den kleineren Tabellen abzurufen. Wir möchten keine benutzerdefinierten Skripte schreiben müssen, um einen Teil der Daten abzurufen, da wir einen schnellen Entwicklungszyklus haben und befürchten, dass die benutzerdefinierten Skripte fragil und wahrscheinlich veraltet sind.

Wie können wir das machen? Gibt es Tools von Drittanbietern, mit denen logische Partitionen aus der Datenbank abgerufen werden können? Wie heißen diese Tools?

Jeder allgemeine Rat auch geschätzt!

Jonathan Peterson
quelle

Antworten:

108

In Ihren größeren Tabellen können Sie den Befehl COPY verwenden, um Teilmengen abzurufen ...

COPY (SELECT * FROM mytable WHERE ...) TO '/tmp/myfile.tsv'

COPY mytable FROM 'myfile.tsv'

https://www.postgresql.org/docs/current/static/sql-copy.html

Sie sollten in Betracht ziehen, eine Reihe von Entwicklungsdaten zu verwalten, anstatt nur eine Teilmenge Ihrer Produktion abzurufen. Wenn Sie Komponententests schreiben, können Sie dieselben Daten verwenden, die für die Tests erforderlich sind, und versuchen, alle möglichen Anwendungsfälle zu ermitteln.

Ben
quelle
Ich habe diese Technik mit großem Erfolg eingesetzt, um das Gleiche wie beim OP zu tun. Für Testläufe habe ich COPY (SELECT ..) TO .. ​​-beschränkte Daten in eine "Template" -Datenbank geladen und CREATE DATABASE test_run_XX TEMPLATE product_snapshot_XX verwendet. Ich habe die Daten natürlich auf ein Minimum reduziert, damit der geladene Produkt-Snapshot und die Test-DB-Erstellungsvorgänge schnell genug sind, um kein Hindernis für das Team zu sein.
Trey
5
Gibt es eine Möglichkeit, dies zum Laufen zu bringen, wenn Sie mehrere verknüpfte Tabellen haben, von denen Sie Snapshots möchten? COPY FROM unterstützt nicht das Importieren mehrerer Tabellen.
mlissner
1
Du bist der Mann ... Das macht es mir so einfach, aber für einen anderen Zweck. Ich habe es verwendet, um Daten aus dem öffentlichen Schema in ein benutzerspezifisches Schema in einer mandantenfähigen App zu verschieben. Vielen Dank !
Jeremy F.
5
Beachten Sie, dass diese Methode keine Sequenzen in den kopierten Tabellen aktualisiert, sodass weitere Einfügungen möglicherweise die Einschränkungen des Primärschlüssels verletzen.
user2859458
1
Ich musste \copystattdessen COPYauch verwenden, da letzteres nur für Superuser gedacht war. Zum Glück hat alles andere perfekt funktioniert, ohne dass in 9.1 weitere Änderungen vorgenommen wurden.
PJSCopeland
8

Ich kenne keine Software, die dies bereits tut, aber ich kann mir 3 alternative Lösungen vorstellen. Leider erfordern alle eine benutzerdefinierte Codierung.

  1. Erstellen Sie alle Tabellen in einem separaten Schema neu und kopieren Sie dann nur die Teilmenge der Daten, die Sie sichern möchten, in diese Tabellen. Verwenden Sie diese INSERT INTO copy.tablename SELECT * FROM tablename WHERE ...und geben Sie sie aus.

  2. Schreiben Sie Ihr eigenes Skript zum Speichern von Daten als SQL-Anweisungen. Ich habe diesen Ansatz in der Vergangenheit verwendet und es dauerte nur etwa 20-30 Zeilen PHP.

  3. Ändern Sie pg_dump so, dass beim Speichern einer einzelnen Tabelle eine Bedingung zusammen mit dem Schalter -t akzeptiert wird.

Aleksander Kmetec
quelle
6

http://jailer.sourceforge.net/ macht das.

Paul Legato
quelle
12
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert.
Talonmies
3
Das macht hier keinen Sinn. Das OP fragte speziell nach den Namen der Tools von Drittanbietern, die dies tun. Das Wesentliche der Antwort ist daher nur: "Es gibt ein Drittanbieter-Tool namens 'Jailer', das dies unter dieser URL tut." Dieser Link selbst enthält alle wichtigen Informationen. es gibt nichts anderes hinzuzufügen. Wenn dieser Link nicht mehr funktioniert, kann aus der URL leicht abgeleitet werden, dass "das Programm Jailer heißt". Es wäre also überflüssig, dies hinzuzufügen.
Paul Legato
2
Natürlich ist der Link jetzt kaputt und Google zeigt keine Alternative.
Owensmartin
1
Der Link funktioniert derzeit für mich und das Googeln für "Jailer Postgres" ist auch auf github.com/Wisser/Jailer aufgetaucht .
Paul Legato
8
Wenn Sie eine hilfreiche Beschreibung howIhrer Verwendung dieses Tools hinzugefügt haben , können wir möglicherweise verstehen, wie es das Ziel erreicht
Bryan Ash