[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 メーリングリストの案内