cronでPostgresqlの全テーブルを世代バックアップ
2011年10月12日MySQLに続いて、Postgresqlの世代バックアップ用スクリプト。
以下のSETTING欄を設定後、cron実行するのみ。
<?php /** * ------------------------------------------------------------ * Script for PostgreSQL Backup(cron) * ------------------------------------------------------------ * $id$ * Author $Author$ * Date $Date$ * Rev $Rev$ * URL $URL$ * ------------------------------------------------------------ * PostgreSQLのDB内全てのデータベースをバックアップ * バックアップするデータベースへは、スーパーユーザーでアクセス * バックアップ時のアーカイバの指定可能 * 古い(指定日経過後)バックアップファイルは、保存指定の世代数 * を超えると自動的に古いデータから削除 **/ /* SETTINGS ------------------------------------------------- */ // PostgreSQL スーパーユーザーユーザーアカウント $RootUser = 'user'; $RootPass = 'password'; // バックアップ先(最後にスラッシュ必須) $BackPath = "/home/.backup/.pgsql/"; // 世代保存日数 $KeepDay = 14; // アーカイブコマンド $Arc = "/bin/tar cpzf"; // アーカイブ拡張子 $ToExt = "tgz"; // ダンパ $Dumper = "/usr/bin/pg_dump"; // バックアップ対象データベース // $Target未指定の場合は、全データベースを対象とする $Target = array(); /* ------------------------------------------------- SETTINGS */ /* フォルダ書き込み確認 */ if ( !touch($BackPath) ){ if( !is_dir($BackPath) ){ ErrorOut("フォルダがありません: $BackPath"); }else{ ErrorOut("書き込み権限がありません: $BackPath"); } } /* 出力フォルダへ移動 */ chdir($BackPath); ~~~~ /* 出力バッファ内データ出力 */ @ob_end_flush(); ~~~~ /* DB接続 */ if ( !($conn = @pg_connect("host=localhost port=5432 user=$RootUser password=$RootPass")) ) ErrorOut("PostgreSQL接続エラー: サービス停止 or 接続情報が一致しません"); /* データベースの一覧を取得 -> $db[] */ if ( empty($Target) ) { $res = pg_list_dbs($conn); if ( empty($res) ) { ErrorOut( "データベース名を取得できません"); }else{ while($db = pg_fetch_assoc($res)) { foreach($db as $_val) { if ($_val != 'template0') $Target[] = $_val; } } } } /* mysqldumpと$Arcを実行 */ $now = date('Ymd'); for ($i = 0; $i < count($Target); $i++) { //pg_dump -U postgres -F c -f <バックアップ・アーカイブ名.car> <データベース名> //pg_restore -U postgres -d <データベース名> -F c <バックアップ・アーカイブ名.car> $cmd = "$Dumper -U $RootUser -F p -f $BackPath{$Target[$i]}.pgdump {$Target[$i]}"; if (MySystem($cmd)) ErrorOut("次のコマンド実行でエラーになりました。$cmd"); $cmd = "$Arc $BackPath{$Target[$i]}.$now.$ToExt {$Target[$i]}.pgdump"; if (MySystem($cmd)) ErrorOut("次のコマンド実行でエラーになりました。$cmd"); @unlink("$BackPath{$Target[$i]}.pgdump"); }; /* 古いバックアップファイルを削除 */ $KillDate = (int)date('Ymd', mktime(0,0,0, date('m'), date('d') - $KeepDay, date('Y'))); $dir = opendir($BackPath); while ($fname = readdir($dir)) { $ex = explode('.', $fname); if (count($ex) == 3) { if ((int)$ex[1] < $KillDate) @unlink($BackPath. "/" . $fname); } } closedir($dir); //{{{ function ErrorOut() /** * エラー時の処理。実際の運用では管理者へメールを送信するなどに変える * @param string $msg * @access public **/ function ErrorOut($msg) { echo $msg . "\n"; exit; } //}}} //{{{ function MySystem() /** * コマンドの実行 * @param string $cmd * @access public **/ function MySystem($cmd) { return system($cmd); } //}}} //{{{ function pg_list_dbs() /** * PostgreSQLのデータベース一覧を取得 * @param string $dbs * @access public **/ function pg_list_dbs($dbs) { assert(is_resource($dbs)); /* $query = ' SELECT~ d.datname as "Database", u.usename as "Owner", pg_encoding_to_char(d.encoding) as "Encoding" FROM pg_database d LEFT JOIN pg_user u ON d.datdba = u.usesysid ORDER BY 1; '; */ $query = ' SELECT~ d.datname FROM pg_database d ORDER BY 1; '; return pg_query($dbs, $query); } //}}} ?>