カテゴリー別アーカイブ: プログラミング

[WordPress] シェル + cron でデータベースをバックアップする

ロリポップのレンタルサーバを使って WordPress を運用している場合の例です。
以下のスクリプトを backup.sh などのファイル名で保存し、FTP ソフトでサーバにアップロードします。
レンタルサーバが提供している cron 機能でスクリプトを定期的に実行するようにします。(私は毎日1回実行させています。)


#!/bin/sh

# Mysqlユーザ名
mysql_user=xxxxxxxx

# Mysqlユーザパスワード
mysql_pw=xxxxxxxx

# ホスト名
host_name=xxxxxxxx

# バックアップ先
save_dir=~/web/xxxxxxxx/backup/

# バックアップファイル名
bak=`date +%Y_%m_%d`

# バックアップするDB
mysql_db_name=xxxxxxxx

# バックアップファイルを残す数
max_save_count=3

mysqldump --opt -u $mysql_user --password=$mysql_pw -h $host_name $mysql_db_name > $save_dir$bak.sql
chmod 644 $save_dir$bak.sql

zip $save_dir$bak.sql.zip $save_dir$bak.sql

rm -rf $save_dir$bak.sql

file_count=`ls -F1 $save_dir | grep -v / | wc -l`
if [ $file_count -gt $max_save_count ] ; then
rm -rf $save_dir`ls -F1tr $save_dir | grep -v / | head -n 1`
fi

私の場合は、バックアップ先を WordPress インストールディレクトリ内にすることで、ファイルのバックアップ時に一緒にデータベースのバックアップもダウンロードしています。

robocopyコメンドでミラーリングバックアップ

windows7でディレクトリを効率よく完全にバックアップするスクリプト

大地震・暴風豪雨・大停電・ミサイル・隕石衝突・テポドン(w)など、あらゆる震災に備え、PCデータはバックアップをとり、物理的に離れた実家などに保管しておくのが私のルールです。

500GBのポータボーハードディスクを2つ購入し(コスパの良いBUFFALO HD-PVRU2を2つ購入)、バックアップファイルの入ったポータボーHDDが必ず1つは150km離れた実家に保管されている状態をとっています。
帰省する度に、最新のバックアップをとったポータボーHDDを実家へ持って行き、実家に保管してあったポータボーHDDを自宅へ持って帰ります。(企業並みの事業継続性!とはいかないけど、怠りません♪)

毎回のバックアップにあまりにも時間がかかるので、これまで効率の悪かったスクリプトを改修しました。(今までは、一度ドライブを空にしてからコピーしていました。そんなことをしていてはバックアップに何時間も費やすことになり、その間にちっさいテポドンが飛んできて家はほぼ無傷なのに運悪くPCのみに直撃して破壊されたら悔みに悔やみきれません。)

robocopy.exeで堅牢性の高いファイルコピー!

robocopy.exeは、Windows Vista/Windows Server 2008/Windows 7/Windows Server 2008 R2で用意されているOS標準コマンドです。安心して使えますね!
robocopyは、リモートのファイル・サーバ同士でフォルダを同期させるために作られたコマンドですから、ミラーリングコピーをしたい場合には打って付けですね。

それではまず、これまで使っていたスクリプトをお披露目します。(恥ずかしすぎて死にそうです)

ECHO OFF
ECHO;
ECHO F:が対象のドライブであるか確認します。
TIMEOUT /T 3 /NOBREAK > NUL
ECHO;
F:
SET filename="これはバックアップ用ドライブです.txt"
ECHO 「F:\%filename%」が存在するか確認します。。。
TIMEOUT /T 3 /NOBREAK > NUL
IF EXIST %filename% GOTO RM
ECHO %filename%が見つかりません!F:が対象ドライブではない可能性があります。
ECHO 「F:\%filename%」を作成してから再実行してください。
pause
EXIT

:RM
ECHO F:が対象のドライブであることを確認しました。
TIMEOUT /T 3 /NOBREAK > NUL
ECHO;
ECHO 10秒後にドライブを空にします。
TIMEOUT /T 10
RMDIR F:\backup /s /q
ECHO ドライブを空にしました。
TIMEOUT /T 3 /NOBREAK > NUL

ECHO 3秒後にバックアップを開始します。
TIMEOUT /T 3 /NOBREAK > NUL

XCOPY "K:\Users\ahoman\AppData\Local\Evernote\Evernote" "F:\backup\Evernote" /e /h /y /i

