pg_bman : Yet another backup tool for PostgreSQL

リモートサーバにデータをバックアップできるpg_rmanみたいなツールを作ってみた。

動機

pg_rmanはとてもよいツールだったのだが、PostgreSQLを置いたサーバにしかバックアップデータを保存できない*1。通常は別サーバにバックアップデータを置くので、実は今までpg_rmanの使いどころがなかった。

他にもPostgreSQLのバックアップツールはあるが、どれもデータの読み書きにssh+rsyncを使う。例えばpgbarmanなど。
問題はsshでパスワード入力しなくても済むように設定しなければならないことで、この為だけにPostgreSQLが稼働するサーバに無条件でloginできる状態を作らなければならないのは如何なものかと、常々思っていた。

アプローチと実装

PostgreSQL通信プロトコルだけでオンラインバックアップをするにはどうすればよいか、ネタフリに対して、花田さんはじめ皆様から有益な情報を頂き、特急で作ってみたのがpg_bman

Extensionはpg_read_binary_file()とpg_ls_dir()の制約を緩めただけ、SQLを発行する側のソフトはほぼテンプレの使い回し、操作ツールはbash。手抜きの極地。

結果

ネタフリ7月7日でGitHub公開7月9日。
大した作業もせずにpg_rmanとほぼ同様のバックアップ機能は実装できた(その後、2時間くらいでリストアも実装)。
少なくとも、個人的に使う分には充分な機能。


フィジビリティスタディなので、実装で気になった点を2つ。

byteaデータの送受信

pg_read_binary_read()は、内部で拾ってくるデータサイズ+VARHDRSZのメモリ領域をpallocで確保する。今回はWALセグメントを拾ってくるので16[Mbyte]を確保することになる。これ、640kの壁なんてものを意識しながらプログラミングを覚えた身としては、とても気になる。

	buf = (bytea *) palloc((Size) bytes_to_read + VARHDRSZ);


そもそも、byteaのデータを拾ってくる時には全部こうやってるのか?これから時間があるときに確認してみるつもりだけれども、通信ライブラリまわりって、まだ改良の余地が残ってそう。

リストア

どこでリストアするのかにも依存するけども、他のサーバ上でリストアするには結局sshftpなどが必要になるわけで、ことリストアに関してはlibpqに拘るのは無意味だということに、作り終わってから気づいた。ま、こんなモンですよね。

*1:pg_rmanは直でファイルシステムを読み書きするため。改造も容易でない。別サーバにバックアップを保存するには、NFSを使うくらいしか手がない。