月別: 2015年7月

mysqlのバックアップ(mysqldump)のロック問題

こんにちは、はらぐちです。

今回お話したいのは、mysqlのバックアップ方法についてのあれこれです。

バックアップ mysqldump

mysqlのバックアップといえばmysqldumpです。
以下のような形で使います。

mysqldump -u root -p -x -A > my_dumpall.db

これで全データベースのダンプができます。
特定のデータベースをダンプしたい場合は、以下のようにデータベース名を指定します。

mysqldump -u root -p -x データベース名 > dump.sql

定期的にバックアップを取りたい場合は、シェルスクリプトで以下のようなものを
cronで実行してあげるといいでしょう。
二日間のバックアップを保持するスクリプト例です。

#!/bin/bash
MPASS=パスワード
mysqldump --defaults-extra-file=<(printf '[mysqldump]\npassword=%s\n' ${MPASS}) -u root -x -A > my_dumpall_`date +%Y%m%d`.db
OLDDATE=`date "-d2 days ago" +%Y%m%d`
rmfile=my_dumpall_$OLDDATE.db
if [ -e $rmfile ]; then
sleep 5m
rm -f $rmfile
fi

ちなみにリストアは以下のような形です。

mysql -u root -p < dump.sql
mysql -u root -p データベース名 < dump.sql

バックアップ datadirのコピー

mysqlのdatadirをOS上でコピーしてしまえばバックアップになります。

この方法の最大の利点は、リストアが非常に高速な事です。
通常のリストアはダンプファイル(SQL)をmysqlに渡す事で処理をするのでIndexの再作成などの処理もかかり、
mysqlのcpuがボトルネックとなってきますが、datadirによるリストアはdatadirのファイルを
そのまま置き換えてあげるだけですので、簡単かつ高速です。

しかし、同様に整合性の問題がありますので、mysqlを停止してからでなければいけないのが欠点です。
停止となるので完全に止まってしまいます。また、データベース単位でのバックアップなどはできません。

このバックアップ方法をとるのはサーバー移行などの高速なリストアが必要な時です。

mysqldumpのロック問題

mysqldumpコマンドのオプションで「-x」というものがありますが、
これはデータベースのすべてのテーブルをリードロックする、というものです。
データベースをリードロックすると参照系のクエリは発行できますが、
更新系のクエリはロックが解除されるまで待ち状態となります。
これはデータベースの整合性を保つ為に必要です。

しかし、サービス運用中ですと、この「更新系が待ち」になる事が許容できない事があります。
たかだか1Gくらいのデータベースですと、ミッションクリティカルなサーバーでない限り
ロックがかかる時間も少ないのでまだ許容できるかもしれませんが、
これが20GBほどのサイズとなると、30分ほどかかったりする事がざらにあります。

セッションをDBで管理してたりすると、すべてのユーザーがサービスを利用できなくなるというわけです。

ロック問題の解決策 single-transaction

データベースがすべて「innodb」であればシングルトランザクションオプションを使ったダンプを行う事で
ロックせずにバックアップする事ができます。

mysqldump -u root -p --single-transaction -A > my_dumpall.db

内部的にはスナップショットをとって、そのデータをダンプする事でロックする事なく
整合性のとれたダンプを取る事が可能です。
通常のmysqldumpと異なる点は、ダンプデータが「ダンプが終了した時の状態」ではなく
「ダンプを開始した時の状態」であるという点です。

ちなみに–master-data=2を付けるとbinlogファイルと位置の情報をdumpに含めてくれるので
レプリケーションslaveを作る際に大変重宝します。
この方法の最大の欠点はすべてのデータがinnodbである必要がある点です。
myisamなどのテーブルは整合性が取れなくなる可能性があります。

ロック問題の解決策
レプリケーションslaveにてdump

サーバーがもう一台必要ですがレプリケーションしたslaveサーバーにてバックアップを行うと、
ロックをかけてもサービスには影響を与えません。

ロック問題の解決策
LVMのスナップショットでdatadirをコピー

こちらは実際には行った事がないのですが、LVMのスナップショットで
datadirのスナップショットを取ってしまえばmysqlの停止なくバックアップ可能です。
ですが、スナップショット作成中は非常に負荷が高くなるそうで、
該当時間の書き込み処理の性能がガタ落ちするそうです。

一番いいのはsingle-transaction

日々のバックアップ用途であれば今までの運用の経験から「single-transaction」オプションでの
mysqldumpが一番よかったかなぁと思います。
これからサーバーでmysqlを使う時は、意識的に「InnoDBを使う」という事を心がけていくといいと思います。

デスクトップPC(Windows)が起動しない場合について

こんにちは、中氏です。

先日、普段自分が使用しているデスクトップPC(Windows)が
いきなり起動しなくなるという事態が起こりました。

しかし、一言に「起動しない」と言っても、原因はいろいろ考えられます。
パソコンを復活させるためにも、原因を探ってみました。

