2005-01-01から1年間の記事一覧

btree index (8)

_bt_compare scankeyとindex tupleを比較する。 index_getattrでindex tupleのデータを取得し,FunctionCall2で比較を実行する。 FunctionCall2には,異なるデータ型の比較をサポートするために,先頭の引数にindex tupleのデータを渡さなければいけないとい…

btree index (7)

_bt_findsplitloc btree indexのページを分割するとき,どの位置で左右に分割するかを決める。 先頭のアイテムから順にサイズを取得し,そのアイテムを左のページに追加した場合の左右の空き領域を計算する。次に_bt_checksplitlocを実行して左右の空き領域…

btree index (6)

meta page btree indexの先頭ページにはmeta pageというデータがおかれ,rootノードの位置などを記録する。(btreeではrootページが分割されるときrootページが移動するので,その位置をmeta pageで管理している) typedef struct BTMetaPageData { uint32 btm…

btree index (5)

_bt_moveright 例えば,更新トランザクション(UPD-Tr)と検索トランザクション(SEL-Tr)が,以下のように並行動作した場合, UPD-Tr: 親ノードP0を検索し,リーフページP1のポインタを取得 SEL-Tr: 親ノードP0を検索し,リーフページP1のポインタを取得 UPD-Tr…

btree index (4)

_bt_addtup ページの指定した位置に,BTItemを登録する。 offsetを指定してPageAddItemを実行する。 PageAddItem ページにItemを登録する。 PageAddItemはb-tree以外にも,tupleや他のindexのアイテムを登録するために 実行される。OffsetNumberでページ内の…

btree index (3)

_bt_insertonpg 指定したページにBTItemを登録する。 non-unique indexで重複したキーを登録する場合,以下のルールで登録する場所を決めている。(1)指定したページに登録できる場合:同じキーの先頭に挿入する。(新しく登録するアイテムが先頭になる)(2)指…

btree index (2)

_bt_doinsert btreeへBTItemを登録する。public interfaceのbtbuildやbtinsertから実行される。 (1)_bt_mkscankeyでインデックスのデータを比較するためのScanKeyを生成する (2)_bt_searchでBTItemを登録する,先頭のリーフページを取得する (3)Read lockを…

btree index (1)

Indexがあるテーブルにinsert文を実行すると、indexに登録するためにbtinsertが実行される。 #0 btinsert (fcinfo=0xbffeb8a0) at nbtree.c:225 #1 0x08289103 in FunctionCall6 (flinfo=0x83f10b0, arg1=1099692112, arg2=3221142352, arg3=3221142320, arg…

check_stack_depth

関数呼び出しが深くなるたび、各関数のローカル変数などを割り当てるためにスタック領域を消費する。再帰コールが大量に発生するなどの理由で、スタックを使い切ってしまうとSIGSEGVエラーになりプロセスが終了してしまうため、そうなる前にERRORを発生させ…

parser/keywords.c

ScanKeywords キーワードの配列。 selectなどのキーワードが列記してある。バイナリサーチで検索するためアルファベット順に記述されている。 ScanKeywordLookup() 文字列がキーワードに一致するか調べる。parserから実行される。 一致するキーワードが見つ…

データ型による性能の違い

テストテーブル作成 create table int4_test(d int4); create table int8_test(d int8); create table float4_test(d float4); create table float8_test(d float8); create table numeric_test(d numeric); create table text_test(d text); create table v…

Cache last known per-tuple offsets to speed long tuple accessを実装したときのメモ

カラム数が多いテーブルをjoinするとき,heaptuple.cのnocachegetattr()に負荷がかかる。 390行目付近のfor()ループで,カラムの先頭から調べてるので,カラム数が多いほど負荷が高くなる。ExecProject() -> ExecTargetList() -> ExecEvalExpr() -> ExecEval…

regexp_replaceを実装したときのメモ

1.backend/regex/regexec.cのpg_regexec()で,検索開始位置を設定できるように拡張する。 (これがないと,2箇所目以降の置換開始位置を決められない)○backend/regex/regexec.c ・pg_regexecに検索開始位置を指定する引数を増やす(size_t search_start)。 ・p…

AllocSetResetの高速化

AllocSetContextにisResetという変数が追加された。これはcontextの初期化やリセット時にtrueに設定され、contextからメモリを確保したときにfalseになる。 bool isReset; /* T = no space alloced since last reset */AllocSetResetではisResetがfalseのと…

WAL(3)

heap_insertのときのブロックのバックアップ insertするタプルがブロックの最初のタプルだった場合,ブロックのバックアップは行わない。(rdata[1].buffer = rdata[2].buffer = InvalidBuffer;でクリアしている) checkpointを発生させる方法 superuserでログ…

optimizer: havingの最適化

subquery_plannerで,havingの条件をwhereに移動する最適化を実行している。(planner.c:294-346行目) 以下の3パターンがある。(1)where句に移動できないケース having句に指定したカラムが,集約関数やvolatile関数だったりする場合。 集約関数などの実行結…

WAL(2)

Recovery バックエンドが異常終了した後、再起動時に実行されるリカバリは,StartupXLOGのdo-whileループで実行される。(コメントにmain redo apply loopとある箇所) ログレコードにページ(ブロック)のバックアップが含まれている場合,RestoreBkpBlocksを実…

WAL(1)

起動後またはチェックポイントが発生した後に、バッファのページを最初に更新する場合,ページ全体をログに出力する。ページのバックアップがないとbackground writerがページを書き込んでいるときにbackendがクラッシュした場合、リカバリが難しくなる。(例…

sum(int4)の高速化

backend/utils/adt/numeric.cのint4_sumで、 Datum int4_sum(PG_FUNCTION_ARGS) { int64 newval; if (PG_ARGISNULL(0)) { /* No non-null input seen so far... */ if (PG_ARGISNULL(1)) PG_RETURN_NULL(); /* still no non-null */ /* This is the first no…

operator

例えば、 select * from branches b where b.bid = 1;というSQLで'='というoperatorがどのように処理されるのか。 parserの処理 make_op()でoper(), make_op_expr()を実行し、executorが使うOpExprデータを作成する。 oper()では、operator名('=')と左辺/右…

lock manager

src/backend/storage/lmgr/READMEより:LOCKING OVERVIEWPostgreSQLは,以下の3種類のロックを使用する。 Spinlocks Spinlockは超短期的なロックを取得することを意図しており,主にLightweight lockのインフラとして使用される。 Spinlockが要求されると,…

lxrの設定

必要なソフト ・apache ・perl ・lxr 0.3.1 ・glimpse 4.18.01.glimpseのインストール ソースを展開して,configure, make, makeinstallでOK. 2.lxrのインストール (1)ソースを展開 $ gzip -dcv lxr-0.3.1.tar.gz | tar xf - $ cd lxr-0.3 (2)Makefileを編集…

Optimizer: exists

現在の実装では、exists句のsubqueryはマージされないため、テーブルのJoin方法はNested loop joinになる。 Nested loop joinでは、Outer側(以下の例ではaccounts)から1行取り出すごとにsubqueryが実行されるため、Outer側のテーブルが大きい場合、検索が非…

Optimizer: in (subquery)の最適化

pull_up_IN_clauses(), convert_IN_to_join()で、in句のsubqueryを上位の階層のqueryにマージしている。 select a.* from accounts a where a.bid in (select bid from branches b where b.bid < 10)このSQLが以下のようになる。 select a.* from accounts a…

Optimizer

PostgreSQLのOptimizerは、Parser/Rewriterで作成されたQuery structureを受け取り、Executorが使うPlan structureを生成する。Optimizerは利用可能な全てのアクセスパスを生成し、最もコストが小さいパスを選択する。 テーブルへのアクセスはTable ScanとIn…

bitmapsetのAPI

extern Bitmapset *bms_copy(const Bitmapset *a); aをコピーする。 extern bool bms_equal(const Bitmapset *a, const Bitmapset *b); aとbを比較する。一致した場合はtrueを返す。 extern Bitmapset *bms_make_singleton(int x); xで指定した整数からBitma…

bitmapset

正の整数をbitとして扱うための汎用ルーチン。 bitmapset.h, bitmapset.cで定義されている。bitmapsetでは整数nは、右からn番目のビットが立った2進数へ変換されて扱われる。 例: 0 -> 00000001 1 -> 00000010 2 -> 00000100 3 -> 00001000bitmapセットのデ…

add_path()

optimizer/util/pathnode.cのadd_path()で,pathの候補を追加する。 pathを追加する前に、既に追加されているpathとcompare_fuzzy_path_costs()でコストを比較して、コストが高いpathは削除される(追加されない)。 コストが大体おなじだったときは、pathkey(…

join方法を決めているところ

make_join_rel() -> add_paths_to_joinrel() ここでmerge join, nestloop join, hash joinのpathが作成される。 そしてset_cheapest()でコストが小さいpathが選択される。

lxrの設定

lxr-0.3.1でversionsなどで指定するディレクトリ名に'_'を使いたい場合、Config.pm::verexpandの正規表現に'_'を追加する。そうしないとdbdir, sourcerootなどが正しくならない。