(特にクラウド環境で)MySQL データベースを使って運用している皆さん、データのバックアップはどうしてますか?
色々な目的や用途、制限の中で使っているので正解は1つではないと思っています。中には「初めからバックアップ込みの DBaaS サービスを使っている」という人もいるでしょう。コスト的に問題なければそれがベストかもしれません。
自分の場合、ある環境では cron で一日一回 mysqldump で取り出した内容を圧縮してそのままオブジェクトストレージに丸投げ、という方法を採用していたりします。オブジェクトストレージにダンプデータが残っていれば、そこからリストアできる、という考え方です。ケースバイケースではあるし、クラウド業者のオプションとかにも依存はしますが、オブジェクトストレージは手軽に使えて、比較的安価な割にデータポータビリティの高いデータストレージなので、コスパ的にもあっていました。これだけだとダンプにないデータやダンプ後に変更があったデータは救えませんが、そこまでシビアなデータ管理を要求されることもないデータベースであれば、手軽なこの方法はオススメでもあります。
一方、データが失われてからリストアするのにあまり長い時間かかることが許されないような場合や、救えないデータがあってはまずい場合はこの方法は向きません。データベースサーバーを多重化するなどして「最悪、1台死んでもいい」環境を構築することになります。
最近、自分の管理している環境下で MySQL データベース(正確には MariaDB だったけど)の Master-Slave レプリケーション環境を構築する機会がありました。その時の作業を記録しておきます。
まず前提条件として、以下のような環境を想定します:
- MySQL 5.x サーバーが1台稼働中。レプリケーション設定はしていない。
- MySQL サーバーを新たにもう1台追加して、Master-Slave の2台構成にする。
- 現在使っているサーバーを Master、新たに追加するサーバーを Slave とする。
- レプリケーションの対象とするデータベースの名前は mydb とする。
以下、順に説明します。現在稼働中の MySQL サーバーを「A」と呼ぶことにします。このサーバーが Master サーバーになります。また、新たに追加する MySQL サーバーを「B」と呼ぶことにして、このサーバーを Slave サーバーとして運用します:
1. Slave 用 MySQL サーバー環境の構築(B)
Slave サーバーとなる新しい MySQL サーバー環境を構築します。この辺りを参照してください:
CentOS に MySQL をインストール/セットアップする
Slave 側にも MySQL 環境が構築できたら、mysql コマンドでレプリケーションを行う先のデータベースを作成しておきます。UTF-8 指定などは環境に合わせて適当に:
2. レプリケーション用ユーザーの作成(A)
MySQL コマンドを使って Slave が Master のバイナリログを参照する際に接続するユーザーを作成します。
この例ではユーザー名 repl、パスワード password で、192.168.1.XXX/24 環境からの接続のみ許可されたユーザーとしています:
3. Master 用の設定(A)
具体的には Master のバイナリロギングを有効にし、かつサーバーを識別するための ID を /etc/my.cnf 内に追加設定します(MariaDB の場合は /etc/my.cnf.d/server.cnf):
4. レプリケーション用ユーザーの作成(B)
MySQL コマンドを使って Slave 内にデータを複製するユーザーを作成します。この例ではユーザー名 repl、パスワード password としています:
5. Slave 用の設定(B)
サーバーを識別するための ID を /etc/my.cnf 内に追加設定します(MariaDB の場合は /etc/my.cnf.d/server.cnf)。この ID はシステム全体でユニークにする必要があるため、3. で設定した内容とは異なるものにします:
6. バイナリログ位置の確認(A)
Master 側サーバーの MySQL コマンドで以下を実行して、その結果をメモしておきます:
なお、"SHOW MASTER STATUS;" の実行結果が "Empty Set" と表示される場合は、File は ""(空文字)、Position は 4 とみなすことができるので、これらの値を後に使うことになります。
7. スナップショットの作成(A)
続いてこの状態のデータベースのスナップショットを取得します。6. で "FLUSH TABLES WITH READ LOCK" を実行しているのでデータベースにはロックがかかっています。この状態で別のコンソールやターミナルを使って以下のコマンドを実行します:
8. スナップショットのコピー(AまたはB)
7. で取得したスナップショットファイルを(mydbdump.db)、Slave サーバーとなる B に転送します。SFTP などを使って A から B へ送ってもいいし、B から A に取りに行ってもいいし、全く別の方法でも構いません。スナップショットファイルが B のディスク内にあって、9 のコマンドが実行できさえすればいい、ということです。
9. スナップショットの展開(B)
7. で取得した Master のスナップショットを Slave である B の mydb データベースに展開します:
10. Master 情報登録(B)
続いて MySQL コマンドで Slave に Master の情報を登録します:
11. レプリケーションスタート(B)
最後にレプリケーションを開始します:
スレーブを増やして、3台目以降の MySQL サーバーを構築する場合も同様にして行います。
環境によっては「初めから MySQL をクラスター環境で構築する」という選択肢もあります。そういう場合はこちらを参照してください:
CentOS に MySQL クラスター環境を構築する
色々な目的や用途、制限の中で使っているので正解は1つではないと思っています。中には「初めからバックアップ込みの DBaaS サービスを使っている」という人もいるでしょう。コスト的に問題なければそれがベストかもしれません。
自分の場合、ある環境では cron で一日一回 mysqldump で取り出した内容を圧縮してそのままオブジェクトストレージに丸投げ、という方法を採用していたりします。オブジェクトストレージにダンプデータが残っていれば、そこからリストアできる、という考え方です。ケースバイケースではあるし、クラウド業者のオプションとかにも依存はしますが、オブジェクトストレージは手軽に使えて、比較的安価な割にデータポータビリティの高いデータストレージなので、コスパ的にもあっていました。これだけだとダンプにないデータやダンプ後に変更があったデータは救えませんが、そこまでシビアなデータ管理を要求されることもないデータベースであれば、手軽なこの方法はオススメでもあります。
一方、データが失われてからリストアするのにあまり長い時間かかることが許されないような場合や、救えないデータがあってはまずい場合はこの方法は向きません。データベースサーバーを多重化するなどして「最悪、1台死んでもいい」環境を構築することになります。
最近、自分の管理している環境下で MySQL データベース(正確には MariaDB だったけど)の Master-Slave レプリケーション環境を構築する機会がありました。その時の作業を記録しておきます。
まず前提条件として、以下のような環境を想定します:
- MySQL 5.x サーバーが1台稼働中。レプリケーション設定はしていない。
- MySQL サーバーを新たにもう1台追加して、Master-Slave の2台構成にする。
- 現在使っているサーバーを Master、新たに追加するサーバーを Slave とする。
- レプリケーションの対象とするデータベースの名前は mydb とする。
以下、順に説明します。現在稼働中の MySQL サーバーを「A」と呼ぶことにします。このサーバーが Master サーバーになります。また、新たに追加する MySQL サーバーを「B」と呼ぶことにして、このサーバーを Slave サーバーとして運用します:
1. Slave 用 MySQL サーバー環境の構築(B)
Slave サーバーとなる新しい MySQL サーバー環境を構築します。この辺りを参照してください:
CentOS に MySQL をインストール/セットアップする
Slave 側にも MySQL 環境が構築できたら、mysql コマンドでレプリケーションを行う先のデータベースを作成しておきます。UTF-8 指定などは環境に合わせて適当に:
mysql > create database mydb character set utf8;
2. レプリケーション用ユーザーの作成(A)
MySQL コマンドを使って Slave が Master のバイナリログを参照する際に接続するユーザーを作成します。
この例ではユーザー名 repl、パスワード password で、192.168.1.XXX/24 環境からの接続のみ許可されたユーザーとしています:
mysql > GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.0/255.255.255.0' IDENTIFIED BY 'password';
3. Master 用の設定(A)
具体的には Master のバイナリロギングを有効にし、かつサーバーを識別するための ID を /etc/my.cnf 内に追加設定します(MariaDB の場合は /etc/my.cnf.d/server.cnf):
ここまで設定したら MySQL サーバー(A)を再起動します。# vi /etc/my.cnf [mysqld] log-bin=mysql-bin server-id=1001
4. レプリケーション用ユーザーの作成(B)
MySQL コマンドを使って Slave 内にデータを複製するユーザーを作成します。この例ではユーザー名 repl、パスワード password としています:
mysql > GRANT ALL PRIVILEGES ON *.* TO 'repl'@localhost IDENTIFIED BY 'password';
5. Slave 用の設定(B)
サーバーを識別するための ID を /etc/my.cnf 内に追加設定します(MariaDB の場合は /etc/my.cnf.d/server.cnf)。この ID はシステム全体でユニークにする必要があるため、3. で設定した内容とは異なるものにします:
ここまで設定したら MySQL サーバー(B)を再起動します。# vi /etc/my.cnf [mysqld] log-bin=mysql-bin server-id=1002
6. バイナリログ位置の確認(A)
Master 側サーバーの MySQL コマンドで以下を実行して、その結果をメモしておきます:
この結果の File がバイナリログ名、Position が現在位置です。これらの値は後に使います。mysql > FLUSH TABLES WITH READ LOCK; mysql > SHOW MASTER STATUS; +----------------------+-----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +----------------------+-----------+--------------+------------------+ | mysql-bin.000031 | 285 | | | +----------------------+-----------+--------------+------------------+
なお、"SHOW MASTER STATUS;" の実行結果が "Empty Set" と表示される場合は、File は ""(空文字)、Position は 4 とみなすことができるので、これらの値を後に使うことになります。
7. スナップショットの作成(A)
続いてこの状態のデータベースのスナップショットを取得します。6. で "FLUSH TABLES WITH READ LOCK" を実行しているのでデータベースにはロックがかかっています。この状態で別のコンソールやターミナルを使って以下のコマンドを実行します:
これで指定した mydb データベースのダンプを mydbdump.db というファイルに取得することができます。取得後は再度もう一つのターミナルに戻って以下のコマンドを実行し、ロックを解除します:# mysqldump -u root -p mydb --lock-all-tables > mydbdump.db
mysql > UNLOCK TABLES;
8. スナップショットのコピー(AまたはB)
7. で取得したスナップショットファイルを(mydbdump.db)、Slave サーバーとなる B に転送します。SFTP などを使って A から B へ送ってもいいし、B から A に取りに行ってもいいし、全く別の方法でも構いません。スナップショットファイルが B のディスク内にあって、9 のコマンドが実行できさえすればいい、ということです。
9. スナップショットの展開(B)
7. で取得した Master のスナップショットを Slave である B の mydb データベースに展開します:
# mysql -u repl -p mydb < mydbdump.db
10. Master 情報登録(B)
続いて MySQL コマンドで Slave に Master の情報を登録します:
なお、ここで指定する値ですが、MASTER_HOST は A のサーバー名(IPアドレス)、MASTER_USER は複製用(Aの)ユーザー、MASTER_PASS はそのパスワード、MASTER_LOG_FILE は 6. で取得した File の値、MASTER_LOG_POS は同 Position の値です。mysql > CHANGE MASTER TO MASTER_HOST='192.168.1.XXX', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000031', MASTER_LOG_POS=285;
11. レプリケーションスタート(B)
最後にレプリケーションを開始します:
これでレプリケーションがスタートする、はず。mysql > START SLAVE;
スレーブを増やして、3台目以降の MySQL サーバーを構築する場合も同様にして行います。
環境によっては「初めから MySQL をクラスター環境で構築する」という選択肢もあります。そういう場合はこちらを参照してください:
CentOS に MySQL クラスター環境を構築する
コメント
コメント一覧 (2)