Learning PostgreSQL from README

この記事は、PostgreSQL Advent Calendar 2014の12/10分の記事です。

前口上

12/5はPostgreSQLカンファレンス2014講演をさせていただきました。ニッチな内容にもかかわらずたくさんの方に聞いていただいて、本当にありがとうございました。その後、懇親会では「Learning English from PostgreSQL」というタイトルのLTを4分50秒という完璧タイムに納めたにもかかわらず、パイ×2を味わってきました。

このLTは「PostgreSQLからDBじゃないことを学んだって良いじゃないか」という当日の思いつきだったんですが、PostgreSQLの詳細な作りやいろんな仕様はやっぱりちゃんと学ばないとね、ということで、この記事ではソフトウェアにつきものの「READMEファイル」に着目してみます。

README とは

Wikipediaで「README」を検索すると、以下のような説明が出てきます。

リードミー(Readme)とは、ソフトウェアを配布する際の添付文書のひとつ。配布物の一般的な情報を記載したファイルである。多くの場合、そのソフトウェアをインストールし使用する前に読むべきものとされている。

「read me」ってくらいなので、「まずはこれを読め!質問はそれからだ!」ですよね。いきなりソフト使って使い方分からないと不平を言うよりも、進んでREADMEを読みましょう。最近流行のGitHubなんかでは、READMEをマークダウンで書いておくとリポジトリメインページでフォーマットして表示してくれたり、ややリッチな傾向もありますが、PostgreSQLのREADMEは硬派にプレーンテキストです。

PostgreSQLのREADMEファイル

PostgreSQLのソースを展開して(またはgit cloneなどで)できたディレクトリに入り「find . -name 'README*'」などとしてREADMEを探すと、ちょうど64個みつかりました。全部で1万行を超えていて、ちょっとしたプログラムよりも全然大きいですね。以下の表に、READMEファイルのパスと内容を整理してみました。

