7

私のセットアップでは、大きなcsvファイルをテーブルにロードしようとするとPostgreSQL9.2.2がエラーになるようです。

csvファイルのサイズは約9GBです

一括読み込みに使用しているSQLステートメントは次のとおりです。

copy chunksBase (chunkId, Id, chunk, chunkType) from path-to-csv.csv' delimiters ',' csv

数分後に発生するエラーは次のとおりです。

pg.ProgrammingError: ERROR:  out of memory
DETAIL:  Cannot enlarge string buffer containing 1073723635 bytes by 65536 more bytes.
CONTEXT:  COPY chunksbase, line 47680536

バッファは正確に1GBを超えて割り当てることはできないと思います。これは、postgresql.confの問題である可能性があると思います。

postgresql.confのコメントされていない行は次のとおりです。

bash-3.2# cat postgresql.conf | perl -pe 's/^[ \t]*//' | grep -v '^#' | sed '/^$/d'
log_timezone = 'US/Central'
datestyle = 'iso, mdy'
timezone = 'US/Central'
lc_messages = 'en_US.UTF-8'         # locale for system error message
lc_monetary = 'en_US.UTF-8'         # locale for monetary formatting
lc_numeric = 'en_US.UTF-8'          # locale for number formatting
lc_time = 'en_US.UTF-8'             # locale for time formatting
default_text_search_config = 'pg_catalog.english'
default_statistics_target = 50 # pgtune wizard 2012-12-02
maintenance_work_mem = 768MB # pgtune wizard 2012-12-02
constraint_exclusion = on # pgtune wizard 2012-12-02
checkpoint_completion_target = 0.9 # pgtune wizard 2012-12-02
effective_cache_size = 9GB # pgtune wizard 2012-12-02
work_mem = 72MB # pgtune wizard 2012-12-02
wal_buffers = 8MB # pgtune wizard 2012-12-02
checkpoint_segments = 16 # pgtune wizard 2012-12-02
shared_buffers = 3GB # pgtune wizard 2012-12-02
max_connections = 80 # pgtune wizard 2012-12-02
bash-3.2# 

バッファを明示的に1GBに設定するものはありません。

何が起きてる?解決策がpostgresql.confのバッファーを増やすことである場合でも、postgresが1回のコピー呼び出しでcsvファイル全体をRAMに一括ロードしようとしているように見えるのはなぜですか?大きなcsvファイルをロードすることは一般的なタスクだと思うでしょう。私はこの問題に最初に遭遇することはできません。したがって、postgresがバルクロードのチャンク処理を処理して、最初からバッファ制限に到達しないようにしたと思います。

回避策として、csvを小さなファイルに分割してから、ファイルごとにcopyを呼び出します。これは正常に機能しているようです。しかし、これは特に満足のいく解決策ではありません。これは、postgresにロードする各大きなcsvの分割バージョンを維持する必要があるためです。大きなcsvファイルをpostgresに一括ロードするためのより適切な方法が必要です。

編集1:csvファイルの形式が正しくないことを確認中です。これを行うには、分割されたすべてのcsvファイルをpostgresにロードしようとします。すべてをロードできる場合、これは、csvファイルの形式が正しくないことが原因で問題が発生している可能性が低いことを示しています。私はすでにいくつかの問題を見つけました。大きなcsvを読み込もうとしたときに、これらの問題が文字列バッファエラーの原因であるかどうかはまだわかりません。

4

1 に答える 1

7

不正な形式のcsvファイルであることが判明しました。

大きなcsvを小さなチャンク(それぞれ100万行)に分割し、それぞれをpostgresにロードし始めました。

私はより有益なエラーを受け取り始めました:

pg.ProgrammingError: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
CONTEXT:  COPY chunksbase, line 15320779

pg.ProgrammingError: ERROR:  invalid byte sequence for encoding "UTF8": 0xe9 0xae 0x22
CONTEXT:  COPY chunksbase, line 369513

pg.ProgrammingError: ERROR:  invalid byte sequence for encoding "UTF8": 0xed 0xaf 0x80
CONTEXT:  COPY chunksbase, line 16602

数億のうち、無効なutf8バイトシーケンスを含む合計5行がありました。これらの行を削除した後、大きな9GBのcsvが正常に読み込まれました。

大きなファイルを最初にロードするときに、無効なバイトシーケンスエラーが発生するのは良かったでしょう。しかし、少なくとも私が問題を切り分け始めたら、それらは現れました。

大きなファイルを最初にロードするときのエラーに記載されている行番号は、小さなcsvサブセットファイルをロードするときに検出されたエンコードエラーとは関係がないことに注意してください。最初の行番号は、正確に1GBのデータが発生したファイル内のポイントであったため、1GBのバッファー割り当てエラーに関連していました。しかし、そのエラーは実際の問題とは何の関係もありませんでした...

于 2012-12-17T04:46:38.507 に答える