2015/03/12

PostgreSQLのコードを読む話(4)

前回はオプティマイザー周りに入ったのでした。


多分 optimizer の planner.c あたりを読み進めると検索プランの作成方法が、
Portal あたり(どこだ?)を読み進めると、検索プランに従って実際に検索を行う処理が見つかる気がする。

今回は Portal の方にあたりをつけて読み進めてみることにする。

CreatePortal

  • http://127.0.0.1:9292/home/postgres/src/backend/utils/mmgr/README
  • readmeみる
  • mmgr は Memory Manager っぽい
  • Context単位でメモリ管理をするようなモデルらしい

PortalDefineQuery

parseされたStatementを受け取っているので、ここで実行?
statement 名を設定しているだけだった。。。

PortalStart

実行準備とのこと
なにやら strategy にしたがって動作している

PortalSetResultFormat

見てない

PortalRun

多分ここが実行。。。
時間切れだったので、次回はここから。

PostgreSQLのコードを読む話(3)

前回の続き、フロントエンドとバックエンド間の通常操作サブプロトコルのひとつ、Queryを読んでみることにした。

ここから
https://github.com/postgres/postgres/blob/master/src/backend/tcop/postgres.c#L3969

exec_simple_queryに入った

https://github.com/postgres/postgres/blob/master/src/backend/tcop/postgres.c#L824
  • start_xact_command - トランザクション?いったん飛ばす
  • drop_unnamed_stmt - 名無しのステートメントを除去?一端とばす
  • MemoryContextSwitchTo
  • pg_parse_query - クエリをパースしてツリーを作るっぽい
  • コンテキスト戻している
  • ツリーをトラバースしている。。。
    • pg_plan_queries - クエリプラン作成?ここで色々しているとのこと
    • Portalってなんだろう?カーソルのことらしい
    • CommandCounterIncrement トランザクション関連らしい。飛ばす
      home/postgres/src/backend/access/transam/README トランザクションシステムの説明

pg_plan_queriesからオプティマイザーあたりに入った

  • プラグインでoptimizerのプランナーフックを仕掛けることが可能っぽい
  • pull_up_sublinks - any/existsを内部的にjoinに変形するらしい

オプティマイザーの全体を俯瞰した方がよいかと思いREADMEを見る

https://github.com/postgres/postgres/blob/master/src/backend/optimizer/README#L286
optimizerの動作についての説明がのっていた

時間切れ、次回はここから見ていこう。。。

2015/01/25

PostgreSQLのコードを読む話(2)

前回の続き。先日のサッポロビームで活動してきた。
今回はほとんどコードを読んでいない。
postgres.c の PostgresMain の query とか parse とは?というあたりを調べた。
あとはPostgreSQLのドキュメントを色々読んでた。

"簡易問い合わせ"と"拡張問い合わせ"

PostgreSQLのドキュメントの「フロントエンド/バックエンドプロトコル」が参考になります。通常利用される問い合わせプロトコルに"簡易問い合わせ"と"拡張問い合わせ"があるとのこと。

フロントエンド/バックエンドプロトコル


  1. 接続開始
  2. 通常操作
    • 簡易問い合わせ
      • Query
    • 拡張問い合わせ
      • Parse
      • Bind
      • Execute
    • 関数呼び出し
      • FunctionCall(非推奨らしい、Bind & Executeを利用せよとのこと)
    • その他特殊な操作向け
      • Copy
      • など...
  3. 接続終了

PostgresMain ではこのプロトコルの内、接続開始後の各サブプロトコルの種類を判別してそれぞれのサブプロトコルで定義される操作を呼び出している模様。

簡易問い合わせと拡張問い合わせの概要は次の通り。
"簡易問い合わせ"プロトコルでは、フロントエンドはテキストで問い合わせ文字列を単に送信し、バックエンドによって解析され、即実行されます。
"拡張問い合わせ"プロトコルでは、問い合わせの処理は、解析、パラメータ値の結び付け、そして実行という複数の段階に分離されます。 これは複雑性が加わりますが、柔軟性と性能という点で利点が生まれます。
このあたりを念頭に各操作の内容を読んでいけばなんとかなりそう。

その他

演算子クラス/演算子族

ひたすらドキュメントを読んでたらインデックス周りで演算子クラスとか演算子族というのが出てきた。
インデックスの種類やデータ型ごとに演算子クラスをユーザが定義することで、独自にインデックスを拡張できる?らしい。演算子クラスをまとめたのが演算子族?なのかな?インデックス周りを確認するときにもうちょっとちゃんと調べる予定。

Notify

肉さん情報。バックエンドからフロントエンド側に何らかのタイミングで通知を送る機能があるらしい。そのうち調べる。

次回

https://github.com/postgres/postgres/blob/master/src/backend/tcop/postgres.c#L3969
前回と同じくここから。通常操作のサブプロトコルからひとつ(Queryがよいかな)を読んで、その後DBの物理ファイルやインデックス周りの箇所を調べる予定。

