pg_dump が使えないけどバックアップしたい+CakePHP

とあるお仕事での話。

DBサーバ(PostgreSQL利用)とWebサーバが別で、DBサーバのファイルシステムには一切手を入れられない。だけど、Webサーバ側から定期的に(月1回)データベース内のデータをバックアップしたい、というオーダーがありました。

Webサーバ側にあるシステムは CakePHP 1.1 を使って構築されています。cronも使えないので、「定期的に」は、システムにログインされたタイミングで処理を実行させることにしました(あまりデータベースの中身が大きいと、待たせることになっちゃうのでお勧めしませんが)。

最初は pg_dump を呼べばいいと高を括っていたのですが、Webサーバ側には pg_dumppsql もない。ひとまず、SQLでのダンプはあきらめてくださいね、とお願いした上で、PostgreSQL の COPY table_name TO 命令を使ってみることに。

だが、普通に COPY table_name TO file_name したのでは、DBサーバ上にファイルを記録しに行ってしまう。もちろん、DBサーバは手を入れられないのでアウト。COPY table_name TO stdout にしていろいろやってみたが、うまく行かず・・・(この場合のstdoutって、DBサーバ側の標準出力ですよね。Webサーバ側のPHPPerlからどうにか取得でないか、いろいろやってみたのですが・・・。)

最終的に行き着いたのが、PHPpg_copy_to 関数を使うこと。今度はそうなると、CakePHP から実行するには、データベースのコネクションが拾えないといけない。調べていたら、以下のページを見つけました。

CakePHP で Model を介さずに SQL を呼ぶ - d.hetima

これで connection を拾い出せそうなので、/cake/libs/model/model_php5.php 辺りを見ながら、以下のように書いて解決しました。

$db =& ConnectionManager::getDataSource( $this->MODEL->useDbConfig );
$arr = pg_copy_to( $db->connection, $table_name );

※「MODEL」は何でもテキトウな Model で。

ふぅ、ここまで長い時間使ってしまいました。

ホスティングサーバだと、同じようなケースがありそうなので、メモの意味も含め。