XCOPY "K:\仕事のファイル" "F:\backup\仕事のファイル" /e /h /y /i

XCOPY "K:\ユーザー\ahoman" "F:\backup\ユーザー\ahoman" /e /h /y /i

スクリプトの解説・・・
まず、ポータボーHDDを空にします。このとき、ドライブレター(「C:」や「D:」など)がいつもと変わっていてローカルのドライブを削除してしまったら大変です!なので、空にする対象のドライブが本当にバックアップ用ポータボーHDDかどうかをアナログな方法で調べています。
その方法が、ポータボーHDDのトップディレクトリに
「これはバックアップ用ドライブです.txt」
という名前の空ファイルを置いておく、という方法です。
ドライブにこのファイルが無ければスクリプトはそこで終了、ファイルが有ればドライブを空にするステップに進みます。
空にするまでに更に10秒間の猶予を与え(どんなけ慎重やねん!)、そして空にし、バックアップを開始します。

さて、こんなバックアップの仕方をしていたら寿命が3倍伸びても収入は3%くらいしか増えません。

そこで今回、robocopyコマンドを使って効率よくバックアップをとるスクリプトに改修したいと思います。

変更点は以下です。
・ドライブを空にするステップを削除する。
・XCOPYコマンドをROBOCOPYコマンドに変更する。

robocopy.exeの便利なオプションの1つに「/MIR」があります。このオプションを使えばミラーリングが可能です。新しいファイルはコピーし、更新されたファイルは上書きし、コピー元に無いファイルはコピー先から削除してくれます。つまり、この最小限の働きで全く同じディレクトリ構造を作るという最大限の結果をもたらしてくれる、まさにリオネル・メッシのようなコマンドなのです!
(私のPCなんてコマンドでmessiと入力するとrobocopyが実行されるようにしているんですから!)

では、改修後のスクリプトを見てみます。

ECHO OFF
ECHO;
ECHO F:が対象のドライブであるか確認します。
TIMEOUT /T 3 /NOBREAK > NUL
ECHO;
F:
SET filename="これはバックアップ用ドライブです.txt"
ECHO 「F:\%filename%」が存在するか確認します。。。
TIMEOUT /T 3 /NOBREAK > NUL
IF EXIST %filename% GOTO RM
ECHO %filename%が見つかりません!F:が対象ドライブではない可能性があります。
ECHO 「F:\%filename%」を作成してから再実行してください。
pause
EXIT

:RM
ECHO F:が対象のドライブであることを確認しました。
TIMEOUT /T 3 /NOBREAK > NUL
ECHO;
ECHO 10秒後にミラーリングを開始します。
TIMEOUT /T 10

ROBOCOPY "K:\Users\ahoman\AppData\Local\Evernote\Evernote" "F:\backup\Evernote" /MIR

ROBOCOPY "K:\仕事のファイル" "F:\backup\仕事のファイル" /MIR

ROBOCOPY "K:\ユーザー\ahoman" "F:\backup\ユーザー\ahoman" /MIR

一部のみの改修ですが、バックアップ時間がかなり短縮しました。
これまでは「あ、実家に帰ろ!」と突発的に思っても、バックアップに半日かかるので、結局バックアップをせず、故に事業継続性に不安がある状態が続いており、つまりテポドンの危機に少しだけ直面していたのですが、これからは帰省の支度をしている間にバックアップが完了するということになります。(普段から頻繁にミラーリングバックアップをしておけば、帰省直前のバックアップにかかる時間は更に短縮されますね!ま、面倒なのでしませんけど!w)

ロリポップ!(チカッパ)でcron+ssh+rsyncにハマった。

ssh経由でログインして実行すればうまくいくシェルスクリプトがcronでは動かない。
エラーメッセージは、「/usr/bin/rsync: Permission denied」
スクリプトの内容は、あるディレクトリ以下のファイルを別サーバに同期(バックアップ)。

以下のようなスクリプト
——————————
#!/bin/sh

/usr/bin/rsync -a –delete ~/test_dir/ example.com:~/test_dir
——————————

24時間ほどハマり、なんとか解決。
/usr/bin/rsyncを~/web/以下にコピーし、それを使う。
——————————
cp /usr/bin/rsync ~/web/bin/
——————————

修正後のシェルスクリプト
——————————
#!/bin/sh

~/web/bin/rsync -a –delete ~/test_dir/ example.com:~/test_dir
——————————

