スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQL8.0.17で導入されたCLONEプラグインについて

はじめに

2019年07月22日にリリースされた MySQL8.0.17 で、新しく「CLONE」機能が実装されました。

リリースノート
公式リファレンスマニュアル

同機能は、これまでのMySQLの運用方法(特にバックアップ)を大きく変える可能性があり、MySQLユーザからの反響も多いです。そこで、本ブログでも様々な観点から同機能について調査してみました。

1. 機能の概要

「CLONE」機能を端的に言えば、「既存のMySQLの全データを手軽にコピーする機能」です。ここでいう”全データ”とは、InnoDBのスキーマ、テーブル、テーブルスペース、データディクショナリのメタデータを一式含んだ、物理スナップショットのことを示しています。

コピーしたデータはそのままローカルに保存することもできますし、他のサーバに転送すれば全く同じMySQLを複製(クローン)することもできます。

2. 使い方

※ 以下で紹介するコマンドは、MySQL8.0.17時点のものです

CLONE機能を使用する場合は、まずMySQL8.0.17(もしくはそれ以降のバージョン)をインストールします。今回は dbdeployerを使って環境を構築します。このツールについては、過去のブログも参照してください。

次に、CLONE plugin をインストールする必要があります。

さらに、sysbenchを使ってテストデータを生成します。こちらも過去のブログで取り上げています。

–table-size=1000000(100万行)の時、テーブルあたり240MBくらいのデータサイズです。今回は sbtest と sbtest2 のデータベースに、それぞれ 10テーブル / 5テーブル ずつ作成します。

※ 以下のコマンドは node1 が127.0.0.1の25718ポートで稼働している前提です(情報はuseコマンドで確認できます)

最後に動作検証のため、sbtest2上にMyISAMテーブルを作成します。

2-1. バックアップ

参照マニュアル

まずはローカルにCLONEを作成してみましょう。コマンドは非常にシンプルです。

※ rootユーザ以外で実行する場合は、BACKUP_ADMIN権限を付与する必要があります
※ 保存先に指定したディレクトリが既に存在している場合、エラーとなります
※ mysqldの実行ユーザ(mysqlユーザ)が保存先ディレクトリへの書き込み権限を持っている必要があります

これで /tmp/cloned_data/ の下にクローンデータが作成されました。実行時間も約27秒とそれほど長くありません。

このディレクトリを datadir に指定することで、簡単に同じデータを持ったMySQL(=クローン)を作ることができます。dbdeployer の node2 で試してみましょう。

node1のデータがリストアされていることを確認します。なお、仕様上はMyISAMテーブルは対象外となるはずですが、my_testテーブルがリストアされていました。しかし、テーブル自体は空になっていたので、どうやらメタデータのみ含まれているようです。

2-2. スレーブ追加

参照マニュアル

CLONE機能を使えば、手軽にレプリケーションスレーブを用意することもできます。
実際に、node1のデータを使ってnode3をスレーブとして設定してみましょう。

まずはnode1でレプリケーション用ユーザとCLONE用ユーザを作成します。どちらもnode3からアクセスできるよう接続元ホストを指定してください(dbdeployerの場合 127.0.0.1 になります)。

次にスレーブとなるnode3側から、CLONEコマンドを実行します。この時、node1への接続情報をつけることで、node1からネットワーク経由で直接データを受け取ることができます(dbdeployerの場合はローカル上で完結します)。

また、別サーバからCLONEデータを受け取る場合は、先に clone_valid_donor_list 変数にサーバ情報を登録しておく必要があります。

※ root ユーザ以外で実施する場合は、CLONE_ADMIN権限が必要となります

およそ48秒ほどで処理は完了しました。
GTIDレプリケーションを利用している場合は、この後に START SLAVE … MASTER_AUTO_POSITION=1 ; を実行するだけでレプリケーションが開始されます。

※ MySQL8.0のデフォルト認証プラグインである「caching_sha2_password」の仕様上、SSL通信を有効にする必要があります

正常にレプリケーションが動作することを確認します。

ちなみに、非GTIDレプリケーションを利用する場合は、CLONEデータのリストア後に performance_schema.clone_status テーブルを参照すれば、レプリケーションを開始すべきバイナリログポジションの情報を確認できます。

2-3. Group Replication

参照マニュアル
参照マニュアル2

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” を追記する方法を採用します。

node1(PRIMARY)に対して、sysbenchでテストデータをロードします。各種オプションは上でやったものと同じです。

クラスタから node3 を切り離し、データを削除します。

レプリケーションの時と同じようにDONORとなるnode1からCLONEデータを受け取ります。この時、レプリケーション用ユーザ(兼 CLONE用ユーザ)を作成するのを忘れないでください。

その後、CHANGE MASTERコマンドを実行してから、GROUP REPLICATIONを開始します。

この手順を使えば、簡単に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と従来のバックアップツールの比較

こちらの記事に続きます

MySQL
Return Top