最新のMySQL8.0でのバックアップ運用にCLONE PLUGINはつかえるのか

技術本部 サービスリライアビリティグループ(SRG)の鬼海(@fat47)です。
#SRG(Service Reliability Group)は、主に弊社メディアサービスのインフラ周りを横断的にサポートしており、既存サービスの改善や新規立ち上げ、OSS貢献などを行っているグループです。
本記事は、SRG 内にある DBWG(DBワーキンググループ)が全社内向けに提供しているデータベースに関する資料を公開します。
なにかの役に立てば幸いです。
 

現在のXtraBackupの利用における問題点


現在のバックアップ運用

私達のチームが担当しているサービスでは、MySQLのバックアップはPercona社のXtraBackupを利用し、binlogは別途数分おきにバックアップする運用をしています。
例えば下記のような運用です。
バックアップ種類頻度手段
フルバックアップ1日1回cronでXtraBackup実行
binlogバックアップ5分ごとcronでs3 sync実行

現在のリストアの流れ

XtraBackupでとったフルバックアップを展開し、バックアップ取得時のbinlog positionを確認し、その時点以降のデータはbinlogバックアップからのデータを当てることでリストアしています。
 

XtraBackupでの問題点

基本的にMySQL8.0でもこの運用で問題ありませんでした。
MySQL8.0.29が来るまでは…。
 
上記バージョンからの仕様が変わり、InnoDB REDOログ形式も仕様変更されました。
DDL実行時のデフォルトの動作がINSTANTに変更されているので、普通にALTER文を実行するとで実行されます。
この機能を完全に回避するにはすべてのDDLに を指定する必要があります。
余談ですが、この機能まわりでクリティカルなバグがあり、8.0.29はリリース後すぐに公開停止となりました。その後8.0.30以降を利用するよう公式よりアナウンスがされています。
 
このMySQL8.0.29以降のが適用されると問題となるのが、XtraBackupをそのままでは利用できなくなるという点です。
 
1つでも適用されたテーブルがあるとXtraBackup実行時に下記のようなエラーが出力されます。
回避するには、エラー文に書いてある通り対象テーブルに対してを実行する必要があります。
対象のテーブルのサイズが小さいときには、バックアップ実行前に毎回OPTIMIZE等を実行すればよいですが、巨大なテーブルの場合は非常に時間がかかってしまうことが考えられます。
が利用されたテーブルがないかは下記のクエリで判別することもできます。
 

MySQL8.0の新機能 CLONE PLUGIN


先のXtraBackupの問題点を回避するために、MySQLの機能であるCLONE PLUGINが使えないかと考えました。
改めて簡単にCLONE PLUGINについてご紹介します。
CLONE PLUGINは2019年のMySQL8.0.17でリリースされたMySQLの新しい物理バックアップ機能です。
ローカルにファイルとして保存するのはもちろん、リモートでデータ提供側(ドナー)サーバのコピーを作成することができます。
例えばレプリカを1台追加したいとなったとき、下記のコマンドを実行することでデータ提供側(ドナー)のサーバからすべてのデータをコピーしてくることが可能です。
 
※実際にはドナーからCLONEを利用する際には下記のような準備が必要となります。
データ提供側(ドナー)側のMySQL
 
コピー先(受信者)側のMySQL
 

XtraBackupのかわりにCLONE PLUGINを使うには


XtraBackupのMySQL8.0.30以降の運用に問題があることをさきほどご紹介しました。
この章ではMySQL8.0.30以降のMySQLでのバックアップ運用を考えてみます。
 
下記のような構成でReplicaのサーバでCLONE PLUGINを実行してバックアップを取得し、
S3などのオブジェクトストレージにアップロードしていることを想定しています。
 
💡
CLONE PLUGINではストレージエンジンはInnoDBのみ等の制限事項があります。 詳細は公式ドキュメントをご参照ください。 https://dev.mysql.com/doc/refman/8.0/ja/clone-plugin-limitations.html
今回は非GTID環境でS3アップロード部分は割愛して、ローカルにファイルを置いている例でご紹介します。

フルバックアップ

(初回のみ実行)バックアップ実行ユーザの作成
 
CLONE PLUGINはbinlogファイルやmy.cnfのバックアップ機能がありません。
バックアップを取得した瞬間のMASTER POSITIONを知る術がないので、Replicaのレプリケーションを停止してポジションを記録したあとに、CLONEを実行します。
 
レプリケーションを停止します。
 
ポジションを記録します。
 
バックアップを実行します。
 
レプリケーションを再開します。
 

binlogのバックアップ

cronでrsyncなどでbinlogファイルを別ディレクトリに定期的にコピーするようにします。
 

リストアの流れ

  1. MySQLを停止します。
  1. CLONEで取得したフルバックアップをMySQL dirに展開します。
    1. フルバックアップ取得後以降の変更をbinlogファイルから抽出します。
      1. 先程記録したポジションファイル確認
        1. フルバックアップ以降に更新されたbinlogファイル確認
          1. リカバリー用のクエリを生成します。
            1. start-positionには↑で表示したポジションを指定し、読み込むbinlogファイルはフルバックアップ取得時以降のbinlogファイルをすべて指定します。
        1. MySQLを起動します。
        1. 起動したMySQLにリカバリー用のクエリを流します。
          1. これでフルバックアップ取得時+それ以降の差分がリストアできました。
           

          終わりに


          今回のようにCLONE PLUGINでもXtraBackupのような使い方ができます。
          MySQL8.0.29以降をお使いのかたは、XtraBackup+OPTIMIZE TABLE運用をするか、今回のような手順でCLONE PLUGINを使うかを検討してみていだだければと思います。
           
          今回ご紹介しませんでしたが、CLONE PLUGINではレプリカの追加操作の場合は、従来のレプリカ追加手順よりもっと簡単に追加できたり、とても便利なので活用していきたいですね。
           
          SRG では一緒に働く仲間を募集しています。 ご興味ありましたらぜひこちらからご連絡ください。
           
          このエントリーをはてなブックマークに追加