在我的设置中,PostgreSQL 9.2.2似乎在尝试将大型csv文件加载到表中时出错.
csv文件的大小约为9GB
这是我用来进行批量加载的SQL语句:
copy chunksBase (chunkId, Id, chunk, chunkType) from path-to-csv.csv' delimiters ',' csv
Run Code Online (Sandbox Code Playgroud)
这是几分钟后我得到的错误:
pg.ProgrammingError: ERROR: out of memory
DETAIL: Cannot enlarge string buffer containing 1073723635 bytes by 65536 more bytes.
CONTEXT: COPY chunksbase, line 47680536
Run Code Online (Sandbox Code Playgroud)
我认为缓冲区不能分配超过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#
Run Code Online (Sandbox Code Playgroud)
没有任何明确将缓冲区设置为1GB的内容.
这里发生了什么?即使解决方案是在postgresql.conf中增加缓冲区,为什么postgres似乎尝试在单拷贝调用中将整个csv文件批量加载到ram中?有人会认为加载大型csv文件是一项常见任务; 我不能成为第一个遇到这个问题的人; 所以我认为postgres会处理大量加载的分块,因此首先从未达到缓冲区限制.
作为一种解决方法,我将csv拆分为较小的文件,然后为每个文件调用copy.这似乎工作正常.但它并不是一个特别令人满意的解决方案,因为现在我必须维护每个大型csv的拆分版本,我想加载到postgres中.必须有一种更合适的方法将大型csv文件批量加载到postgres中.
编辑1:我正在确保csv文件没有任何形式的格式错误.我这样做是通过尝试将所有拆分csv文件加载到postgres中.如果可以加载所有内容,则表明此处的问题不太可能是由于csv文件格式错误.我已经发现了一些问题.在尝试加载大型csv时,还不确定这些问题是否导致字符串缓冲区错误.
结果是一个格式错误的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
Run Code Online (Sandbox Code Playgroud)
总共有5行具有无效的utf8字节序列,其中有几亿行.删除这些行后,大的9GB csv加载就好了.
最初加载大文件时,获得无效的字节序列错误会很不错.但至少他们出现了我开始孤立问题.
请注意,最初加载大文件时错误中提到的行号与加载较小的csv子集文件时发现的编码错误无关.初始行号是文件中恰好发生1GB数据的点,因此它与1GB缓冲区分配错误有关.但是,这个错误与真正的问题无关......
| 归档时间: |
|
| 查看次数: |
7066 次 |
| 最近记录: |