LVMスナップショットを使用してMySQLデータベースをDigitalOceanスペースにバックアップする方法

提供:Dev Guides
移動先:案内検索

序章

定期的なデータベースのバックアップは、意図しないデータ損失イベントを防ぐための重要なステップです。 効果的なバックアップおよびリカバリ戦略の設計には、多くの場合、パフォーマンスへの影響、実装コスト、およびデータストレージコストと、リカバリ速度、データ整合性、およびバックアップカバレッジとのトレードオフが含まれます。 最適なソリューションは、リカバリポイントと時間目的およびデータベースの規模とアーキテクチャによって異なります。

このガイドでは、LVMスナップショットを使用して実行中のMySQLデータベースのライブ(または「ホット」)物理バックアップを実行する方法を示します。 次に、データを圧縮してDigitalOceanSpaceに保存します。

このチュートリアルで紹介する手順は、大規模なMySQLデータベース、ストレージエンジン(InnoDB、TokuDB、MyISAMなど)を組み合わせて使用するデータベース、およびLVMを使用して管理される複数のブロックストレージボリュームが接続されたデータベースサーバーに適しています。

まず、Ubuntu16.04サーバーがLVMスナップショットを取得してマウントできることを確認します。 次に、MySQLのデータディレクトリを含む論理ボリュームのLVMスナップショットを作成します。 次に、このスナップショットボリューム(凍結された論理ボリューム)をマウントし、MySQLデータディレクトリを圧縮してDigitalOceanSpacesに送信して保存します。 結論として、サンプルのリカバリシナリオについて簡単に説明します。

前提条件

このガイドを使用するには、次の前提条件を利用できる必要があります。

これらすべてを設定したら、このガイドを開始する準備が整います。

ステップ1—MySQLとLVMの構成を調査する

まず、MySQLデータディレクトリを見つけて、LVM構成に関する詳細をメモします。

MySQLdatadirを見つけます

MySQLデータディレクトリへのパスを見つけるには、次のコマンドを実行します。

mysqladmin -u root -p variables | grep datadir

プロンプトが表示されたら、MySQLrootパスワードを入力します。 次のような出力が表示されます。

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が実際にはmysql_dataと呼ばれるLVM論理ボリュームのマウントポイントであることがわかります。 ボリュームグループvg1のメンバーです。

ここで、LVMスナップショットを作成するためにボリュームグループvg1で十分な空き領域があることを確認する必要があります。

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   ]

1つのボリュームグループ(vg1)に1つの500GB物理ボリューム(/dev/sda)があることがわかります。 この物理ボリュームの475GBは論理ボリュームに割り当てられていますが、25GBはボリュームグループが自由に使用できます。

これは、vgdisplayコマンドを使用してvg1ボリュームグループを詳しく調べることで確認できます。

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 の行から、vg1ボリュームグループに475GBが割り当てられ、25GBが空いていることがわかります。 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サイズから、/dev/vg1/mysql_dataにある475GBの論理ボリュームmysql_dataが1つあることがわかります(vg1mysql_dataのボリュームグループ)。

要約すると、このチュートリアルで使用したUbuntu 16.04サーバーには、1つのボリュームグループ(vg1)をバックアップするために使用される1つの500GB物理ボリューム(/dev/sda)があり、そこから1つのボリュームを作成しました。 475GB論理ボリューム(mysql_data)。 これにより、ボリュームグループに25GBの空き領域が残り、これを使用してさらに論理ボリューム(およびスナップショット)を作成できます。

ハードウェアとLVMの構成は異なる可能性があります。 複数のブロックストレージデバイスが接続され、単一または複数のボリュームグループにプールされている場合があります。 それでも、特定の論理ボリュームのスナップショットを作成する手順は同じです。

このセクションに示されている一連のコマンドを使用すると、LVMとハードウェア構成の概要を理解できるはずです。

次のステップでは、LVMスナップショット用にデータベースサーバーを準備します。

ステップ2—LVMスナップショット用にサーバーを準備する

LVMスナップショットを安全に取得できるようにするには、バックアップおよびSpacesへのファイル転送中に発生する可能性のある書き込みまたは変更をカバーするのに十分なディスクスペースをプロビジョニングする必要があります。 データベースのサイズによっては、このバックアップが完了するまでに数時間かかる場合があるため、ここでは注意を怠るのが最善です。 バックアップの実行中にスナップショットボリュームの容量が不足すると、スナップショットボリュームが無効になり、一貫性のあるバックアップができなくなります。

前のステップで、プリンシパル論理ボリューム(mysql_data)を含むボリュームグループ(vg1)の空き容量が25GBしかないことを確認しました。 データベースのバックアップにかかる時間内に25GBの変更がディスクに書き込まれない場合もありますが、理想的には少なくとも100GBの安全マージンが必要です。 本番環境では、スケジュールされたバックアップウィンドウ中にディスクに書き込まれるデータの平均量を測定し、それに応じてスナップショットボリュームサイズをスケーリングすることがベストプラクティスになります。

vg1ボリュームグループに75GBのスペースを追加するには、ブロックストレージデバイスを接続するか、現在ドロップレットに接続されているボリュームのサイズを大きくします。 このチュートリアルでは、すでに接続されているブロックストレージボリュームを拡張します。 追加のブロックストレージボリュームの接続の詳細については、 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

別のpvscanを実行して、物理ボリュームが100GB大きくなったことを確認しましょう。

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スナップショットがアクティブな間は、ディスクへの書き込み時にパフォーマンスが低下します。 最初に、シミュレートされた負荷のある非本番データベースを使用してこの手順をテストし、この方法が本番デプロイメントで機能することを確認する必要があります。


次に、lvcreateを使用して、mysql_data論理ボリュームのスナップショットを作成します。 これを行う前に、データの一貫性を保証できるように、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スナップショットを作成してマウントします。

      1. スナップショットボリュームの作成とマウント

このMySQLクライアント接続を開いたまま、新しいターミナルウィンドウからデータベースサーバーにログインします。

警告:この接続を閉じると、ロックが破棄されて書き込みが再開され、スナップショットの一貫性が失われます。


これで、mysql_data論理ボリュームのスナップショットを作成できます。 物理バックアップを実行するときに、書き込みやその他の変更を吸収するために100GBのバッファースペースを割り当てます。 LVMスナップショットを作成するには、次のlvcreateコマンドを実行します。

sudo lvcreate -L 100G -s -n mysql_data_snap /dev/vg1/mysql_data

-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の概要を参照してください。