cronでPostgresqlの全テーブルを世代バックアップ

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);

}

//}}}

?>