DB(MySQL)のバックアップについて調べたのでメモを残す。
これまでDBのバックアップを残すとすればWordPress関連のものばかりだったのでDBのバックアップをとるプラグインで対応をしていたが、今回WordPressではなく独自でPHP/MySQLのWebアプリケーションを作成したのでそのMySQLのバックアップについて検討したという次第である。
バックアップの方式としては、mysqldumpでdumpファイルを作成してそのファイルをパスワードつきzipで固めてからメール添付で自分に送るというプログラムを作成してcronで1日に1,2回定期実行をするかたちにしたい。
まずはdumpファイルの作成を試すためにteratermでさくらのサーバーにログインをして実行をした。
ユーザー名が「USERNAME」、
パスワードが「PASSWORD」、
バックアップをとりたい対象のDB名が「DBNAME」
dumpファイルのファイル名を「dump.sql」
としたい場合のコマンドとしては下記のような感じだ。
mysqldump -uUSERNAME -pPASSWORD DBNAME > dump.sql
実行するとコマンドを実行したディレクトリにdump.sqlができているはずである。
これを.shで保存して使おうかと思ったのだが、メール送信などを考えるとPHPで作成したいので調べ直した。PHPの場合は下記のような感じ。作成するファイル名はdump.sqlとした。
<?php $dbHost = 'ホスト名'; $dbUser = 'ユーザー名'; $dbPass = 'パスワード'; $dbName = 'データベース名'; $fileName = 'dump.sql'; $command = "/usr/local/bin/mysqldump --default-character-set=binary ".$dbName." --host=".$dbHost." --user=".$dbUser." --password=".$dbPass." > ".$fileName; system($command); ?>
続いて、作成したdump.sqlをパスワードつきzipにするPHPのコードはこんな感じ。zipのファイル名はdump.zipとした。
<?php $zip_pass = "zipに設定したいパスワード"; $zipcommand = "/usr/local/bin/zip -P " . $zip_pass . " dump.zip dump.sql"; system($zipcommand); ?>
上記ふたつのコードをひとつのファイルに書いて実行をしたらパスワードつきのdump.zipが生成された。
ただ、いまはDBのレコード数も多くないのですぐにdumpファイルができるので問題はなかったが、これがレコード数も多くなればきっとdumpファイルの作成に時間がかかると思われ、その場合にdump.sqlが完全に生成される前にzipファイルをつくったりしないのだろうか。
ちょっと心配になったので処理に時間を空けられないか調べてみるとsleep関数というものがあった。
sleep(60);
と書く事で60秒処理を遅らせる事ができるというものだ。こんな関数があるとは知らなかった。
上記のふたつのコードの間にsleep関数を入れても無事に動作の確認ができた。
しかしこれで本当に正しいのか不明なので、ちょっとレコード数の多いDBに対してsleep関数なしで実行をしてみたが、問題なくzipファイルは作成される事が分かった。system関数を使った場合にその実行したコマンドの処理が終わるまで待ってくれるっぽい。というかその結果が戻ってこないと先に進めないのかな。良くわからん。動いているから良しとしよう。
続いて、dump.zipのメール添付のコードに関して。下記サイトに記載されているコードで動いた。
<?php
//マイムタイプ定義
$mime_content_types = array(
'ez' => 'application/andrew-inset',
'atom' => 'application/atom+xml',
'atomcat' => 'application/atomcat+xml',
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'ice' => 'x-conference/x-cooltalk'
);
//送信先メールアドレス
$to = 'example@example.com';
//送信元メールアドレス
$from = 'example@example.com';
//件名
$subject = '添付ファイルのテスト';
//メール本文
$message = "テストメール。\n";
$message .= "添付ファイル送信のテストです。\n";
//添付ファイル
$files = array('images/test.gif');
//件名・本文をエンコード
$subject = mb_convert_encoding($subject, 'JIS', 'UTF-8');
$message = mb_convert_encoding($message, 'JIS', 'UTF-8');
$subject = '=?iso-2022-jp?B?' . base64_encode($subject) . '?=';
//バウンダリ文字列を定義
if (empty($files)) {
$boundary = null;
} else {
$boundary = md5(uniqid(rand(), true));
}
//メールボディを定義
if (empty($files)) {
$body = $message;
} else {
$body = "--$boundary\n";
$body .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
$body .= "Content-Transfer-Encoding: 7bit\n";
$body .= "\n";
$body .= "$message\n";
foreach($files as $file) {
if (!file_exists($file)) {
continue;
}
$info = pathinfo($file);
$content = $mime_content_types[$info['extension']];
$filename = basename($file);
$body .= "\n";
$body .= "--$boundary\n";
$body .= "Content-Type: $content; name=\"$filename\"\n";
$body .= "Content-Disposition: attachment; filename=\"$filename\"\n";
$body .= "Content-Transfer-Encoding: base64\n";
$body .= "\n";
$body .= chunk_split(base64_encode(file_get_contents($file))) . "\n";
}
$body .= '--' . $boundary . '--';
}
//メールヘッダを定義
$header = "X-Mailer: PHP5\n";
$header .= "From: $from\n";
$header .= "MIME-Version: 1.0\n";
if (empty($files)) {
$header .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
} else {
$header .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
}
$header .= "Content-Transfer-Encoding: 7bit";
//メール送信
if (mail($to, $subject, $body, $header)) {
echo 'メールが送信されました。';
} else {
echo 'メールの送信に失敗しました。';
}
?>
で、最後にdump.sqlとdump.zipをrmで削除する。
system("rm dump.sql");
system("rm dump.zip");
以上で正常に動作をしたのでこのphpファイルをcronで定期実行をしてバックアップをとる事にした。
また何かあれば追記をする。