LVMスナップショットを使用してMySQLデータベースをDigitalOceanスペースにバックアップする方法
序章
定期的なデータベースのバックアップは、意図しないデータ損失イベントを防ぐための重要なステップです。 効果的なバックアップおよびリカバリ戦略の設計には、多くの場合、パフォーマンスへの影響、実装コスト、およびデータストレージコストと、リカバリ速度、データ整合性、およびバックアップカバレッジとのトレードオフが含まれます。 最適なソリューションは、リカバリポイントと時間目的およびデータベースの規模とアーキテクチャによって異なります。
このガイドでは、LVMスナップショットを使用して実行中のMySQLデータベースのライブ(または「ホット」)物理バックアップを実行する方法を示します。 次に、データを圧縮してDigitalOceanSpaceに保存します。
このチュートリアルで紹介する手順は、大規模なMySQLデータベース、ストレージエンジン(InnoDB、TokuDB、MyISAMなど)を組み合わせて使用するデータベース、およびLVMを使用して管理される複数のブロックストレージボリュームが接続されたデータベースサーバーに適しています。
まず、Ubuntu16.04サーバーがLVMスナップショットを取得してマウントできることを確認します。 次に、MySQLのデータディレクトリを含む論理ボリュームのLVMスナップショットを作成します。 次に、このスナップショットボリューム(凍結された論理ボリューム)をマウントし、MySQLデータディレクトリを圧縮してDigitalOceanSpacesに送信して保存します。 結論として、サンプルのリカバリシナリオについて簡単に説明します。
前提条件
このガイドを使用するには、次の前提条件を利用できる必要があります。
-
Ubuntu 16.04を使用したサーバーの初期設定で詳しく説明されている、sudo権限を持つ非rootユーザーのUbuntu16.04ドロップレット
-
Ubuntu 16.04にMySQLをインストールする方法で詳しく説明されている、実行中のMySQL5.7以降のインストール
-
MySQLデータベースのデータディレクトリを保存するために使用されるLVM論理ボリューム:
- LVMの詳細と論理ボリュームのセットアップ方法については、 LVMの概念、用語、および操作の概要を参照してください。
- MySQLのデータディレクトリをデフォルトから移動する方法の詳細
/var/lib/mysql
場所については、 MySQLDataDirectoryをUbuntu16.04の新しい場所に移動する方法を参照してください。
-
DigitalOceanスペースとAPIキーの作成方法で詳しく説明されているDigitalOceanスペースとAPIクレデンシャルのセット
-
s3cmd
DigitalOceanスペースを管理するためのs3cmd2.xの構成方法で詳しく説明されているように、スペースにアクセスするように構成されています。
これらすべてを設定したら、このガイドを開始する準備が整います。
ステップ1—MySQLとLVMの構成を調査する
まず、MySQLデータディレクトリを見つけて、LVM構成に関する詳細をメモします。
MySQLを探します datadir
MySQLデータディレクトリへのパスを見つけるには、次のコマンドを実行します。
- mysqladmin -u root -p variables | grep datadir
MySQLを入力してください root
プロンプトが表示されたらパスワード。 次のような出力が表示されます。
Output| datadir | /data/mysql/
このガイドで使用されているMySQLインストールの場合、データディレクトリは次のとおりです。 /data/mysql
.
今、それを確認する必要があります /data/mysql
LVM論理ボリューム上に存在します。 これを確認するために、実行します lsblk
:
- lsblk
次のような出力が表示されます。
OutputNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 600G 0 disk
└─vg1-mysql_data 252:0 0 475G 0 lvm /data
vda 253:0 0 160G 0 disk
├─vda1 253:1 0 159.9G 0 part /
├─vda14 253:14 0 4M 0 part
└─vda15 253:15 0 106M 0 part /boot/efi
これから私達はそれを観察します /data
実際には、と呼ばれるLVM論理ボリュームのマウントポイントです。 mysql_data
. ボリュームグループのメンバーです vg1
.
ボリュームグループで十分な空き容量があることを確認する必要があります vg1
LVMスナップショットを取得します。
LVM構成を調べる
このセクションで説明するコマンドからの出力は、サーバーのハードウェアとLVMの構成によって異なることに注意してください。 このガイドで使用されているUbuntu16.04サーバーのハードウェアとLVMの構成を簡単に調べてみましょう。
まず、使用している物理ボリュームの数を調べましょう pvscan
:
- sudo pvscan
次のような出力が表示されます。
Output PV /dev/sda VG vg1 lvm2 [500.00 GiB / 25.00 GiB free]
Total: 1 [500.00 GiB] / in use: 1 [500.00 GiB] / in no VG: 0 [0 ]
500GBの物理ボリュームが1つあることがわかります(/dev/sda
)これは1つのボリュームグループに含まれます(vg1
). この物理ボリュームの475GBは論理ボリュームに割り当てられていますが、25GBはボリュームグループが自由に使用できます。
これを確認するには、 vg1
を使用したボリュームグループ vgdisplay
指図:
- sudo vgdisplay
次のような出力が表示されます。
Output--- Volume group ---
VG Name vg1
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 2
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 1
Act PV 1
VG Size 500.00 GiB
PE Size 4.00 MiB
Total PE 127999
Alloc PE / Size 121600 / 475.00 GiB
Free PE / Size 6399 / 25.00 GiB
VG UUID KEsoDE-zON7-NdyO-ioxb-6FSl-CB4m-S3QCRj
Alloc PE /SizeおよびFreePE / Size の行から、475GBが割り当てられ、25GBが空きであることがわかります。 vg1
ボリュームグループ。 Cur PV 行は、このボリュームグループに1つの物理ボリュームがあることを示しています。 Cur LV 行は、このボリュームグループのスペースのプールを使用して1つの論理ボリュームを作成したことを示しています。
を使用してこの論理ボリュームを見てみましょう lvdisplay
:
- sudo lvdisplay
次のような出力が表示されます。
Output --- Logical volume ---
LV Path /dev/vg1/mysql_data
LV Name mysql_data
VG Name vg1
LV UUID T98x9c-zvC1-f0Rw-4ipn-Cxo2-duwk-KUwQQc
LV Write Access read/write
LV Creation host, time LVM, 2018-04-18 20:11:48 +0000
LV Status available
# open 1
LV Size 475.00 GiB
Current LE 121600
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 252:0
LVサイズから、475GBの論理ボリュームが1つあることがわかります。 mysql_data
、で見つかりました /dev/vg1/mysql_data
(それを思い出します vg1
の名前でした mysql_data
のボリュームグループ)。
要約すると、このチュートリアルで使用したUbuntu 16.04サーバーには、500GBの物理ボリュームが1つあります(/dev/sda
)1つのボリュームグループをバックアップするために使用されます(vg1
)、そこから単一の475GB論理ボリュームを作成しました(mysql_data
). これにより、ボリュームグループに25GBの空き領域が残り、これを使用してさらに論理ボリューム(およびスナップショット)を作成できます。
ハードウェアとLVMの構成は異なる可能性があります。 複数のブロックストレージデバイスが接続され、単一または複数のボリュームグループにプールされている場合があります。 それでも、特定の論理ボリュームのスナップショットを作成する手順は同じです。
このセクションに示されている一連のコマンドを使用すると、LVMとハードウェア構成の概要を理解できるはずです。
次のステップでは、LVMスナップショット用にデータベースサーバーを準備します。
ステップ2—LVMスナップショット用にサーバーを準備する
LVMスナップショットを安全に取得できるようにするには、バックアップおよびSpacesへのファイル転送中に発生する可能性のある書き込みまたは変更をカバーするのに十分なディスクスペースをプロビジョニングする必要があります。 データベースのサイズによっては、このバックアップが完了するまでに数時間かかる場合があるため、ここでは注意を怠るのが最善です。 バックアップの実行中にスナップショットボリュームの容量が不足すると、スナップショットボリュームが無効になり、一貫性のあるバックアップができなくなります。
前のステップで、ボリュームグループ(vg1
)主要な論理ボリュームを含む(mysql_data
)無料の25GBしかありませんでした。 データベースのバックアップにかかる時間内に25GBの変更がディスクに書き込まれない場合もありますが、理想的には少なくとも100GBの安全マージンが必要です。 本番環境では、スケジュールされたバックアップウィンドウ中にディスクに書き込まれるデータの平均量を測定し、それに応じてスナップショットボリュームサイズをスケーリングすることがベストプラクティスになります。
75GBのスペースを追加するには vg1
ボリュームグループの場合、ブロックストレージデバイスを接続するか、現在ドロップレットに接続されているボリュームのサイズを大きくすることができます。 このチュートリアルでは、すでに接続されているブロックストレージボリュームを拡張します。 追加のブロックストレージボリュームの接続の詳細については、 DigitalOceanBlockStorageの概要を参照してください。
注:一部のリージョンはまだブロックストレージをサポートしておらず、ブロックストレージボリュームをドロップレットに接続できない場合があります。 この場合の合理的な回避策は、ドロップレットのスナップショットを作成し、このスナップショットイメージを使用して新しいドロップレットを作成し、それにブロックストレージを追加することです。
このドロップレットに添付されているブロックストレージボリュームを拡張してみましょう。
DigitalOceanのWebコントロールパネルに移動し、ダッシュボードからドロップレットに移動します。
サイドバーで、ボリュームをクリックします。
このペインから、ドロップレットに接続されているブロックストレージボリュームが表示されます。 このガイドで使用されているUbuntuドロップレットには、1つのブロックストレージボリュームが接続されています。
その他をクリックしてから、ボリュームのサイズ変更をクリックします。
ここから、いくつかの事前定義されたボリュームサイズのいずれかを選択するか、独自のボリュームサイズを選択できます。 500GBのボリュームを100GBから600GBに増やしましょう。
続行を押します。 これで、接続されたブロックのストレージボリュームが100GB増加しました。
このデバイスの変更をLVMに伝播するには、実行する必要があります pvresize
.
サーバーにログインして、 pvscan
再度、物理ボリュームをスキャンします。
- sudo pvscan
以前と同じ出力が表示されます /dev/sda
物理的ボリューム:
Output PV /dev/sda VG vg1 lvm2 [500.00 GiB / 25.00 GiB free]
Total: 1 [500.00 GiB] / in use: 1 [500.00 GiB] / in no VG: 0 [0 ]
今、実行します pvresize
追加したばかりの余分なスペースを埋めるためにボリュームに:
- sudo pvresize /dev/sda
次の出力が表示されます。
OutputPhysical volume "/dev/sda" changed
1 physical volume(s) resized / 0 physical volume(s) not resized
別のファイルを実行して、物理ボリュームが100GB大きくなったことを確認しましょう pvscan
:
- sudo pvscan
私たちは、 /dev/sda
物理ボリュームは600GBになりました:
Output PV /dev/sda VG vg1 lvm2 [600.00 GiB / 125.00 GiB free]
Total: 1 [600.00 GiB] / in use: 1 [600.00 GiB] / in no VG: 0 [0 ]
ボリュームグループの空き容量も100GB増加したことを確認しましょう。
- sudo vgdisplay
次に、次の出力が表示されます。
Output --- Volume group ---
VG Name vg1
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 3
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 1
Act PV 1
VG Size 600.00 GiB
PE Size 4.00 MiB
Total PE 153599
Alloc PE / Size 121600 / 475.00 GiB
Free PE / Size 31999 / 125.00 GiB
VG UUID KEsoDE-zON7-NdyO-ioxb-6FSl-CB4m-S3QCRj
これは、スナップショットボリュームを作成するための125GBの空き容量があることを示しています。
このチュートリアルでは、バックアップとアップロードの手順で書き込みと変更を吸収するのに125GBで十分ですが、実稼働環境では、バックアップウィンドウで予想されるディスク使用量に比例してスナップショットのボリュームサイズをスケーリングする必要があります。
ボリュームグループに、スナップショットとバックアップ中に発生する可能性のある書き込みや変更をカバーするのに十分なスペースができたので、スナップショットボリュームの作成に進むことができます。
ステップ3—LVMスナップショットを作成してマウントする
警告: LVMスナップショットがアクティブな間は、ディスクへの書き込み時にパフォーマンスが低下します。 最初に、シミュレートされた負荷のある非本番データベースを使用してこの手順をテストし、この方法が本番デプロイメントで機能することを確認する必要があります。
次に、のスナップショットを作成します mysql_data
を使用した論理ボリューム lvcreate
. これを行う前に、を使用してデータベースへの書き込みをフリーズする必要があります FLUSH TABLES WITH READ LOCK
データの一貫性を保証できるようにします。 テーブルは、実行するまで読み取りロックする必要があるだけです。 lvcreate
、その時点でロックを解除できます。 この一連のコマンドをスクリプト化する場合、現在実行中の書き込みクエリに応じて、合計ロック時間は非常に短くなります。
ロックMySQLデータベースを読む
テーブルをフラッシュすることから始めましょう。 データベースサーバーのターミナルから、 mysql
MySQLデータベースにログインするには:
- mysql -u root -p
MySQLシェルから、 FLUSH TABLES
データベースを読み取りロックするコマンド。
警告:次のコマンドを実行すると、開いているすべてのテーブルが閉じられ、すべてのデータベースのすべてのテーブルがグローバル読み取りロックでロックされます。 これを本番データベースで実行する場合は、このコマンドをレプリカで実行するか、スクリプトの一部として実行して、データベースがロックされる時間を最小限に抑えることをお勧めします。
- FLUSH TABLES WITH READ LOCK;
次の出力が表示されます。
OutputQuery OK, 0 rows affected (0.00 sec)
これは、データベースがリードロックされていることを示しています。 MySQLプロンプトを終了しないでください。開いたままにしておく必要があります。
次に、MySQLデータを格納するために使用される論理ボリュームのLVMスナップショットを作成してマウントします。
###スナップショットボリュームの作成とマウント
このMySQLクライアント接続を開いたまま、新しいターミナルウィンドウからデータベースサーバーにログインします。
警告:この接続を閉じると、ロックが破棄されて書き込みが再開され、スナップショットの一貫性が失われます。
これで、スナップショットを撮ることができます mysql_data
論理ボリューム。 物理バックアップを実行するときに、書き込みやその他の変更を吸収するために100GBのバッファースペースを割り当てます。 LVMスナップショットを作成するには、以下を実行します lvcreate
指図:
sudo lvcreate -L 100G -s -n mysql_data_snap /dev/vg1/mysql_data
The -L
フラグは、論理ボリュームのサイズ(この場合は100GB)を指定します。 -s
論理ボリュームがスナップショットになることを示します。この場合は、 /dev/vg1/mysql_data
論理ボリューム。 このスナップショットボリュームに名前を付けることにしました mysql_data_snap
.
次の結果が表示されます。
OutputLogical volume "mysql_data_snap" created.
これは、 mysql_data
バックアップを実行できる論理ボリューム。
ある時点でMySQLデータファイルを本質的に「凍結」したので、データベーステーブルのロックを解除して書き込みを再開できます。 開いているMySQL接続から、次のコマンドを実行します。
- UNLOCK TABLES;
次の結果が表示されます。
OutputQuery OK, 0 rows affected (0.00 sec)
テーブルのロックが解除され、この接続を安全に閉じることができます。
この時点で、データベースはまだ稼働しており、着信接続と書き込みを受け入れていますが、実行した時点でのデータの一貫したスナップショットがあります。 FLUSH TABLES WITH READ LOCK
(または完全に正確に言うと、その後の最後の書き込みクエリの時点 FLUSH
完了)。
最後のステップは、これらのフリーズされたデータファイルにアクセスできるように、このスナップショットをマウントすることです。
まず、というマウントポイントを作成します /backup_src
:
- sudo mkdir /backup_src
次に、スナップショットボリュームをにマウントします /backup_src
:
- sudo mount /dev/vg1/mysql_data_snap /backup_src
これで、フリーズしたデータファイルにアクセスできます。 見てみましょう:
- cd /backup_src
- ls
MySQLデータディレクトリが表示されます。
Outputlost+found mysql
データの一貫したスナップショットにアクセスできるようになったので、データをDigitalOceanSpaceにバックアップできます。
ステップ4—ファイルを圧縮してDigitalOceanSpacesにアップロードする
このバックアップをDigitalOceanSpaceにアップロードするには、 s3cmd
前提条件の手順でインストールおよび構成したツール。
最初にテストします s3cmd
構成し、バックアップスペースへのアクセスを試みます(このチュートリアルでは、スペースの名前は mysql-backup-demo
):
- s3cmd info s3://mysql-backup-demo/
次の出力が表示されます。
Outputs3://mysql-backup-demo/ (bucket):
Location: nyc3
Payer: BucketOwner
Expiration Rule: none
Policy: none
CORS: none
ACL: 3587522: FULL_CONTROL
この出力は、接続が成功し、 s3cmd
オブジェクトをスペースに転送できます。
次に、MySQLデータディレクトリを圧縮してアップロードします。 mysql-backup-demo
スペース:
- sudo tar -czvf - /backup_src/mysql | s3cmd put - s3://mysql-backup-demo/mysql_backup_180423.tar.gz
ここでは、 tar
MySQLデータディレクトリを圧縮してアーカイブし、出力をにパイプします s3cmd
、圧縮されたアーカイブをSpacesに転送するために使用します。 圧縮アーカイブに名前を付けました mysql_backup_180423.tar.gz
.
使ったので tar
詳細モードでは、圧縮されているファイルのリストが表示されます(この出力を非表示にするには、 -v
上記のコマンドのフラグ)。
出力は、次のファイル転送情報で終了します。
Output...
upload: '<stdin>' -> 's3://mysql-backup-demo/mysql_backup_180423.tar.gz' [part 1, 1417kB]
1451996 of 1451996 100% in 0s 1993.41 kB/s done
転送が完了したら、スペースの内容を一覧表示して、ファイルがスペースに正常に転送されたことを確認します。
- s3cmd ls s3://mysql-backup-demo/
バックアップアーカイブファイルが表示されます。
Output2018-04-23 20:39 297 s3://mysql-backup-demo/mysql_backup_180423.tar.gz
この時点で、DigitalOceanSpacesへのMySQLの物理バックアップが正常に完了しました。
次に、スナップショットボリュームをアンマウントして削除し、使用済みスペースをボリュームグループに復元します。 vg1
.
ステップ5—スナップショットボリュームのマウント解除とドロップ
データがバックアップされたので、このチュートリアルの前半で作成したスナップショットボリュームは使用できなくなり、安全にドロップできます。
ボリュームをアンマウントするには、次のコマンドを実行します。
- sudo umount /backup_src
交換 /backup_src
スナップショットボリュームのマウントポイントを使用します。
これで、スナップショットボリュームを削除できます。 これを行うには、次のコマンドを実行します。
- sudo lvremove vg1/mysql_data_snap
ここ、 vg1
ボリュームグループ名に対応し、 mysql_data_snap
スナップショットボリューム名に。
削除の確認を求めるメッセージが表示されたら、Yと応答する必要があります。
次の出力が表示されます。
Output Logical volume "mysql_data_snap" successfully removed
スナップショットボリュームは正常に削除されました。 これで、MySQLの完全な物理バックアップが完了し、DigitalOceanSpaceにアップロードされました。
回復シナリオをすばやく実行して、このチュートリアルを終了します。
ステップ6—物理バックアップからの復元をテストする
以前にSpacesにアップロードした物理バックアップからMySQLデータベースを復元するには、バックアップをデータベースサーバーに転送し、抽出したファイルを復元したMySQLデータディレクトリとして使用します。
まず、バックアップをSpaceからデータベースサーバー上のユーザーのホームディレクトリに戻しましょう。
- s3cmd get s3://mysql-backup-demo/mysql_backup_180423.tar.gz ~/mysql_backup_180423.tar.gz
ファイル転送の出力が表示されるはずです。
Outputdownload: 's3://mysql-backup-demo/mysql_backup_180423.tar.gz' -> '~/mysql_backup_180423.tar.gz' [1 of 1]
1451889 of 1451889 100% in 0s 38.49 MB/s done
物理バックアップファイルからのクリーンな復元をテストするため、実行中のデータベースサーバーを停止し、既存のデータディレクトリを削除します。
まず、MySQLサーバーを停止します。
- sudo service mysql stop
次に、MySQLデータディレクトリの内容を削除します。
- sudo rm -rf /data/*
このチュートリアルでは、デフォルト以外のMySQLデータディレクトリパスは /data
.
次に、物理バックアップアーカイブをMySQLデータディレクトリに抽出します。
- sudo tar -xzvf ~/mysql_backup_180423.tar.gz -C /data
データファイルが復元されたので、MySQLデータベースを再起動して回復できるようにします。
- sudo service mysql start
最後に、データベースサーバーにログインして、復元が正常に完了したことを確認できます。
- mysql -u root -p
パスワードを入力すると、MySQLクライアントプロンプトが表示されます。
OutputWelcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.21-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
ここから、いくつかのテーブルをスキャンして、データが完全であることを確認できます。
結論
このチュートリアルでは、LVMのスナップショット機能を利用してファイルシステムをフリーズし、実行中のMySQLインスタンスの完全な物理バックアップと復元を実行する方法を示しました。 LVMを使用してMySQLデータを含む1つ以上のストレージボリュームを管理する場合、この機能は本番データベースをバックアップするための便利な方法を提供します。
実稼働環境では、この手順は、適切なログ記録、監視、およびアラートを使用してスクリプト化およびスケジュールするのが理想的です。 さらに、 FLUSH TABLES WITH READ LOCK
(どんなに短くても)マスターサーバーではなく、最小限にロードされたレプリカで実行する必要があります。 わずかな変更を加えるだけで、上記の手順を適用して、マスター物理バックアップからレプリカをすばやく起動することもできます。
MySQLインスタンスがストレージエンジンとしてInnoDBのみを使用している場合は、Percona XtraBackupを使用して、同様の方法でデータベースの物理バックアップを実行することもできます。 詳細については、 Ubuntu16.04でPerconaを使用してMySQLデータベースをオブジェクトストレージにバックアップする方法に関するチュートリアルを参照してください。
Spacesに物理バックアップファイルをアップロードする代わりの合理的な方法は、LVMスナップショットをドロップレットスナップショットと組み合わせて使用することです。 ドロップレットスナップショットの詳細については、DigitalOceanバックアップとスナップショットの説明を参照してください。
このガイドで使用されているオブジェクトストアであるDigitalOceanSpacesの詳細については、DigitalOceanSpacesの概要を参照してください。