1

私は Ubuntu Linux 11 と Postgresql 9.1 を使用しています。私は CREATE TABLE .. SELECT を dblink で使用し、約 200 万行のテーブルを取得します。

ERROR:  out of memory
DETAIL:  Failed on request of size 432.

そのため、あるデータベースからテーブル全体の内容を取得し、(同じマシン上の) 別のデータベース内に挿入 (または作成) しています。Postgresql のデフォルト値を使用していますが、pgtune の値も試してみましたが、役に立ちませんでした。挿入中にメモリ使用量が増加していることがわかりますが、マシンの制限に達する前にエラーが発生します。ulimit -a 言う

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 30865
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 30865
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

create table as ... 同じデータベース内で選択すると、問題なく動作します。何か案は?

編集: postgresql.conf でさまざまなメモリ設定を調整しようとしましたが、役に立ちませんでした。私は何が欠けていますか?

4

1 に答える 1

0

これからの私の推測では、中間セットはメモリにのみ割り当てられており、それ自体を具体化することはできません。最善の選択肢は、回避策を見つけるか、dblink の担当者と協力してこの問題を解決することです。いくつかの潜在的な回避策は次のとおりです。

  1. COPY で csv ファイルを作成し、それをデータベースに挿入します。

  2. クエリをチャンクして、一度に 10 万行にします。

明確にするために、私の推測では、dblink は結果セットを割り当て、必要なメモリを割り当て、データを Postgresql に渡すことによって物事を処理します。これは、リクエストが dblink モジュール自体のメモリに完全に割り当てられていない可能性がある場合に、リクエストを迅速にプロキシ (およびネットワーク接続を介して転送) できるようにする方法で行われる可能性があります。

ただし、INSERT ... SELECT最初に結果セット全体をメモリに割り当ててから、それを処理して一度にテーブルに挿入しようとする場合があります。

ただし、これはコードの詳細なレビューがない直感です (dblink.c を開いてすばやくスキャンしました)。ここで覚えておく必要があるのは、PostgreSQL が他のサーバーに対する db クライアントとして、また db サーバー自体として同時に機能していることです。そのため、libpq とバックエンドの両方のメモリ ゴッチャが一緒になります。

編集:もう少しレビューした後、これはほとんど正しいようです。dblink は内部でカーソルを使用します。私の推測では、挿入前にカーソルからすべてがフェッチされているため、一度に実行できます。

于 2013-04-06T16:05:21.540 に答える