[pgsql-jp: 41676] Re: DBLINK使用時に Out of Memory エラー

Shigeru HANADA hanada @ metrosystems.co.jp
2014年 6月 4日 (水) 09:56:42 JST


花田です。

(2014/06/02 23:54), MauMau wrote:
> おそらく、9.2での次の性能改善に起因するメモリリークだと思います。
> 残念ながら、パラメータなど外部からの制御で問題を回避することはできなさそ 
> うです。
> 
> Improve efficiency of dblink by using libpq's new single-row processing 
> mode (Kyotaro Horiguchi, Marko Kreen)
> 
> dblinkでSQL文を実行する際、
> dblink temporary contextというメモリコンテキストを作成します。
> 本来なら、contrib/dblink/dblink.cのstoreQuery()の最後で、
> このメモリコンテキストを削除するのが正しいのでしょう。
> これにより、dblinkの関数から復帰するときには、このメモリコンテキストがな 
> くなります。
> 
> 今の実装だとおそらく、dblinkを呼び出すSQL文、今回だとDELETE文の終了時に、
> 削除し忘れたメモリコンテキストが自動的に削除されると推測します。
> 今回は1つのDELETE文で16万回dblink関数が呼ばれており、
> それぞれの呼び出しが8KBのメモリをリークするため、1GB超のメモリが残ってし 
> まったものと思います。
> 
> 有識者の方、正しいか確認いただけると幸いです。
> よければ、コミュニティに修正パッチを送ってみます。

materializeQueryResult()関数を抜けるところでsinfo.tmpcontextが失われるの
で、リーク(?)してますね。おそらく行単位でメモリコンテキストを作成しなお
すオーバーヘッドを避けたものと思われるので、性能劣化がなければいいんです
が…と思ったんですが、そもそもmaterializeQueryResult()でtmpcontextの作
成・削除を一回だけやれば済む話ですかね。

とはいえ、やはりひとつのSQL文で16万回もdblink()関数が呼ばれる理由は
ちょっと気になりますので、SQLや実行計画は見てみたいですね。EXISTS内の
SELECTで、Nested LoopのInnerにdblink関数が来ているのかな?と。

-- 
株式会社メトロシステムズ
インテグレーション事業部
花田茂
TEL: 03-5951-1219(部門直通)


pgsql-jp メーリングリストの案内