はじめに
2019年07月22日にリリースされた MySQL8.0.17 で、新しく「CLONE」機能が実装されました。
同機能は、これまでのMySQLの運用方法(特にバックアップ)を大きく変える可能性があり、MySQLユーザからの反響も多いです。そこで、本ブログでも様々な観点から同機能について調査してみました。
1. 機能の概要
「CLONE」機能を端的に言えば、「既存のMySQLの全データを手軽にコピーする機能」です。ここでいう”全データ”とは、InnoDBのスキーマ、テーブル、テーブルスペース、データディクショナリのメタデータを一式含んだ、物理スナップショットのことを示しています。
コピーしたデータはそのままローカルに保存することもできますし、他のサーバに転送すれば全く同じMySQLを複製(クローン)することもできます。
2. 使い方
※ 以下で紹介するコマンドは、MySQL8.0.17時点のものです
CLONE機能を使用する場合は、まずMySQL8.0.17(もしくはそれ以降のバージョン)をインストールします。今回は dbdeployerを使って環境を構築します。このツールについては、過去のブログも参照してください。
1 2 3 4 5 |
$ dbdeployer unpack ./mysql-8.0.17-linux-glibc2.12-x86_64.tar.xz $ dbdeployer deploy multiple 8.0.17 --gtid --enable-general-log ... $ ls multi_msb_8_0_17/ clear_all n1 n2 n3 node1 node2 node3 restart_all sbdescription.json send_kill_all start_all status_all stop_all test_sb_all use_all |
次に、CLONE plugin をインストールする必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ multi_msb_8_0_17/use_all -e "INSTALL PLUGIN clone SONAME 'mysql_clone.so'" # server: 1 # server: 2 # server: 3 $ multi_msb_8_0_17/use_all -e "SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone'" # server: 1 PLUGIN_NAME PLUGIN_STATUS clone ACTIVE # server: 2 PLUGIN_NAME PLUGIN_STATUS clone ACTIVE # server: 3 PLUGIN_NAME PLUGIN_STATUS clone ACTIVE |
さらに、sysbenchを使ってテストデータを生成します。こちらも過去のブログで取り上げています。
–table-size=1000000(100万行)の時、テーブルあたり240MBくらいのデータサイズです。今回は sbtest と sbtest2 のデータベースに、それぞれ 10テーブル / 5テーブル ずつ作成します。
※ 以下のコマンドは node1 が127.0.0.1の25718ポートで稼働している前提です(情報はuseコマンドで確認できます)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash $ sudo yum -y install sysbench $ multi_msb_8_0_17/node1/use -u root -e "CREATE DATABASE sbtest" $ multi_msb_8_0_17/node1/use -u root -e "CREATE DATABASE sbtest2" $ sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=25718 \ --mysql-user=root --mysql-password=msandbox --mysql-db=sbtest \ --tables=10 --table-size=1000000 oltp_read_write \ prepare $ sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=25718 \ --mysql-user=root --mysql-password=msandbox --mysql-db=sbtest2 \ --tables=5 --table-size=1000000 oltp_read_write \ prepare $ ls -lh multi_msb_8_0_17/node1/data/sbtest/ | grep sbtest1 -rw-r----- 1 takahashi takahashi 240M 8月 27 11:30 sbtest1.ibd -rw-r----- 1 takahashi takahashi 240M 8月 27 11:38 sbtest10.ibd |
最後に動作検証のため、sbtest2上にMyISAMテーブルを作成します。
1 2 |
$ multi_msb_8_0_17/node1/use -e "CREATE TABLE sbtest2.my_test (id int) ENGINE = MyISAM" $ multi_msb_8_0_17/node1/use -e "INSERT INTO sbtest2.my_test VALUES (1),(2),(3)" |
2-1. バックアップ
まずはローカルにCLONEを作成してみましょう。コマンドは非常にシンプルです。
※ rootユーザ以外で実行する場合は、BACKUP_ADMIN権限を付与する必要があります
※ 保存先に指定したディレクトリが既に存在している場合、エラーとなります
※ mysqldの実行ユーザ(mysqlユーザ)が保存先ディレクトリへの書き込み権限を持っている必要があります
1 2 3 4 5 6 7 8 |
$ mkdir /tmp/cloned_data/ $ chmod 777 /tmp/cloned_data/ ### dbdeployerを使用している場合 $ sudo chown -R mysql:mysql /tmp/cloned_data/ $ time multi_msb_8_0_17/node1/use -u root -e "CLONE LOCAL DATA DIRECTORY '/tmp/cloned_data/first_clone/' " real 0m27.096s user 0m0.009s sys 0m0.011s |
これで /tmp/cloned_data/ の下にクローンデータが作成されました。実行時間も約27秒とそれほど長くありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ ls -lh /tmp/cloned_data/first_clone/ 合計 169M drwxr-x--- 2 takahashi takahashi 89 8月 27 16:18 #clone -rw-r----- 1 takahashi takahashi 5.4K 8月 27 16:18 ib_buffer_pool -rw-r----- 1 takahashi takahashi 48M 8月 27 16:18 ib_logfile0 -rw-r----- 1 takahashi takahashi 48M 8月 27 16:18 ib_logfile1 -rw-r----- 1 takahashi takahashi 12M 8月 27 16:18 ibdata1 drwxr-x--- 2 takahashi takahashi 6 8月 27 16:18 mysql -rw-r----- 1 takahashi takahashi 23M 8月 27 16:18 mysql.ibd drwxr-x--- 2 takahashi takahashi 197 8月 27 16:18 sbtest drwxr-x--- 2 takahashi takahashi 101 8月 27 16:18 sbtest2 drwxr-x--- 2 takahashi takahashi 28 8月 27 16:18 sys -rw-r----- 1 takahashi takahashi 11M 8月 27 16:18 undo_001 -rw-r----- 1 takahashi takahashi 11M 8月 27 16:18 undo_002 |
このディレクトリを datadir に指定することで、簡単に同じデータを持ったMySQL(=クローン)を作ることができます。dbdeployer の node2 で試してみましょう。
1 2 3 4 5 6 7 8 9 |
$ multi_msb_8_0_17/node2/stop $ vi multi_msb_8_0_17/node2/my.sandbox.cnf 以下のように書き換え datadir = .../multi_msb_8_0_17/node2/data ↓ datadir = /tmp/cloned_data/first_clone/ $ multi_msb_8_0_17/node2/start ... sandbox server started |
node1のデータがリストアされていることを確認します。なお、仕様上はMyISAMテーブルは対象外となるはずですが、my_testテーブルがリストアされていました。しかし、テーブル自体は空になっていたので、どうやらメタデータのみ含まれているようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ multi_msb_8_0_17/node2/use -u root -e "SHOW TABLES FROM sbtest2" +-------------------+ | Tables_in_sbtest2 | +-------------------+ | my_test | | sbtest1 | | sbtest2 | | sbtest3 | | sbtest4 | | sbtest5 | +-------------------+ $ multi_msb_8_0_17/node2/use -u root -e "SELECT * FROM sbtest2.my_test" → empty |
2-2. スレーブ追加
CLONE機能を使えば、手軽にレプリケーションスレーブを用意することもできます。
実際に、node1のデータを使ってnode3をスレーブとして設定してみましょう。
まずはnode1でレプリケーション用ユーザとCLONE用ユーザを作成します。どちらもnode3からアクセスできるよう接続元ホストを指定してください(dbdeployerの場合 127.0.0.1 になります)。
1 2 3 4 5 |
$ multi_msb_8_0_17/node1/use -u root -e "CREATE USER repl_user@127.0.0.1 IDENTIFIED BY 'replpass'" $ multi_msb_8_0_17/node1/use -u root -e "GRANT REPLICATION SLAVE ON *.* TO repl_user@127.0.0.1" $ multi_msb_8_0_17/node1/use -u root -e "CREATE USER clone_user@127.0.0.1 IDENTIFIED BY 'clonepass'" $ multi_msb_8_0_17/node1/use -u root -e "GRANT BACKUP_ADMIN ON *.* TO clone_user@127.0.0.1" |
次にスレーブとなるnode3側から、CLONEコマンドを実行します。この時、node1への接続情報をつけることで、node1からネットワーク経由で直接データを受け取ることができます(dbdeployerの場合はローカル上で完結します)。
また、別サーバからCLONEデータを受け取る場合は、先に clone_valid_donor_list 変数にサーバ情報を登録しておく必要があります。
※ root ユーザ以外で実施する場合は、CLONE_ADMIN権限が必要となります
1 2 3 4 5 6 7 |
$ multi_msb_8_0_17/node3/use -u root -e "SET GLOBAL clone_valid_donor_list = '127.0.0.1:25718' " $ time multi_msb_8_0_17/node3/use -u root -e "CLONE INSTANCE FROM clone_user@127.0.0.1:25718 IDENTIFIED BY 'clonepass' " real 0m48.270s user 0m0.011s sys 0m0.009s |
およそ48秒ほどで処理は完了しました。
GTIDレプリケーションを利用している場合は、この後に START SLAVE … MASTER_AUTO_POSITION=1 ; を実行するだけでレプリケーションが開始されます。
※ MySQL8.0のデフォルト認証プラグインである「caching_sha2_password」の仕様上、SSL通信を有効にする必要があります
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ multi_msb_8_0_17/node3/use -u root node3 [localhost:25720] {root} ((none)) > CHANGE MASTER TO MASTER_HOST="127.0.0.1", MASTER_PORT=25718, MASTER_AUTO_POSITION = 1, MASTER_SSL = 1, GET_MASTER_PUBLIC_KEY = 1, MASTER_PUBLIC_KEY_PATH='..(略)../multi_msb_8_0_17/node1/data/server-key.pem'; node3 [localhost:25720] {root} ((none)) > START SLAVE USER="repl_user" PASSWORD="replpass"; node3 [localhost:25720] {root} ((none)) > SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 127.0.0.1 Master_User: repl_user Master_Port: 25718 Connect_Retry: 60 Master_Log_File: Read_Master_Log_Pos: 4 Relay_Log_File: mysql-relay.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: Slave_IO_Running: Yes Slave_SQL_Running: Yes |
正常にレプリケーションが動作することを確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ multi_msb_8_0_17/node1/use -u root -e "CREATE TABLE sbtest2.repl_test (id int)" $ multi_msb_8_0_17/node3/use -u root -e "SHOW TABLES FROM sbtest2" +-------------------+ | Tables_in_sbtest2 | +-------------------+ | my_test | | repl_test | | sbtest1 | | sbtest2 | | sbtest3 | | sbtest4 | | sbtest5 | +-------------------+ $ multi_msb_8_0_17/node3/use -u root -e "STOP SLAVE" |
ちなみに、非GTIDレプリケーションを利用する場合は、CLONEデータのリストア後に performance_schema.clone_status テーブルを参照すれば、レプリケーションを開始すべきバイナリログポジションの情報を確認できます。
1 2 3 4 5 6 |
$ multi_msb_8_0_17/node3/use -u root -e "SELECT BINLOG_FILE, BINLOG_POSITION FROM performance_schema.clone_status" +------------------+-----------------+ | BINLOG_FILE | BINLOG_POSITION | +------------------+-----------------+ | mysql-bin.000003 | 906346956 | +------------------+-----------------+ |
2-3. Group Replication
CLONE機能は Group Replication でも利用することができます。具体的には、Clusterに新規追加するノードに対して既存データをリストアする方法がより効率的になります(※)。これは、Galera ClusterのSST機能と同じイメージです。
※ これまではmysqldumpで取得したフルバックアップをリストアするなど時間がかかっていました
まずは検証のため、dbdeployerで Group Replication のテスト環境を作成してみましょう。
ただし、Single Primaryモードの場合 node2とnode3 両方で super_read_only が有効になっているため、rootユーザであってもINSTALL PLUGINコマンドが実行できません。
そこで、今回は –my-cnf-options を使用して、my.cnf(my.sandbox.cnf)に “plugin-load-add=mysql_clone.so” を追記する方法を採用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ dbdeployer deploy --topology=group replication 8.0.17 --single-primary --my-cnf-options "plugin-load-add=mysql_clone.so" ... # Node 1 # select * from performance_schema.replication_group_members +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 00022718-1111-1111-1111-111111111111 | 127.0.0.1 | 22718 | ONLINE | PRIMARY | 8.0.17 | | group_replication_applier | 00022719-2222-2222-2222-222222222222 | 127.0.0.1 | 22719 | ONLINE | SECONDARY | 8.0.17 | | group_replication_applier | 00022720-3333-3333-3333-333333333333 | 127.0.0.1 | 22720 | ONLINE | SECONDARY | 8.0.17 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ # Node 2 # select * from performance_schema.replication_group_members ... $ group_sp_msb_8_0_17/use_all -e "SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone' " # server: 1 PLUGIN_NAME PLUGIN_STATUS clone ACTIVE # server: 2 PLUGIN_NAME PLUGIN_STATUS clone ACTIVE # server: 3 PLUGIN_NAME PLUGIN_STATUS clone ACTIVE |
node1(PRIMARY)に対して、sysbenchでテストデータをロードします。各種オプションは上でやったものと同じです。
1 2 3 4 5 6 7 8 9 10 11 |
$ group_sp_msb_8_0_17/node1/use -u root -e "CREATE DATABASE sbtest" $ group_sp_msb_8_0_17/node1/use -u root -e "CREATE DATABASE sbtest2" $ sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=22718 \ --mysql-user=root --mysql-password=msandbox --mysql-db=sbtest \ --tables=10 --table-size=1000000 oltp_read_write \ prepare $ sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=22718 \ --mysql-user=root --mysql-password=msandbox --mysql-db=sbtest2 \ --tables=5 --table-size=1000000 oltp_read_write \ prepare |
クラスタから node3 を切り離し、データを削除します。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ group_sp_msb_8_0_17/node3/use -u root -e "STOP GROUP_REPLICATION" $ group_sp_msb_8_0_17/node3/use -u root -e "SET GLOBAL super_read_only=OFF" $ group_sp_msb_8_0_17/node3/use -u root -e "DROP DATABASE sbtest" $ group_sp_msb_8_0_17/node3/use -u root -e "DROP DATABASE sbtest2" $ group_sp_msb_8_0_17/node1/use -u root -e "SELECT * FROM performance_schema.replication_group_members" +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 00022718-1111-1111-1111-111111111111 | 127.0.0.1 | 22718 | ONLINE | PRIMARY | 8.0.17 | | group_replication_applier | 00022719-2222-2222-2222-222222222222 | 127.0.0.1 | 22719 | ONLINE | SECONDARY | 8.0.17 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ |
レプリケーションの時と同じようにDONORとなるnode1からCLONEデータを受け取ります。この時、レプリケーション用ユーザ(兼 CLONE用ユーザ)を作成するのを忘れないでください。
1 2 3 4 5 |
$ group_sp_msb_8_0_17/node1/use -u root -e "CREATE USER repl_user@'127.0.0.1' IDENTIFIED BY 'replpass' " $ group_sp_msb_8_0_17/node1/use -u root -e "GRANT REPLICATION SLAVE, BACKUP_ADMIN ON *.* TO repl_user@'127.0.0.1' " $ group_sp_msb_8_0_17/node3/use -u root -e "SET GLOBAL clone_valid_donor_list = '127.0.0.1:22718' " $ group_sp_msb_8_0_17/node3/use -u root -e "CLONE INSTANCE FROM repl_user@127.0.0.1:22718 IDENTIFIED BY 'replpass' " |
その後、CHANGE MASTERコマンドを実行してから、GROUP REPLICATIONを開始します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ group_sp_msb_8_0_17/node3/use -u root node3 [localhost:22720] {root} ((none)) > CHANGE MASTER TO MASTER_USER='repl_user', MASTER_PASSWORD='replpass' FOR CHANNEL 'group_replication_recovery'; node3 [localhost:22720] {root} ((none)) > START GROUP_REPLICATION; Query OK, 0 rows affected (3.61 sec) node3 [localhost:22720] {root} ((none)) > SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 00022718-1111-1111-1111-111111111111 | 127.0.0.1 | 22718 | ONLINE | PRIMARY | 8.0.17 | | group_replication_applier | 00022719-2222-2222-2222-222222222222 | 127.0.0.1 | 22719 | ONLINE | SECONDARY | 8.0.17 | | group_replication_applier | 00022720-3333-3333-3333-333333333333 | 127.0.0.1 | 22720 | ONLINE | SECONDARY | 8.0.17 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ 3 rows in set (0.01 sec) |
この手順を使えば、簡単にGroup Replicationのノード追加を行うことができます。
MySQL Shell 8.0.17 のリリース情報によれば、MySQL Shell でも同バージョンからCLONE機能に対応しているようなので、MySQL InnoDB Clusterにおけるノードの運用・管理もかなり楽になるのではないでしょうか。
3. CLONE関連のパラメータ変数
CLONE機能の実装に伴い、新しいパラメータ変数が追加されています。マニュアルに記載された内容を以下の表にまとめました。
変数名 | デフォルト | 動的変更 | 説明 |
---|---|---|---|
clone_autotune_concurrency | ON | 可 | リモートCLONE実行時の動的スレッド生成を有効にします。 clone_max_concurrency変数でスレッドの最大数を設定できます。 clone_autotune_concurrencyが無効な場合、リモートCLONE実行した時点で最大数分のスレッドが生成されます。 |
clone_buffer_size | 4MB | 可 | CLONEデータを転送する際に使用される中間バッファのサイズを設定します。 デフォルトは4MiBです。 バッファーサイズを大きくすると、I/Oデバイスがデータを並列フェッチできるようになり、CLONEのパフォーマンスが向上します。 |
clone_ddl_timeout | 300 | 可 | CLONE実行時に、バックアップロックを取得するために待機する時間(秒)です。CLONEは、DDLと並列して実行できません。 バックアップロックは donor と recipient、両方のMySQLインスタンスで必要です。 CLONEはDDLが完了するのを待機します。 バックアップロックが取得されると、それ以降のDDLはCLONEの完了を待ちます。"0" を設定した場合は、CLONE実行時にバックアップロックを取得しなくなります。 この場合、クローン実行中にDDLが実行された場合、CLONE処理がエラーになります。 |
clone_enable_compression | 16 | 可 | リモートCLONE時の、ネットワークレイヤーのデータ圧縮を有効にします。 圧縮を有効にするとネットワーク帯域を節約できますが、CPUコストは上がります。 データの転送効率が向上する可能性があります。 |
clone_max_concurrency | 16 | 可 | リモートCLONE実行時に使用される並列スレッドの最大数を設定します。デフォルトは16スレッドです。 設定値を引き上げるとCLONEのパフォーマンスが向上しますが、MySQLに同時接続するクライアント接続数も圧迫されるため、既存のクライアント接続のパフォーマンスに影響が出る可能性があります。 リモートCLONEには、1スレッドあたり最小でも1MiBのデータ転送速度が推奨されます。このデータ転送速度は、clone_max_data_bandwidth変数によって制御されます。 |
clone_max_data_bandwidth | 0 | 可 | リモートCLONE実行時の1秒当たりの最大データ転送速度を MiB 単位で設定します。 この変数は、CLONEのパフォーマンスへの影響を制御するのに役立ちます。 donorインスタンスのディスクI/O帯域幅が上限に達し、パフォーマンスに影響が出ている時にのみ、制限を行うことが推奨されます。 "0"を設定すると"制限なし"となり、可能な範囲で最も高いデータ転送速度でCLONEを実行します。 データ転送速度の最小値は1スレッドあたり 1MiB/秒 です。 例えば、8スレッドあった場合は1秒間の最小転送速度は 8MiB/秒 になります。 clone_max_concurrency変数はリモートCLONEの最大スレッド数を制御します。 clone_max_data_bandwidth 変数によって設定されたデータ転送速度は、performance_schema.clone_progressテーブルのDATA_SPEEDカラムの値と異なる可能性があります。 |
clone_max_network_bandwidth | 0 | 可 | リモートCLONEにおける1秒あたりの最大ネットワーク転送速度を MiB 単位で設定します。 この変数は、ネットワーク上で行われるCLONE処理のパフォーマンスへの影響を制御するのに役立ちます。 donorインスタンスのネットワーク帯域幅が上限に達し、パフォーマンスに影響が出ている時にのみ、制限を行うことが推奨されます。 "0"を設定すると"制限なし"となり、ネットワーク上で可能な最も高いデータ転送速度でCLONEを実行します。 |
clone_ssl_ca | empty | 可 | 認証局 (CA)ファイルのパスを指定します。 リモートCLONEの接続を暗号化する場合に使用します。 |
clone_ssl_cert | empty | 可 | 公開鍵証明書ファイルのパスを指定します。 リモートCLONEの接続を暗号化する場合に使用します。 |
clone_ssl_key | empty | 可 | 秘密鍵ファイルのパスを指定します。 リモートCLONEの接続を暗号化する場合に使用します。 |
clone_valid_donor_list | empty | 可 | リモートCLONEを実行するうえで有効なdonorホストのIPアドレスを設定します。 次のようなカンマ区切りリストのフォーマットのみが有効です:"HOST1:PORT1,HOST2:PORT2,HOST3:PORT3"(スペースを入れることはできません) IPv6形式のIPアドレスはサポートされていません。 代わりに、IPv6アドレスへのエイリアスを使用できます。 IPv4アドレスはそのまま使用できます。 |
まとめ
以上、CLONE機能について簡単に見てきました。実際に使ってみた感想としては、コマンドの内容も分かりやすく、今後のMySQL運用の面ではかなり便利な機能だと思います。
今回は検証しきれませんでしたが、次回は以下のような内容についても調査したいと考えています。
- MySQL InnoDB ClusterにおけるCLONE機能の利用
- CLONE機能を使用するうえでのデメリット(制限)
- リモートCLONEが内部的に実行しているコマンド(具体的なデータ転送手段)
- CLONEと従来のバックアップツールの比較
→ こちらの記事に続きます