PHP

PHPとcronでデータベースを外部サーバーに自動バックアップしてみました。

2017/04/18

PHPとcronを使用してレンタルサーバーのデータベースを別のレンタルサーバーのデータベースに自動バックアップできないかと考えていたところ、方法が見つかりましたのでご紹介です。

概要

クライアントの基幹システムが動いているサーバーに、もし障害が発生したら業務が止まってしまう…。そんな不安から自動バックアップの方法を考えました。結構需要のある記事になるんじゃないかと思っています。データベースはMySQLを使用しています。

今回使用したレンタルサーバーは、元サーバーがエックスサーバー、backup用サーバーがヘテムルとなっています。PHPとcronが利用できるサーバーであれば他のレンタルサーバーでもおそらく同じ方法でバックアップが可能だと思います。

手順としては、
① 【元サーバー】cronでデータベースのSQLファイルをdump (出力)
② 【backup用サーバー】cronでPHPのftp_connect()を使用して元サーバーでdumpしたSQLファイルをbackup用サーバーに移す。
③ 【backup用サーバー】cronでSQLファイルをデータベースにインポートする。
以上になります。

※ここからの説明でいくつかファイル名が出てきますが、いずれもお好きなファイル名に変更していただいて大丈夫です。その場合はソース内も同じ名前に書き換えてください。

※SQLファイルを公開ディレクトリに置かないように気をつけましょう!

①cronでデータベースのSQLファイルをdump

SQLファイルのdumpにはシェルスクリプトを使用しました。シェルスクリプトについては今回は詳しく説明しませんが、興味のある方はGoogle先生に聞くか、ドットインストールの動画がとてもわかりやすいと思います。

mysite.confというファイルを作成し、サーバーの情報を書いておきます。
(大文字の部分は実際のサーバー情報に置き換えてください)

[client]
host = HOSTNAME
user = USERNAME
password = PASSWORD

次にexport.shというファイルを作成し、シェルスクリプトを記述します。
(1行目はシェルスクリプトの実行に必要なおまじないのようなものと思ってください)
(パス・DATABASENAMEの部分は実際のサーバー情報に置き換えてください)

#!/bin/bash
mysqldump --defaults-extra-file=/パス/mysite.conf DATABASENAME > ./backup.sql

続いて、エックスサーバーの管理画面からcronの設定を行います。

毎日4時にexport.shを実行するようにしています。

ここまでがSQLファイルをdumpする手順になります。

②cronでPHPのftp_connect()を使用して元サーバーでdumpしたSQLファイルをbackup用サーバーに移す。

以降はヘテムルでの作業になります。

cron.phpというファイルを作成してcronで実行し、先ほどエックスサーバーでdumpしたSQLファイルをヘテムルに移動させます。
(1行目とHOSTNAME・USERNAME・PASSWORD・パスの部分は実際のサーバー情報に置き換えてください)

#!/usr/local/php/5.6/bin/php
<?php

$host = 'HOSTNAME';
$user = 'USERNAME';
$pass = 'PASSWORD';
$conn_id = ftp_connect($host) or die("Couldn't connect to $host");

if (!@ftp_login($conn_id, $user, $pass)) {
  echo "Couldn't connect as $user";
}

ftp_pasv($conn_id, true) or die("Cannot switch to passive mode");

//取得ファイルのパスと、保存ファイルのパス
$get_file_name = "backup.sql";
$save_file_name = "/パス/" . date('Ymd') . ".sql";

$ret = ftp_nb_get($conn_id, $save_file_name, $get_file_name, FTP_BINARY);

while ($ret == FTP_MOREDATA) {
  // ダウンロードを継続する…
  $ret = ftp_nb_continue($conn_id);
}
if ($ret != FTP_FINISHED) {
 exit("can not download file to finish ".$get_file_name."<br>");
}

ftp_close($conn_id);

shell_exec("sh /パス/import.sh");

$get_file_nameはFTP接続をした直後のディレクトリを対象としていますので、他の場所にバックアップを行った場合はそこまでのパスを記述してください。$save_file_nameはフルパスを記述してください。うまくいけばバックアップ用サーバーに日付.sqlのファイル名でSQLファイルができます。

更にshell_execでシェルスクリプトを実行してバックアップ用サーバーのデータベースにSQLファイルをインポートします。

③cronでSQLファイルをデータベースにインポートする。

backup.confというファイルを作成し、バックアップ用サーバーの情報を書いておきます。
(大文字の部分は実際のサーバー情報に置き換えてください)

[client]
host = HOSTNAME
user = USERNAME
password = PASSWORD

次にimport.shというファイルを作成し、シェルスクリプトを記述します。
(1行目はexport.shと同じく、必要なおまじないのようなものと思ってください)
(パス・DATABASENAMEの部分は実際のサーバー情報に置き換えてください)

#!/bin/bash
mysql --defaults-extra-file=/パス/backup.conf DATABASENAME < /パス/`date +%Y%m%d`.sql

最後に先程作成したcron.phpをヘテムルの管理画面からcornで実行するように設定して完了です。

エックスサーバーのcronから少し時間をあけて、毎日4時半にimport.shを実行しています。

最後に…

少し駆け足の説明になってしまったかもしれませんので、不明点等あればお気軽にコメントください。それでは!

-PHP
-