web-dev-qa-db-ja.com

22 GBのMySQLデータベースを毎日バックアップする

現在、mysqldumpを使用してバックアップを実行できます。しかし、私はWebサーバーを停止する必要があり、バックアップを実行するには約5分かかります。 Webサーバーを停止しないと、時間がかかり、終了しません+バックアップ中にWebサイトにアクセスできなくなります。

私の22 GBのデータベースと成長中のデータベースをバックアップするためのより速い/より良い方法はありますか?

すべてのテーブルはMyISAMです。

28
unknown (yahoo)

はい。

2番目のマシンへのレプリケーションをセットアップします。バックアップを行う必要がある場合は、セカンダリマシンをロックし、mysqlhotcopyまたはmysqldumpを実行してから、ロックを解除できます。マスターに追いつくので、マスターをオフラインにする必要はありません。

書き込みI/Oを2倍にしてもかまわない場合は、同じマシンでこれを実行することもできますが、理想的には、2番目の物理サーバーにリアルタイムでバックアップし、必要なだけスナップショットバックアップを作成する必要があります。本番サーバーに影響を与えることなく。

理論的には、既知の状態とバイナリログを使用してデータベースを復元することもできます。私はそれをやったことがないので、まず調査してください。しかし、データベースの既知の状態をバックアップしてから、すべての新しいバイナリログをバックアップし、復元する必要がある場合はそれらを再生することができます。 binlogは線形に書き込まれるため、リモートコンピューターへの新しいbinlogのrsyncは非常に高速になります。

編集:確かに、バックアップにバイナリログを使用することが文書化されているようです。

この質問は関連性が高いです

28
John Douthat

OSがLinuxであると仮定してすみません。 LVMを使用していない場合は、使用する必要があります。もしそうなら、これはスナップショットを介してバックアップを作成する非常に簡単な方法です。

# Define these vars to meet your needs. These meet mine.
lvol="/dev/VolGroup03/lvol0"
snap_name="nightly_snapshot"
snap_vol="$(dirname $lvol)/$snap_name"
snap_path="/mnt/$snap_name"
snap_size="10g" # Not the size of your data, anticipated data changes during the backup
backup_path="/backups/$snap_name"

/usr/bin/time -f 'Databases were locked for %E' -- \
mysql <<- MYSQL
# based on http://pointyhair.com/tiki-view_blog_post.php?blogId=1&postId=5
FLUSH TABLES WITH READ LOCK;
\! lvcreate --size $snap_size --snapshot --name $snap_name $lvol
UNLOCK TABLES;
MYSQL
mount $snap_vol $snap_path
rsync -av --delete $snap_path/mysql $backup_path/
umount $snap_path
lvremove -f $snap_vol

これにより、スレーブサーバーを追加しなくても、毎晩バックアップを作成できます。私は高可用性のためにスレーブサーバーを用意することに非常に賛成ですが、そのスレーブを作成できるようになるまでスタックしていると思わないでください。

5
Bruno Bronosky

読み取りロック付きのFLUSH TABLESは、本番システムで定期的(または準定期的)に実行したいものではありません。それは最後の手段であるべきです。

少なくとも2つのレプリケーションスレーブをセットアップします(もちろん、これには、読み取りロック付きのFLUSH TABLESが必要になります)。いったん設定したら、もう一方を予備のマスターとして同期したまま、一方をバックアップから外すことができます。

また、スレーブの1つに障害が発生した場合は、そのスナップショットを使用して2番目(または3番目)のスレーブを再構築できます。すべてのスレーブが失敗した場合、読み取りロック付きのFLUSH TABLESに戻ります。

データが定期的に同期していることを定期的にチェックするプロセスがあることを忘れないでください-これを行うにはmk-table-checksumなどを使用します(これは設定するのは簡単ではありません。詳細はMaatkitのドキュメントを参照してください)。

22 GBは比較的小さいため、これを実行しても問題はありません。大規模なデータベースでこれを行うと、さらに問題が生じる可能性があります。

2
MarkR

上記のように、ここでの解決策は2つあります。

  1. オフラインにすることができるスレーブへのサーバーのレプリケーションを設定します。これを行う最良の方法は、mysqldumpと--master-dataパラメーターを使用してデータベースのダンプを取得することです。
  2. スレーブで毎晩のバックアップをセットアップします。 --master-data --flush-logsおよび--single-transactionフラグを指定してmysqldumpを使用するか、またはmysqlサーバーを停止してディスク上のデータファイルをコピーし、再起動することができます(レプリケーションは、中断しました)。
  3. スレーブでスクリプトを実行して(例:5、10、20分)、mysqlがまだ複製されていることを確認します。私はそれを行うために simple python script と書きましたが、これを使用することを歓迎します。

テーブルにInnoDBを使用している場合は、-single-transactionフラグを使用して、テーブルロックを行わなくても、マスター上でもデータベースの一貫したダンプを取得できるため、バックアップなしでバックアップを実行できます。サーバーを停止します。ただし、上記のソリューションの方が優れています。

また、LinuxでLVMを使用している場合は、パーティションのLVMスナップショットを取得して、それをバックアップできます。 LVMスナップショットはアトミックであるため、「読み取りロックでテーブルをフラッシュ」し、スナップショットを取得してロックを解除すると、一貫したスナップショットが得られます。

I/Oの競合が原因でダンプに時間がかかりすぎることが心配な場合は、3台目のマシンを追加して、ネットワーク上でmysqldumpを実行し、ディスクのスラッシングを回避できます。

1
Dan Udey

段階的なバックアップを実行できます。 1時間ごとにレコードの1/24をバックアップします。このアプローチの唯一の問題は、それが1日の最初の数時間の間にクラッシュした場合、その時間からクラッシュの時間まで何も失うことです。どちらの方法でも、失われるレコードは24時間未満です(あなたにとってそれがどれほど重要かはわかりません)。

0
musicfreak

環境によっては、スナップショットは通常、最適な方法です。特に、何らかの理由でマスターをバックアップする必要がある場合。マスターとスレーブのペアを実行し、両方でスナップショットバックアップを使用します。

  1. FLUSH TABLES WITH READ LOCK;
  2. データベースとログファイルシステムのスナップショットをプルします。
  3. UNLOCK TABLES;
  4. 自由にスナップショットからデータファイルをコピーします。

InnoDBテーブルでは、読み取りロックを実行する前にSET AUTOCOMMIT=0;を実行する必要があります。

0
jasonjwwilliams

本番MySQLデータベースをバックアップするためのベストプラクティス 」をご覧ください。これはスタックオーバーフローに関する同様の投稿です。

0
Charles Faiga