web-dev-qa-db-ja.com

ZFSスナップショットを介したMySQLデータベースのバックアップ

これを正確に行うことについて話している多くのサイトを見つけましたが、いくつかの重要な詳細がありません。一般的な手順は次のとおりです

  • FLUSH TABLES WITH READ LOCKを実行します
  • ZFSスナップショットを取得する
  • UNLOCK TABLESを実行します

さまざまなソースから、私が使用しているInnoDBが実際にFLUSHを尊重していないことが報告されています。 MySQLユーザーマニュアルでは、InnoDBで使用するためのFLUSH TABLES...FOR EXPORTバリアントがあると記載されていますが、データベース全体をバックアップするのではなく、各テーブルを個別に指定する必要があります。テーブルのリストが実際に存在するテーブルと同期しなくなる可能性がかなりあるため、各テーブルを個別に指定することは避けたいと思います。

もう1つの問題は、mysql -h"$Host" -u"$USERNAME" -p"$PASSWORD" --execute="FLUSH TABLES WITH READ LOCK"のようなことをするつもりです。ただし、これにより、セッションが終了した直後にロックが解除されます。これは理にかなっていますが、スナップショットを撮るときに読み取りロックを保持する必要があるため、かなり煩わしいです。

私のもう1つのアイデアは、Percona XtraBackupなどのツールを使用してホットバックアップを作成し、バックアップのスナップショットを作成することですが、スナップショットを作成するだけのために、すべてのデータを2番目の場所に書き込むコストを負担したくありません。

13
Andy Shulman

すべてのテーブルにInnoDBのみを使用し、innodb_flush_log_at_trx_commitを次のように設定した場合:

  • 1(InnoDBログバッファーの内容は、トランザクションコミットごとにログファイルに書き込まれ、ログファイルはディスクにフラッシュされます)または、
  • 2(各トランザクションのコミット後にInnoDBログバッファーの内容がログファイルに書き込まれ、ログファイルが約1秒に1回ディスクにフラッシュされます)、

スナップショットを作成する前にFLUSH TABLESは必要ありません。ZFSスナップショットを直接実行するだけです。 InnoDBは、データを失うことなくトランザクションコミットログからデータを回復できます。

参照: https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit

4
Gea-Suan Lin

(ほとんどの)データベースを一貫してバックアップするには、完全なデータベースロックが必要です。

マニュアル https://dev.mysql.com/doc/refman/5.5/en/backup-methods.html は言う読み取りロック付きのフラッシュテーブルはZFSスナップショットに対して正しい具体的に。

ファイルシステムのスナップショットを使用したバックアップの作成

Veritasファイルシステムを使用している場合は、次のようなバックアップを作成できます。

  1. クライアントプログラムから_FLUSH TABLES WITH READ LOCK_を実行します。
  2. 別のシェルから、mount vxfsスナップショットを実行します。
  3. 最初のクライアントから_UNLOCK TABLES_を実行します。
  4. スナップショットからファイルをコピーします。
  5. スナップショットをアンマウントします。

同様のスナップショット機能は、LVMやZFSなどの他のファイルシステムで使用できる場合があります。

とんでもないことですこれらの指示から、InnoDBに_FLUSH TABLES table_a, table_b, table_c FOR EXPORT_が必要であるという事実が除外されたことがわかります。そのように各テーブルを指定しなければならないのも愚かです。しかし、EEAAが言うように、バックアップをかなり簡単に開始するときに、テーブルのリストを生成できます。

ロックの保持に関しては、スナップショットの実行中はdb接続をアクティブに保つ必要があります

一般的には、Perlのようなもの、または接続してdbをロックし、db接続を維持しながらスナップショットを取得してロックを解除して切断できる別のプログラミング言語を使用します。複雑ではありません。私はすでにこれを行うツールが世に出ていると思いますが、それを書くのは簡単です。

簡単ではない、複雑ではない、等々。基本的なプログラミングまたは優れたスクリプティングスキルがあることを前提としています。

13
Ryan Babchishin

私は別のサーバー障害 post によって Tobia で見つかったBashの概念的に単純なスクリプトを取り除き、適応させました。そこまでの道の約90%を取得する必要があります。

mysql_locked=/var/run/mysql_locked

# flush & lock MySQL, touch mysql_locked, and wait until it is removed
mysql -hhost -uuser -ppassword -NB <<-EOF &
    flush tables with read lock;
    delimiter ;;
    system touch $mysql_locked
    system while test -e $mysql_locked; do sleep 1; done
    exit
EOF

# wait for the preceding command to touch mysql_locked
while ! test -e $mysql_locked; do sleep 1; done

# take a snapshot of the filesystem, while MySQL is being held locked
zfs snapshot zpool/$dataset@$(date +"%Y-%m-%d_%H:%M")

# unlock MySQL
rm -f $mysql_locked

ここで、使用するmysqlコマンドはバックグラウンドで実行され、ファイルにアクセスします。ファイルが消えるのをバックグラウンドで待ってから、終了してテーブルをロック解除します。その間、メインスクリプトはファイルが存在するまで待機し、スナップショットを作成してファイルを削除します。

$mysql_lockedが指すファイルは、両方のマシンからアクセスできる必要があります。両方のマシンが共通のデータセットにアクセスできるため、簡単に実行できるはずです(異なるパスを使用する可能性があるため、これを考慮する必要があります)。 。

7
Michael Hampton

Myisamはジャーナリングではないため、FLUSH TABLES WITH READ LOCKが必要です。

IMOはジャーナリングであるため、実際にはinnodbには何も必要ありません。とにかく一貫性があり、スナップショットを作成したアトミックな瞬間に何かが発生した場合は、ジャーナルを自動的にロールバックするだけです。

アプリケーションレベルの一貫性が必要な場合は、アプリケーションでトランザクションを使用する必要があります。アプリケーションがトランザクションとinnodbを使用している場合、スナップショットはアプリケーションレベルまで自動的に一貫性を保ちます。

2
Jim Salter

これは、ロックを維持しながらZFSスナップショットを作成する方法です。

mysql << EOF
    FLUSH TABLES WITH READ LOCK;
    system zfs snapshot data/db@snapname
    UNLOCK TABLES;
EOF
2
Petr Stastny