a_ogawa

2005-11-21

[] Virtual tuple slots versus TOAST: big problem

TOASTが必要なTupleをinsert/updateした時、backendがcrushする問題について。

http://archives.postgresql.org/pgsql-hackers/2005-11/msg01016.php

(1)ExecInsertにTupleTableSlot(slot)が渡される。

このときslotのvirtual tuple領域(slot->tts_valuesなど)にデータが設定されている。

(2)ExecMaterializeSlotでslotのvirtual tupleから、physical tuple(slot->tts_tuple)に変換する。slotのvirtual tupleはクリアされる。

(3)ExecConstraintsで制約チェックを実行する。

slotのphysical tupleからチェックするカラムのデータを取り出す。このとき、取り出したカラムとそれより前にあるカラムのデータはslotのvirtual tuple領域にcacheされる。

(4)heap_insertにslotのphysical tupleを渡して、ページにtupleを登録する。

heap_insertでは、tupleサイズがTOAST_TUPLE_THRESHOLDより大きい場合、heap_tuple_toast_attrsを実行する。heap_tuple_toast_attrsは、tupleを上書きして再構成するため、tupleのサイズや各カラムのデータの位置などが変わる。

(*)ここでslotのphysical tupleとvirtual tuple cacheの情報が矛盾してしまう

(5)(ExecInsertに戻って)ExecInsertIndexTuplesを実行してindexにデータを登録するとき、index用のtupleを構築するためにslotのphysical tupleまたはvirtual tupleから、indexに必要なカラムのデータを取り出す。

virtual tupleの情報はphysical tupleの情報と矛盾しているため、virtual tupleの情報を参照したときに正しくない位置のメモリを読んでしまい、backendがcrushするか、間違ったデータを取り出してしまう。

updateについても同様の問題が発生する。

当面の解決策はheap_insert/heap_updateの実行後にvirtual tuple cacheを無効にすること。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/a_ogawa/20051121