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 | libpqのSSL接続 | 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」という外部データラッパ関連の機能がコミットされましたので、ご紹介します。なお、現在開発中の機能ですので、正式リリースまでに変更されることも考えられます(というか、きっと変更が入る)ので、その点はご承知おきください。
続きを読むJSONをもっと便利に:json_accessors
本エントリは、PostgreSQL Advent Calendar 2012の12月22日分です。
昨日@choplinさんがpg-jsonpathのこと書いたばかりでアレですが、空気読まずにJSONネタ続けます :-P
続きを読む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 AirにPostgreSQL関連の開発環境を移したのですが、ドキュメントコンパイル環境がまだ揃ってなかったのでWebの情報をもとに整えました。