これでOK。

ちなみに、SSHの秘密鍵のパーミッションは600にすること。
開けすぎてもエラーになる。注意。

cron登録数1個で複数の間隔で実行する方法

レンタルサーバーによってはcronの登録数は1つだけー!みたいなのもよくありますが

実行したいスクリプトを呼び出す役割のcron用スクリプトを書けば複数の間隔で複数のスクリプトを実行することができます。

例えば、cronに登録するスクリプトを「cron.php」とかにした場合。この「cron.php」はサーバーが許す一番最小実行間隔で実行するとします。(例えば1分ごと)

これで「cron.php」は1分毎に実行されるので、あとはその中で条件分岐させて色んなタイミングでいろんなスクリプトを呼び出せばOKです。

例えば10分毎に一回実行したスクリプトがあるときは

switch(date('i')%10) {
 case 0:
  include(/home/xxxx/xxx/xxxx/oppai.php);
  break;
 case 1:
  ・・・・・・
  break;
}

の様に書きます。呼び出すスクリプトが大量にある場合は上記のようにswitch文でも使って実行時間をうまく分散させるのがレンタルサーバー様に嫌われないコツです。

▼うまく分散させる振り分けのサンプル
・毎分1回実行するもの→そのまま毎分実行させる(しかない。分散のしようがない)。
・10分毎に1回実行するもの→「分」の下一桁が6,7の時に実行(最大2個に分散できる)
・毎時1回実行するもの→「分」の下一桁が0,1,2,3,4,5の時に実行(最大36個に分散できる)
・1日1回実行するもの→「分」が58 の時に実行(時間毎に振り分ければ最大24個に分散できる)
・毎週1回 実行するもの→毎日2:59に実行(曜日毎に振り分ければ最大7個に分散できる)
※それぞれの間隔で実行したいスクリプトの量によって数字は微調整すればよい。

 

[ロリポップ!] PHPがブラウザでは動くが、cronでは動かない(ハマリ度約3時間)

3時間くらいハマリましたね。(見栄張ってるんで実際は5時間くらいハマってたと思います)

phpで書いたデータをDBに突っ込むプログラムが、

ブラウザでは実行できるんだけど、cronでは動かない。(実際にはプログラムは実行されてたんだけど、DBには突っ込まれていなかった、って感じ)

今回のハマりポイントは2つあります。

1つ目は、ロリポップ!のPHP設定でphp5.3を使用する設定していたんだけど、cronの場合はこの設定が反映されるわけではない。cronでphp5.3を使うにはパスを書く必要があった。プログラムの1行目に以下のように。(ロリポップ!cronの設定

#/usr/local/php5.3/bin/php

2つ目のポイントは、プログラムの中にphp5.3以降で有効になった記述方法を使っていたということ。この内容はコレです↓

$oppai = (get_oppai() ?: 0);

「三項演算子」というやつです。この、?と:の間を省略する形はphp5.3からできるようになった文法だったのです。そりゃオッパイゲットできなかったわけです。

なんでこのことに気づいたか。

それは、PHPのオンラインマニュアルで流し読みしていた時に瞬間視記憶としてある文章が頭に残っていたからです。その文章とは

「・・・・・・PHP 5.3 以降・・・・三項演算子のま・・・かの部分をな・・・・・・ともできる・・・・になりました。 ・・・・・・・・・・・・・」

これやーーーーーーって感じでした。

これ、たまたま気づけたけど、実際はもっとハマリ度高めだと思いますね。

 

レストランが作るこだわりの逸品から会議弁当やピザチェーンまで、出前・宅配の総合グルメサイト『ぐるなびデリバリー』

[PHP] クラス名、関数名、変数名の命名ルールのメモ

自分流の命名ルールを忘れてしまいがちなのでメモ。

【クラス名】・・・先頭及び各単語の頭文字を大文字に。
(例)
Layout
ResultsLayout
DataBaseDataManager

【関数名】・・・小文字で記述。単語はアンダーバーで繋ぐ。
(例)
get_details()
set_js_top()

【変数名】・・・小文字で記述。単語はアンダーバーで繋ぐ。
(例)
$price
$new_car_id

【定数】・・・大文字で記述。
(例)
$TAX
$MAX_WEIGHT

【ファイル名】・・・小文字で記述。単語はアンダーバーで繋いでもよい。
(例)
index.php
add_form.php
newcarresult.php