cronでPostgresqlの全テーブルを世代バックアップ
2011年10月12日MySQLに続いて、Postgresqlの世代バックアップ用スクリプト。
以下のSETTING欄を設定後、cron実行するのみ。
[php]
<?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);
}
//}}}
?>
[/php]