参考資料


2015/01/18

PostgreSQLのコードを読む話(1)

昨年末からちびちびとPostgreSQLのコードを読み始めた。
ちびちび読んでいるので、次読むときにどこ読めばいいか忘れるのでその記録。

とは言ってもそんなに C に堪能ではないので、結構飛ばしつつ流れを追っている段階。。。
まずはインデックスとかDBの物理ファイルあたりにたどりつくのが目標。

前回までに読んだところ

  • src/backend/main/main.c
    コマンドでサーバーを起動したときの開始ポイント。まずはここから
  • src/backend/postmaster/postmaster.c#PostmasterMain
    マスタープロセスの起動部分。マスタープロセスから起動時に各種バックエンドプロセスが、コネクション接続時にバックエンドプロセスがフォークされる模様

今回読んだところ

  • src/backend/tcop/postgres.c#PostgresMain
    コネクション毎にpostmasterからフォークして作成されるバックエンドプロセスのメイン部分。コネクションを通してクエリを受け取ったりする。。。はず

次回

  • https://github.com/postgres/postgres/blob/master/src/backend/tcop/postgres.c#L3969
ここから。バックエンドでコマンドを受け取って種類ごとにゴニョゴニョするっぽい。

疑問

  • 次回読み始める箇所のコマンドにあたるものの位置づけがまだ把握できていない(queryの他にparseとかある。parseは何のparse?)
  • ディレクトリ名のtcopってなんだ?
  • DBの物理ファイルとかバッファプール関連の初期化箇所をすっ飛ばしたっぽい。。。
  • Windows の場合は fork する代わりに exe ファイルを起動しまくっている?

役立つもの

2014/09/29

RubyKaigi2014 に参加してきました

もひゃです!先日開催された RubyKaigi2014 に参加してきました!

ジュンク堂RubyKaigi支店に貢献してきました。帰り道は重みがつらい。。。自制心、大事。

初の The RubyKaigi 参加かつ、東京にあまり知り合いもいないしで緊張したのですが、
いつもの札幌勢&元札幌勢がたくさんいたので、さほどぼっちにはならず。ありがたいー。

@nagachika さんの CRuby Committers Who's Who in 2014 (@see 2013)が生で見れたり、@tenderlove 氏の生駄洒落クラブを見れたり、@kakutani さん(緊張したり、元気だったり疲れたりとせわしない)を見れたりと、"お約束"的な所はひと通り堪能し、聞きたいセッションもだいたい聞けたので満足でした!

全体としては、半分強くらいが英語のセッションだった印象。
英語セッションはちょっと聞き逃すと話の筋を理解できないことが多かったので、ちょっと鍛錬しておいたほうがより楽しめそう。。。

以下、いくつか聞いた中で特に面白かったなぁというセッションをちょっと紹介。

2014/09/08

"サーバー/インフラを支える技術"を読んだ

たまたま図書館にあったのでなにとなく借りたのだけれど、とても良かった。
ぼんやりとは知っているけど、ちゃんとわかっていなかったインフラ関係のあれこれを整理することができた。

  • インフラ冗長化の仕組み
  • インフラ冗長化構成の一例
  • Reverse Proxy 等の意義と役割
  • サーバーのチューニング
  • 運用

ちょうど、先日 +Naoya Ito さんが書いてた "Reverse Proxy がなぜ必要か" とかその辺りの話についても詳しく書いてある。(該当箇所はまさに naoya さんが執筆している)
本人が "(とっても)素晴らしい本" と紹介しているが、実際インフラまわりの知識を俯瞰することができる良書だと思う。かなりよかった。

ただし、発行年がちょっと古い(2008)ので、ちょっと内容が古くなってしまっている箇所があるのには注意が必要そう。今だと nginx を使うよぜーという箇所で Apache を使うような構成が紹介されていたりということがあるので、その点については新しい情報を追う必要がありそうです。

個人的には Reverse Proxy の役割とか、ロードバランサーの冗長化ってどうやってるの?みたいな箇所が fmfm なるほどー!でした。インフラ気になる人には大変オススメ。

2014/01/04

[Symfony2]プロファイラーのタイムラインへの独自項目追加方法

Symfony2 では xdebug を導入しなくても、簡易なプロファイラーを利用できます。

"タイムライン"で各処理が消費した時間を見ることができるのですが、コントローラーから呼び出された各処理については自動で時間を取得してはくれません。

Symfonyで提供しているプロファイラーのタイムライン

・・・というわけで独自項目をタイムラインへ追加する方法について調査しました。

タイムラインへの追加手順は次の通り。

  • タイムラインに追加したい処理を行うオブジェクトに "debug.stopwatch" を DI
  • $stopWatch = $this->get('debug.stopwatch'); $event = $stopWatch->start('hogehoge'); ...(任意の処理)...; $event->stop()
こんな感じになります
残念ながらドキュメントにはこのあたり書いてないのですよね。。。

以下、調査メモ