巨大なpostgresテーブルを複製するには?


29

巨大なpostgresテーブルがあります(10GBのデータ-160Mレコード)。テーブルは静的であり、実行された書き込み操作はありません。複製し、書き込みを実行し、インデックスを再作成し、単一の高速トランザクションで古いトランザクションを削除し、新しいトランザクションの名前を元の名前に変更したい。

このような巨大なテーブルを複製する最速の方法は何ですか?

回答:


55

一般的に、テーブルを複製する最も速い方法は単純です:

CREATE TABLE table2 AS SELECT * FROM table1;

並列INSERTはより高速かもしれませんが、非常に高速なディスクサブシステムを使用する場合のみです(多くのドライブでデータがインターリーブされる場合)。そうしないと、これは遅くなります。

変更が完了したら、次のtable2ようにして新しい名前を取得できます。

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

このDROP TABLEコマンドには排他ロックが必要です。これは、予想される方法で並行リーダーに影響を与えます。

  • DROP 他のトランザクションからのテーブルに対する保留中の読み取りが完了するのを待ちます。
  • その間にそのテーブルを読み取ろうとする新しいトランザクションは待機状態になり、元table1のテーブルが存在しないために失敗します。エラーは、「OIDでオープンできませんでした関係のようになります。OID

2番目の問題を回避するために、 これらのリーダーが処理を完了したら、ドロップtable1 するold_table1代わりにに名前を変更し、後でトランザクションの外部でのみドロップすることができます。したがって、上記のシーケンスは次のようになります。

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

2
ありがとう。これはまさに私が探していた種類の説明です。再度、感謝します!
ミロヴァンゾゴヴィッチ

table2に定義されたインデックスがある場合、テーブルの名前が変更されても機能しますか?
BamaPookie

1
@BamaPookieは、インデックス、制約、デフォルトを含む完全なスキーマについてこれを確認しますwiki.postgresql.org/wiki/Clone_schema
Timothy Vogel
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.