在我的設置中,PostgreSQL 9.2.2在嘗試將大型csv文件加載到表中時似乎出錯。PostgreSQL加載大型csv文件到表中時遇到問題
的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似乎嘗試將單個副本調用中的整個csv文件批量加載到ram中?人們會認爲加載大型csv文件是一項常見任務;我不能成爲第一個遇到這個問題的人;所以我認爲postgres會處理分塊的負載,所以緩衝區限制從來沒有達到過。
作爲一種解決方法,我將csv拆分爲較小的文件,然後爲每個文件調用副本。這似乎工作正常。但這不是一個特別令人滿意的解決方案,因爲現在我必須維護要加載到postgres中的每個大型csv的拆分版本。必須有更合適的方式將大型csv文件批量加載到postgres中。
編輯1:我正在確保csv文件不以任何方式格式不正確。我正在通過嘗試將所有拆分csv文件加載到postgres中來完成此操作。如果全部都可以加載,那麼這表明這裏的問題不可能是由於csv文件格式錯誤造成的。我已經發現了一些問題。還不確定這些問題是否在嘗試加載大型csv時導致字符串緩衝區錯誤。
我懷疑你的CSV格式不正確 - 或者更具體地說,不符合你在'COPY'命令中指定的格式。有關詳細信息,請參見[CSV處理文檔](http://www.postgresql.org/docs/current/static/sql-copy.html#AEN66692)。你的CSV有一個不匹配的'''字符嗎? – willglynn
我認爲它是單引號或雙引號和字符串的問題。一些字符串值沒有正確終止或文本值內有單個字符(例如...不是...),我敢打賭第二個。無論如何這就是爲什麼Postgres試圖緩衝更大的字符串,然後它最初保存在csv文件中。 – Wojtas
我首先檢查CSV文件中的(最大)行長度。 BTW:這是遺傳/ DNA數據嗎? – wildplasser