Jak zduplikować ogromną tabelę postgres?

29

Mam ogromną tabelę postgres (10 GB danych - 160 mln rekordów). Tabela jest statyczna i nie wykonuje się na niej żadnych operacji zapisu. Chcę go zduplikować, wykonać zapisy, ponownie zindeksować, a następnie za pomocą jednej szybkiej transakcji usunąć starą i zmienić nazwę nowej na pierwotną.

Jaki jest najszybszy sposób na zduplikowanie tak dużego stołu?

Milovan Zogovic
źródło

Odpowiedzi:

55

Zasadniczo najszybszym sposobem na zduplikowanie tabeli jest po prostu:

CREATE TABLE table2 AS SELECT * FROM table1;

Równoległe WSTAWKI mogą być szybsze, ale tylko z bardzo szybkim podsystemem dyskowym (gdy dane są przeplatane na wielu dyskach). W przeciwnym razie będzie to wolniejsze.

Po zakończeniu modyfikacji table2może przyjąć nową nazwę z:

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

DROP TABLEKomenda musi wyłączną blokadę, która wpływa współbieżnych czytelników w sposób może chcesz przewidywać:

  • DROP będzie czekać na zakończenie wszelkich oczekujących odczytów na stole z innych transakcji.
  • Każda nowa transakcja próbująca w międzyczasie odczytać tę tabelę, spowoduje, że będzie czekać, a następnie zawiedzie, ponieważ oryginał table1już nie istnieje. Błąd wyglądałby tak: „nie można otworzyć relacji z OID oid

Aby uniknąć drugiego problemu, możesz zmienić nazwę table1 na old_table1 zamiast go upuszczać, a następnie upuścić dopiero później poza transakcją, gdy czytniki te skończą. Tak więc powyższa sekwencja wyglądałaby następująco:

BEGIN;
ALTER TABLE table1 RENAME TO old_table1;
ALTER TABLE table2 RENAME TO table1;
COMMIT;
...
DROP TABLE old_table1;
Daniel Vérité
źródło
2
Dzięki stary. Właśnie takiego wyjaśnienia szukałem. Dzięki jeszcze raz!
Milovan Zogovic,
Jeśli w tabeli 2 zdefiniowano indeksy, czy będą one nadal działać po zmianie nazwy tabeli?
BamaPookie,
1
@BamaPookie sprawdź to, aby uzyskać pełny schemat, w tym indeksy, ograniczenia i wartości domyślne wiki.postgresql.org/wiki/Clone_schema
Timothy Vogel