まず、パソコン本体やキーボードなどの電源が入るかどうか確認しました。
この時、全て入らなかったので、次に一度電源コードを抜きました。
パソコン本体に不必要な電気が帯電している場合、正常に起動しない場合があるので
帯電している電気を放出するといいそうです。これを放電といいます。
(コードを抜いてから1分以上放置し再び繋げるのがいいそうです。)

以前はこれで正常に動いたことがあったのですが、今回は動きませんでした・・・

「パソコンが起動できない場合の対処方法(Windows7)」参照

そこで、次にパソコン本体の中身を見てみると、埃がたくさん溜まっていました。
ファンにも埃がひっかかっていて、うまく動いていなかったようです。
きれいに除去して起動してみると、無事復旧できました。

自分と同じように、埃が原因でパソコンが動かなくなることもあるので
こまめに掃除をすることをおすすめします。
初めて分解するときは、壊しそうで少し抵抗があるかもしれませんが
ネジを2、3個外しフタを開けるだけで中身のほぼ全体を見ることができるので、意外と簡単です。

みなさんも、パソコンが起動しないときなどは参考にしてください。

EVMで出来高管理しよう

PMBOKPMPを勉強された方なら聞いたことあると思います。
今回は「EVM」についてご紹介したいと思います。

EVMってなんでしょう?
ということは、ググって見てもらえればわかります(笑)
一言でいえば、プロジェクトの出来高を数値化して管理する手法のひとつ
で、おしまい!なのですが、実際よくわからんし導入したところで何になるの?
と悩まれている方も多いと思います。

正直、私も導入したことがない(ないのかいっ!)のですが、これを機に
導入を検討したいと思います。

まずは、EVMで重要な要素についてです。

BAC・・・プロジェクトの総予算
PV・・・出来高計画値(計画時点で見積もった予算コスト)
AC・・・出来高実績値(現時点までに完了した作業の実コスト)
EV・・・出来高実績値(現時点までに完成した作業の予算コスト)

があります。もっといろいろありますが、その他は慣れてきたら
考えてみたらよいと思います。

そして、EVMの具体例をごくごくシンプルに説明すると
総予算100万のプロジェクトを、機能A4人日、機能B6人日を1人で10人日かけて作業するとします。
(1人でやる分にはプロジェクトといわないかもしれませんが、、)
この場合、BACは総予算なので、100万です。また1日あたりの出来高は10万となります。(100万÷10人日)
このプロジェクトの5日経過時点で、成果が機能A100%、機能B0%でかつ、残業して
機能A完成に、60万使ってしまったとすると
PV=50万、AC=60万、EV=40万となります。
これの意味するところは、

「5日経過時点で、50万の出来高予定だったが、実際は40万分の作業しかできていないにも
かかわらず、60万のコストを使ってしまった。」

ということになります。図化すればもっとわかりやすくなります。

というわけで、EVMの全部を理解しようとせずに、
わかるところから徐々に導入していったらいいと思います。
もっとざっくりいってしまえば、EVMに関わらずステークホルダが納得するような
数値の見せ方を自分なりに工夫して示せれば、OKと考えてます。

平文でわかりにくかったかもしれません、、が
ぜひご参考までに。

Form::select でvalueが空のoption項目を作る

fuelphpのFormクラスはいろいろと便利です。
その中でも、selectとradioはチェックをつけてくれたりするので大好きです。

Form::select – http://fuelphp.jp/docs/1.7/classes/form.html#/method_select

View内で以下のように書いたら、

[code]
<?
$arrGender = [1 => ‘男性’, 2 => ‘女性’];
$gender = 2;
echo Form::select(‘gender’,$gender,$arrGender,[‘class’ =>’form-control’]);
?>
[/code]

こんなhtmlを作ってくれます。

[code]
<select class=”form-control” name=”gender” id=”form_gender”>
<option value=”1″>男性</option<
<option value=”2″ selected=”selected”>女性</option>
</select>
[/code]

通常は$arrGenderの部分は別で定義しておきますし、
$genderの部分はModelあたりから取ってきたりPostされた値が入っています。

$arrGenderの配列に合わせてoption の部分を作ってくれて、
$genderのキーと一致するoptionにselectedを付けてくれます。超便利。

ですが、これだとユーザーが本当に値を選択したのかわからないので、入力が空ならエラーを出す形にしたい。
つまりこういうHTMLを出したい。

[code]
<select class=”form-control” name=”gender” id=”form_gender”>
<option value=””>選択してください</option>
<option value=”1″>男性</option>
<option value=”2″>女性</option>
</select>
[/code]

$arrGenderをこんな配列にしてやれば実現できました。

[code]
<?
$gender = null;
$arrGender = [” => ‘選択してください’, 1 => ‘男性’, 2 => ‘女性’];
echo Form::select(‘gender’,$gender,$arrGender,[‘class’ => ‘form-control’]);
?>
[/code]

© SEEDS Co.,Ltd.