No. ファイル名 内容 行数
1 README PostgreSQLの概要 27
2 README.git gitリポジトリにINSTALLファイルがない説明 14
3 contrib/README contribツールの概要(詳細はドキュメントに移管) 28
4 contrib/start-scripts/osx/README OS X用の起動スクリプト 3
5 doc/src/sgml/README.links SGML文書のリンク 46
6 src/backend/access/gin/README GINインデックス 379
7 src/backend/access/gist/README GiSTインデックス 419
8 src/backend/access/hash/README HASHインデックス 467
9 src/backend/access/heap/README.HOT ヒープのHOT更新 499
10 src/backend/access/heap/README.tuplock ヒープのタプルロック 139
11 src/backend/access/nbtree/README B-Treeインデックス 622
12 src/backend/access/spgist/README SP-GiSTインデックス 373
13 src/backend/access/transam/README トランザクション管理 802
14 src/backend/catalog/README システムカタログ 111
15 src/backend/executor/README エグゼキュータ 202
16 src/backend/libpq/README.SSL libpqSSL接続 60
17 src/backend/nodes/README ノードシステム(PostgreSQL自前のOOP的機構) 80
18 src/backend/optimizer/README オプティマイザ 816
19 src/backend/optimizer/plan/README プランナ 158
20 src/backend/parser/README パーサ 30
21 src/backend/port/darwin/README Darwin依存のコード 36
22 src/backend/regex/README 正規表現 298
23 src/backend/replication/README レプリケーション 99
24 src/backend/snowball/README ワードステミング 49
25 src/backend/storage/buffer/README 共有バッファ管理 282
26 src/backend/storage/freespace/README 空き領域マップ 196
27 src/backend/storage/lmgr/README 内部レベルのロック機構(LWLockやスピンロックなど) 639
28 src/backend/storage/lmgr/README-SSI SSI TX分離レベル 629
29 src/backend/storage/lmgr/README.barrier メモリバリア 199
30 src/backend/storage/page/README ページ管理 63
31 src/backend/storage/smgr/README ストレージマネージャ 58
32 src/backend/utils/fmgr/README SQL関数呼び出し機構 556
33 src/backend/utils/mb/README マルチバイト文字関連ソースの説明 20
34 src/backend/utils/mb/conversion_procs/README.euc_jp エンコード変換関数の追加方法 83
35 src/backend/utils/misc/README GUCパラメータ実装 295
36 src/backend/utils/mmgr/README メモリアロケータ 431
37 src/backend/utils/resowner/README リソースオーナによるクリーンアップ機構 86
38 src/bin/pgevent/README Windowsイベントログ用DLL 20
39 src/interfaces/ecpg/README.dynSQL ECPGの動的SQL 11
40 src/interfaces/ecpg/preproc/README.parser ECPG特有のパース処理 42
41 src/interfaces/ecpg/test/connect/README 接続テストの説明 9
42 src/interfaces/libpq/README ディレクトリの内容 3
43 src/interfaces/libpq/test/README libpq用テストスイート 7
44 src/pl/plperl/README PL/Perl 10
45 src/pl/plpython/expected/README PL/Pythonのバージョン別テスト予想結果ファイル 11
46 src/pl/tcl/modules/README PL/Tcl 18
47 src/port/README 環境差吸収用ライブラリlibpgport 32
48 src/test/isolation/README テストツール(TX分離性) 117
49 src/test/locale/README テストツール(ロケール 28
50 src/test/locale/de_DE.ISO8859-1/README テストツール(de_DE.ISO8859-1ロケール 4
51 src/test/locale/gr_GR.ISO8859-7/README テストツール(gr_GR.ISO8859-7ロケール 4
52 src/test/locale/koi8-to-win1251/README テストツール(koi8-to-win1251ロケール 6
53 src/test/mb/README テストツール(マルチバイト文字) 10
54 src/test/regress/README テストツール(スレッド) 3
55 src/test/thread/README テストツール(ロケール 54
56 src/timezone/README タイムゾーン 42
57 src/timezone/tznames/README タイムゾーン略名 31
58 src/tools/findoidjoins/README 開発用ツール(findoidjoins:OID列の結合調査) 208
59 src/tools/ifaddrs/README 開発用ツール(ifaddrs:IPv4/6アドレス調査) 12
60 src/tools/make_diff/README 開発用ツール(make_diff:diff一括取得) 39
61 src/tools/msvc/README 開発用ツール(MS VCビルド) 103
62 src/tools/pginclude/README 開発用ツール(pginclude:#includeクリーンアップ) 55
63 src/tools/pgindent/README 開発用ツール(pgindent:インデント整形) 110
64 src/tutorial/README SQLチュートリアル 16
Total 10,299

最大のREADMEはsrc/backend/optimizerの816行で、次点はsrc/backend/access/transam/READMEの802行です。やはりプラン生成とトランザクション管理はそれだけで仕様も実装も大変ということですね。また、src/backend/storage/lmgr以下に合計1268行分のREADMEがあります。PostgreSQLが内部的に使用しているロック機構がいかに複雑で難しいか、こんなところからも分かります。

これらのREADMEはほとんどが英語で書かれているので、きちんと理解するには

PostgreSQLの知識
アーキテクチャや機能、用語は全ての基本ですね。
英語力
文学的な文章ではないので、技術用語に慣れればそれほど難しくないです。
一般的なC言語プログラミングスキル
C言語でのデーモンプログラム作成やIPCに関する知識があると理解しやすいかと。
RDBMS一般の知識
トランザクションや結合、SQL仕様などはやはり前提知識として必要です。

といったものが必要になります。src/backend/executor/READMEやsrc/backend/optimizer/READMEなどは個人的に和訳したものもあるので、「他は大体分かるんだけど英語がな〜」という方向けに機会を見て公開できればと思っています(他が分かる人は英語もできそうな気もしますが)。

まとめ

PostgreSQLの詳細な実装を知りたい場合、最終的にはソースコードを読むことになるのですが、その背景にある理論や仕様、実装変遷の経緯などまでソースコードから読み解くのはとても大変です。もしその機能/ツールにREADMEがある場合は、一度その中身を 読んでみることをお勧めします。

明日は、nuko_yokohamaさんです。

PostgreSQL 9.3 新機能:postgres_fdw

現在開発が佳境を迎えている PostgreSQL 9.3 ですが、先日「postgres_fdw」という外部データラッパ関連の機能がコミットされましたので、ご紹介します。なお、現在開発中の機能ですので、正式リリースまでに変更されることも考えられます(というか、きっと変更が入る)ので、その点はご承知おきください。

続きを読む

PostgreSQL 9.2 新機能: libpq の単一行モード

本エントリは、PostgreSQL Advent Calendar 2012の12月2日分です。

PostgreSQL 9.2がリリースされてしばらく経ちますが、皆さんもうお使いでしょうか?IndexOnlyScanやCPUスケーラビリティ向上といった性能改善が大きなトピックになっていますが、細かいところにもいろいろ改善が入っています。このエントリでは、PostgreSQLのクライアントプロトコルであるlibpqに新しく追加された「単一行モード」をご紹介します。libpqはWebアプリケーション等ではあまり意識しないレイヤーかもしれませんが、psqlコマンドや言語別APIのベースとなっているプロトコル/ライブラリです。

続きを読む

相関副問い合わせ+max() vs ウィンドウ関数

きっかけ

社内で作っているシステムで「社員ごとに最新のXXXデータを一件ずつ取得したい」という要件があり、SQLで解決する方法を考えてみました。このエントリでは、pgbenchのpgbench_tellersテーブルを題材にして「branchごとに最も収支の良いtellerを一件ずつ取得する」というシナリオにしています。

$ pgbench -i -s 5

でbidが1〜5でデータが作られるようにテーブル群を初期化しましたが、bbalanceは初期値「0」なので以下のSQL文でランダムに更新しておきます。

postgres=# UPDATE pgbench_tellers SET tbalance = random() * 10000;
UPDATE 50
続きを読む

PostgreSQLのドキュメントコンパイル

きっかけ

postgresql_fdwという、外部のPostgreSQLのデータにアクセスするための外部データラッパを作成しているのですが、併せて説明ドキュメントも本体のドキュメントの一部として書いています。

PostgreSQLのドキュメントは、SGMLベースのドキュメント記述言語であるDocBookで記述されていて、必要に応じてそこからHTMLやPDFにフォーマットできるようになっています。ドキュメントの付録にも説明がありますね。

最近MacBook AirPostgreSQL関連の開発環境を移したのですが、ドキュメントコンパイル環境がまだ揃ってなかったのでWebの情報をもとに整えました。

続きを読む