it-swarm.com.de

Wie dupliziere ich eine riesige Postgres-Tabelle?

Ich habe eine riesige Postgres-Tabelle (10 GB Daten - 160 Millionen Datensätze). Die Tabelle ist statisch und es werden keine Schreibvorgänge ausgeführt. Ich möchte es duplizieren, Schreibvorgänge ausführen, neu indizieren und dann mit einer einzigen schnellen Transaktion die alte löschen und die neue in den ursprünglichen Namen umbenennen.

Was ist der schnellste Weg, um solch eine riesige Tabelle zu duplizieren?

29
Milovan Zogovic

Im Allgemeinen ist der schnellste Weg, eine Tabelle zu duplizieren, einfach:

CREATE TABLE table2 AS SELECT * FROM table1;

Parallele INSERTs sind möglicherweise schneller, jedoch nur mit einem sehr schnellen Festplattensubsystem (wenn Daten auf vielen Laufwerken verschachtelt sind). Andernfalls ist dies langsamer.

Sobald Sie mit dem Ändern von table2 Fertig sind, kann es den neuen Namen annehmen mit:

BEGIN;
DROP TABLE table1;
ALTER TABLE table2 RENAME TO table1;
COMMIT;

Der Befehl DROP TABLE Benötigt eine exklusive Sperre, die sich auf gleichzeitige Leser auf eine Weise auswirkt, die Sie vielleicht vorhersehen möchten:

  • DROP wartet, bis alle ausstehenden Lesevorgänge anderer Transaktionen in der Tabelle abgeschlossen sind.
  • Jede neue Transaktion, die in der Zwischenzeit versucht, diese Tabelle zu lesen, wird gewartet und schlägt dann fehl, da das ursprüngliche table1 Nicht mehr vorhanden ist. Der Fehler würde so aussehen: "Beziehung mit OID oid konnte nicht geöffnet werden")

Um das zweite Problem zu vermeiden, können Sie table1 In old_table1 Umbenennen, anstatt es zu löschen, und es dann erst später außerhalb der Transaktion löschen, wenn diese Leser damit fertig sind. Die obige Sequenz würde also werden:

BEGIN;
ALTER TABLE table1 RENAME TO old_table1;
ALTER TABLE table2 RENAME TO table1;
COMMIT;
...
DROP TABLE old_table1;
55
Daniel Vérité