[pgsql-jp: 25137] text 型に大量(50MB)のデータを入れた場合
Kazumasa Gotoh
kgotoh @ cic-kk.co.jp
2002年 3月 7日 (木) 16:39:13 JST
私のところではなく、知り合いのところで発生した問題なのですが、
以下の条件でエラーが発生するというものがありました。
環境 : Digital UNIX 5.0 + PostgreSQL 7.2
現象 : text 型のカラムに 50MB ほどのデータを insert しにゆくと
"Memory exhausted in AllocSetAlloc(数字)" となる。
"数字" はアロケーションサイズで、50MB ほどの値になります。
結局はその環境で malloc できる最大値を標準の 512MB から1GB に増やして
登録できるようにはなったのですが、何でそんなにメモリを食うの?
という点が疑問になりました。
私自身は追試はしていないのですが、top で見ると、postmaster のプロセス
サイズは確かに 500MB 以上になっていたそうです。
エラー発生個所は、src/backend/utils/mmgr/aset.c の AllocSetAlloc() の
493行目になります。実際にはその前の 489行目の malloc でエラーになって
いるわけです。
485 if (size > ALLOC_CHUNK_LIMIT)
486 {
487 chunk_size = MAXALIGN(size);
488 blksize = chunk_size + ALLOC_BLOCKHDRS + ALLOC_CHUNKHDRSZ;
489 block = (AllocBlock)malloc(blksize);
490 if (block == NULL)
491 {
492 MemoryContextStats(TopMemoryContext);
493 elog(ERROR, "Memory exhausted in AllocSetAlloc(%lu)".
494 (unsigned long) size);
作業者はこの関数でトレースを取るようにしてみたのだそうですが、489行目の
malloc は 8〜10回ほど実行されていたと言っています。
ここが何らかのワーキングセットを確保しているんだろう以上の事は調べて
いませんが、カラムサイズの 10倍くらいのメモリが消費されるというのは
PostgreSQL の動きとしては正しいのでしょうか?
まぁ、text 型になんでそんな大きなデータを入れるんだという話も
あるのかも知れませんが、実際できてしまうし、マニュアルにも無制限と
書いてあるし…
AllocSetRealloc() じゃなくて AllocSetAlloc() だということは、最初に
確保する必要のあるメモリエリアということなのだろうと思うのですが、
結果としてはメモリを食いすぎてる気がしないではありません…
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
(株) セントラル情報センター
後藤和政 kgotoh @ cic-kk.co.jp
pgsql-jp メーリングリストの案内