はじめに
今回の記事は、Percona XtraBackup と、同梱の xbcloud バイナリを使って Amazon S3 および S3 互換のオブジェクトストレージサービスへバックアップを取得する方法を紹介します。
現在(2022年1月12日)の XtraBackup の最新バージョンは 8.0.26-18.0 になります。
Percona XtraBackup 8.0.26-18.0 Release Notes
Percona XtraBackup 8.0.26-18.0 GA版(リリース日:2021年9月2日) ※弊社OSSニュースでのPercona公式リリースノート翻訳
xbcloud は XtraBackup によって取得する(した)バックアップデータを扱う際に xbstream という形式を用いてクラウドサービスへアップロードまたはダウンロードするためのツールです。
バックアップ取得時の例としては、バックアップデータの出力ストリームをパイプを介してxbcloud に渡す、以下のような実行コマンドになります。
1 |
xtrabackup ... --backup --stream=xbstream ... | xbcloud put ... |
xbcloud がサポートしているクラウドストレージタイプは以下の通りです。
- OpenStack Object Storage (Swift)
- Amazon Simple Storage (S3)
- Google Cloud Storage (gcs)
- MinIO
S3互換APIを使用しているため、実際は上記サービスのみならず Alibaba Cloud OSS や Wasabi, IBM Cloud Object Storage といったクラウドサービスでも使用可能です。
利点はなんといってもバックアップファイル用のローカルストレージを必要とせず、運用管理やコスト面でメリットがあるオブジェクトストレージに直接バックアップできることが挙げられます。
また、同じような仕組み・方式を取ろうとした場合、 オブジェクトストレージへデータをアップロードする処理で aws cli や rclone, gof3r などのツールを用いるよりもパフォーマンス面で優れているという点もあります。
この辺りの比較検証については、Percona社からブログ記事が公開されていますので、興味がありましたらご一読ください。(Githubに実行コマンドも掲載されています)
Comparing S3 Streaming Tools with Percona XtraBackup – Percona Database Performance Blog
k8s-lab/pxb-s3 at main · Percona-Lab/k8s-lab · GitHub
そして、最新版の 8.0.26-18.0 で追加された新機能 Exponential Backoff
によって、バックアップ実行中の転送エラー発生時耐障害性が向上し、信頼性が増しました。
以降では、AWS 環境で xbcloud によるバックアップとリストアの実行方法を紹介します。
更に、後半パートでは MinIO を用いた環境での Exponential Backoff
の効果も確認してみたいと思います。
AWS EC2 MySQL + S3 環境での動作確認
環境準備
AWS EC2 に MySQL Community Edition 8.0.26 と XtraBackup(以降 PXBと表記) 8.0.26-18.0 をインストールします。
今回 EC2インスタンスは t3a.medium
、OS は Amazon Linux 2
を選択しました。
MySQL インストール
1 2 3 4 5 6 |
# yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm # yum install -y mysql-community-server-8.0.26 # systemctl start mysqld # mysql -u root -p$(grep "temporary password" /var/log/mysqld.log | tail -n 1 | rev | cut -f 1 -d " " | rev) --connect-expired-password -e "SET PASSWORD = 'MySQL8.0';" # mysql_config_editor set --login-path=localroot --user=root --host=localhost --password |
MySQL のインストールおよびセットアップについての説明は割愛します。 (パラメータはデフォルトのままです)
サンプルデータ(datacharmer/test_db) を投入
バックアップ用に適当なデータを投入しておきます。
1 2 3 4 5 |
# wget https://github.com/datacharmer/test_db/archive/master.zip # unzip master.zip # cd test_db-master # mysql --login-path=localroot < employees.sql # mysql --login-path=localroot < employees_partitioned.sql |
PXB インストール
Percona XtraBackup と qpress パッケージをインストールします。
1 2 3 4 |
# yum install -y epel-release https://repo.percona.com/yum/percona-release-latest.noarch.rpm # amazon-linux-extras install epel # percona-release enable-only tools # yum install -y percona-xtrabackup-80-8.0.26 qpress |
ご参考(弊社過去ブログ記事):Percona XtraBackup 8.0.23 を使ってみる | スマートスタイル TECH BLOG
バックアップ実行ユーザー作成
1 2 3 4 5 6 7 8 |
# mysql --login-path=localroot mysql> CREATE USER 'xtrabackup'@'localhost' IDENTIFIED BY 's3cr%Tpxb'; mysql> GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT, CREATE TABLESPACE, SUPER ON *.* TO 'xtrabackup'@'localhost'; mysql> GRANT SELECT ON performance_schema.log_status TO 'xtrabackup'@'localhost'; mysql> GRANT SELECT ON performance_schema.keyring_component_status TO 'xtrabackup'@'localhost'; mysql> FLUSH PRIVILEGES; mysql> quit # mysql_config_editor set --login-path=pxb --user=xtrabackup --socket=/var/lib/mysql/mysql.sock --password |
必要な権限はマニュアルページを参照願います。
S3 バケットを作成
バックアップデータの出力・保管先バケットを作成しておきます。
1 |
# aws s3 mb s3://ss-blog-test |
バックアップの実行
パラメータ構成ファイルを準備する
PXB と xbcloud のコマンドに渡すオプションを別ファイルに外出しで定義できます。
そのままだとコマンドラインが冗長になってしまうのと、バックアップスクリプトなどでオブジェクトストレージへの接続情報が直書きになってしまうのを回避したい場合にお勧めです。
今回の設定例では、xbstream・xbcloud それぞれ 8並列で処理を実行するようにし、各データチャンクファイルは qpress で圧縮しています。
[xbcloud] セクションの s3-bucket
に、先ほど作成したバケット名を設定しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# cat > /etc/xtrabackup.cnf <<EOT [xtrabackup] stream=xbstream compress no-version-check parallel=8 [xbcloud] storage=s3 s3-endpoint=s3.ap-northeast-1.amazonaws.com s3-access-key=AKIA************** s3-secret-key=hWuov**********************lL3k3 s3-bucket=ss-blog-test parallel=8 EOT |
xbcloud S3用オプションについては以下のページをご参照ください。
Using xbcloud Binary with Amazon S3
完全バックアップ
下準備が整ったので、漸くバックアップ実行となります。
まずは完全バックアップを取得してみましょう。
1 2 3 4 5 6 7 8 9 10 11 |
# PXB_CONF_FILE=/etc/xtrabackup.cnf # xtrabackup \ --defaults-extra-file=${PXB_CONF_FILE} \ --login-path=pxb \ --target-dir=/tmp \ --extra-lsndir=/tmp \ --backup \ | xbcloud \ --defaults-file=${PXB_CONF_FILE} \ put \ mysql-backup/$(date '+%Y-%m-%d-%H%M')-full-backup |
先ほど作成したパラメータ構成ファイルを xtrabackup では --defaults-extra-file
, xbcloud では --defaults-file
オプションで指定しています。
xbcloud のほうは、マニュアルにこの指定方法が明記されていません。(put/get
の前に指定しないと正しく読み込まれないのでご注意ください)
コマンドを実行すると、通常の PXB と同じようにコンソールに実行状況が出力されていきます。
出力内容を見ていくと、xbcloud ツールがオブジェクトストレージへ接続成功した旨が確認できます。
1 2 3 |
(...) 220111 13:47:14 xbcloud: Successfully connected. (...) |
下記のように、qpress(.qp) で圧縮されたバックアップファイルがさらに細切れになりマルチスレッドでアップロードしている様子が確認できます。
各アップロードチャンクサイズはデフォルトで10Mとなります。 (xtrabackup の --read-buffer-size
オプションで変更可能です)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
(...) 220111 13:47:15 xbcloud: successfully uploaded chunk: mysql-backup/2022-01-11-1347-full-backup/employees/dept_manager.ibd.qp.00000000000000000001, size: 43 220111 13:47:15 xbcloud: successfully uploaded chunk: mysql-backup/2022-01-11-1347-full-backup/employees/departments.ibd.qp.00000000000000000001, size: 42 220111 13:47:15 xbcloud: successfully uploaded chunk: mysql-backup/2022-01-11-1347-full-backup/employees/dept_manager.ibd.qp.00000000000000000000, size: 4890 220111 13:47:15 xbcloud: successfully uploaded chunk: mysql-backup/2022-01-11-1347-full-backup/employees/departments.ibd.qp.00000000000000000000, size: 4428 220111 13:47:15 xbcloud: successfully uploaded chunk: mysql-backup/2022-01-11-1347-full-backup/sys/sys_config.ibd.qp.00000000000000000001, size: 35 220111 13:47:15 xbcloud: successfully uploaded chunk: mysql-backup/2022-01-11-1347-full-backup/sys/sys_config.ibd.qp.00000000000000000000, size: 4009 (...) xtrabackup: Transaction log of lsn (621171845) to (621171855) was copied. 220111 13:47:19 completed OK! 220111 13:47:19 xbcloud: Upload completed. |
上記のメッセージが出力されれば、バックアップ&アップロードが成功です。
無事バックアップコマンドが完了したら、S3 バケット内にバックアップファイルが格納されていることを確認しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# aws s3 ls s3://ss-blog-test/mysql-backup/ PRE 2022-01-11-1347-full-backup/ # aws s3 ls s3://ss-blog-test/mysql-backup/2022-01-11-1347-full-backup/ PRE employees/ PRE mysql/ PRE performance_schema/ PRE sys/ 2022-01-11 13:47:19 509 backup-my.cnf.qp.00000000000000000000 2022-01-11 13:47:19 30 backup-my.cnf.qp.00000000000000000001 2022-01-11 13:47:19 234 binlog.000004.qp.00000000000000000000 2022-01-11 13:47:19 30 binlog.000004.qp.00000000000000000001 2022-01-11 13:47:19 142 binlog.index.qp.00000000000000000000 2022-01-11 13:47:19 29 binlog.index.qp.00000000000000000001 (...以下、割愛) |
libcurl のバージョンが古い場合に発生する Segmentation fault への対応
なお、今回の Amazon Linux 2 では発生しませんでしたが、CentOS 7 の curl が 7.29.0 とバージョンの古い環境では、バックアップ実行の最終フェーズに、xbcloud が Segmentation fault を引き起こして異常終了するという問題があります。
具体的には xbcloud の Bug ではなく、curl のライブラリの不具合になりますが、マルチパートでアップロードした際に使用していた複数の接続を全て閉じるときに上手く処理しきれずクラッシュが発生してしまう、というものです。
Bug #63799 for WWW-Curl: Segfault if curl handle persists until global destruction
対応方法としては、curl を最新バージョンにアップグレードするか、以下のように libcurl のみ最新版を抽出し、xbcloud に参照させることで回避可能です。ご参考まで。
1 2 3 4 5 6 7 8 |
## 最新バージョン(7.80.0) の libcurl.so をソースビルド後、ローカルライブラリディレクトリに配置 # cp -p libcurl.so.4.7.0 /usr/local/lib/ # ln -s /usr/local/lib/libcurl.so.4.7.0 /usr/local/lib/libcurl.so.4 ## xtrabackup+xbcloud の実行直前に LD_LIBRARY_PATHを設定し、一時的にライブラリを参照させる # export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH |
増分バックアップ実行
増分バックアップは、以下のように前回のバックアップのLSN番号を参照するために --incremental-basedir
を付与して実行します。
(よって、この例では累積増分ではなく差分増分バックアップになります)
1 2 3 4 5 6 7 8 9 10 11 |
# xtrabackup \ --defaults-extra-file=${PXB_CONF_FILE} \ --login-path=${LOGIN_PATH} \ --target-dir=/tmp \ --extra-lsndir=/tmp \ --incremental-basedir=/tmp \ --backup \ | xbcloud \ --defaults-file=${PXB_CONF_FILE} \ put \ mysql-backup/$(date '+%Y-%m-%d-%H%M')-incr-backup |
こちらもバックアップが成功したら、S3 バケット内を確認してみましょう。
1 2 3 |
# aws s3 ls s3://ss-blog-test/mysql-backup/ PRE 2022-01-11-1347-full-backup/ PRE 2022-01-11-1355-incr-backup/ |
リストア
S3 に取得したバックアップ(完全+増分)を使って MySQL をリストアします。
まずはインスタンスを停止し、datadir 配下のファイルを削除しておきます。
1 2 |
# systemctl stop mysqld # rm -rf /var/lib/mysql/* |
完全バックアップのリストア
xbcloud get
で完全バックアップのフォルダを指定してダウンロードし、ローカル上の指定のリストアディレクトリに展開します。
1 2 3 4 5 6 7 8 9 |
# mkdir -p /data/mysql-restore/full-backup # xbcloud \ --defaults-file=$PXB_CONF_FILE \ get \ mysql-backup/2022-01-11-1347-full-backup \ --parallel=4 2>download.log \ | xbstream \ -xv -C /data/mysql-restore/full-backup \ --parallel=4 2>stream.log |
実行ログの出力でコンソールがあふれるので、xbcloud によるファイルダウンロードと xbstream によるファイルストリーミングの標準エラー出力を別のログファイルにリダイレクトしています。
実行結果を確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# tail -n 5 download.log 220111 14:18:15 xbcloud: Download successfull mysql-backup/2022-01-11-1347-full-backup/xtrabackup_checkpoints.00000000000000000001, size 36 220111 14:18:15 xbcloud: Download successfull mysql-backup/2022-01-11-1347-full-backup/xtrabackup_info.qp.00000000000000000001, size 32 220111 14:18:15 xbcloud: Download successfull mysql-backup/2022-01-11-1347-full-backup/xtrabackup_logfile.qp.00000000000000000001, size 35 220111 14:18:15 xbcloud: Download successfull mysql-backup/2022-01-11-1347-full-backup/xtrabackup_tablespaces.qp.00000000000000000001, size 39 220111 14:18:15 xbcloud: Download completed. # tail -n 5 stream.log undo_001.qp undo_002.qp xtrabackup_info.qp xtrabackup_logfile.qp xtrabackup_tablespaces.qp |
S3 からローカルへ正常にファイルを取得出来たら、以下のコマンドで解凍とREDOログ適用 (prepare) を行います。
1 2 |
# xtrabackup --decompress --target-dir=/data/mysql-restore/full-backup --remove-original # xtrabackup --prepare --apply-log-only --target-dir=/data/mysql-restore/full-backup |
増分バックアップのリストア
増分バックアップの場合も同様のコマンドになります。対象ディレクトリの指定を間違えないようにしましょう。
1 2 3 4 5 6 7 8 9 |
# mkdir -p /data/mysql-restore/incr-backup-1 # xbcloud \ --defaults-file=$PXB_CONF_FILE \ get \ mysql-backup/2022-01-11-1355-incr-backup \ --parallel=4 2>>download.log \ | xbstream \ -xv -C /data/mysql-restore/incr-backup-1 \ --parallel=4 2>>stream.log |
これは xbcloud に限った話ではありませんが、増分バックアップの prepare についての注意としては、最後の増分バックアップ適用までは、--apply-log-only
オプションをつける必要があります。
これは --prepare
実行時のロールバックフェーズを防止するためのものです。
増分バックアップに対してトランザクションがロールバックされてしまうと、それ以降増分バックアップを適用できなくなります。
そのため、逆に一番最後の増分バックアップを適用する時は、下記のように --apply-log-only
オプションを付けずロールバックフェーズも含めて適用してください。
1 2 |
# xtrabackup --decompress --target-dir=/data/mysql-restore/incr-backup-1 --remove-original # xtrabackup --prepare --target-dir=/data/mysql-restore/full-backup --incremental-dir=/data/mysql-restore/incr-backup-1 |
バックアップファイルの準備が整ったら、ファイルを datadir にリストアし、MySQLを起動します。
1 2 3 4 |
# xtrabackup --move-back --target-dir=/data/mysql-restore/full-backup --force-non-empty-directories # chown -R mysql: /var/lib/mysql # systemctl start mysqld |
8.0.26-18.0 新機能 Exponential Backoff について
以前のバージョンの PXB では、チャンク操作のエラーが発生した場合、リトライは行われるものの、すぐに復旧できなければプロセスは異常終了してしまっていました。
8.0.26-18.0 で追加された Exponential Backoff
と呼ばれる新機能は、この点を克服する目的の仕組みと言えます。
- xbcloud によるチャンクデータのアップロードまたはダウンロード操作で失敗が発生した場合、そのエラーがリトライ対象と定義されている場合、xbcloud はリトライする前に一定期間スリープ(バックオフ)します。
- 同じチャンクを指定回数リトライしても以前失敗する場合はプロセス全体が中止されます。
指数バックオフアルゴリズムによってリトライ時のネットワーク輻輳を回避しつつ、極力リトライに努める機能とのことです。
公式ドキュメントによる機能説明および紹介については以下のページをご一読ください。
まずは、以前のバージョンの PXB では具体的にどのような挙動となるか、改めて確認してみたいと思います。
MySQL 8.0.25 + PXB 8.0.25-17 をインストールした別環境を用意しておきます。
ただし、S3 の疑似障害を作り出すのがなかなか困難と思い、MinIO でローカルオブジェクトストレージを構築して動作確認を行います。
※AWS Fault Injection SimulatorではS3は未対応でした…
環境準備
MinIO をインストール
Go 言語で書かれているので簡単にインストールでき、また docker イメージも用意されていますので手軽に環境構築できます。
インストール手順は公式ドキュメントにあるクイックスタートガイドを元にしました。
1 2 3 4 |
# cd ~ # mkdir -p /data/minio # wget https://dl.min.io/server/minio/release/linux-amd64/minio # chmod +x minio |
以下のコマンドでサービスを起動します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# ./minio server /data/minio & API: http://10.233.135.37:9000 http://127.0.0.1:9000 RootUser: minioadmin RootPass: minioadmin Console: http://10.233.135.37:35617 http://127.0.0.1:35617 RootUser: minioadmin RootPass: minioadmin Command-line: https://docs.min.io/docs/minio-client-quickstart-guide $ mc alias set myminio http://10.233.135.37:9000 minioadmin minioadmin Documentation: https://docs.min.io WARNING: Console endpoint is listening on a dynamic port (35617), please use --console-address ":PORT" to choose a static port. WARNING: Detected default credentials 'minioadmin:minioadmin', we recommend that you change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables |
デフォルトのままなので色々と警告が出ていますが、もし管理者ユーザ名とパスワードを変更したい場合は上記の案内の通り環境変数を設定してサービス起動してください。
また、もし HTTPS/TLSアクセスを試したい場合は、こちらのページを参考に自己署名鍵と証明書を生成して ~/.minio/certs/
ディレクトリに配置してサービスを起動してください。(HTTPSアドレスになります)
MinIO クライアントをインストールしバケットを作成
バケット作成や参照などの操作を行うため、クライアントツールもインストールしておきます。
サーバ同様、至ってシンプルにインストールできます。
1 2 3 |
# wget https://dl.min.io/client/mc/release/linux-amd64/mc # chmod +x ./mc # cp mc /usr/bin |
先ほどサービス起動したときのコンソール出力の真ん中あたりに表示されていた alias コマンドを実行するとクライアントツールに接続情報をセットしておくことができ便利です。
1 |
# mc alias set myminio http://10.233.135.37:9000 minioadmin minioadmin |
そのエイリアス名を指定してサービスの稼働状態をコマンドで確認してみます。
1 2 3 4 5 6 |
# mc admin info myminio ● 10.233.135.37:9000 Uptime: 2 minutes Version: 2022-01-08T03:11:54Z Network: 1/1 OK |
バックアップ出力・保管用のバケットを作成しておきます。
1 2 3 4 5 |
# mc ls myminio # mc mb myminio/mysql-backup Bucket created successfully `myminio/mysql-backup`. # mc ls myminio [2022-01-10 14:16:45 JST] 0B mysql-backup/ |
バックアップ実行中に S3 サービス停止 : PXB 8.0.25 の場合
MinIO 向けに xbcloud のパラメータを設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# cat > /etc/xtrabackup.cnf <<EOT [xtrabackup] stream=xbstream compress no-version-check parallel=4 [xbcloud] storage=s3 s3-endpoint='http://localhost:9000' s3-access-key='minioadmin' s3-secret-key='minioadmin' s3-bucket=mysql-backup parallel=4 EOT |
バックアップ実行のコマンドは前述同様以下となります。
1 2 3 4 5 6 7 8 9 10 11 12 |
# PXB_CONF_FILE=/etc/xtrabackup.cnf # xtrabackup \ --defaults-extra-file=${PXB_CONF_FILE} \ --login-path=pxb \ --target-dir=/tmp \ --extra-lsndir=/tmp \ --backup \ | xbcloud \ --defaults-file=${PXB_CONF_FILE} \ put \ --insecure \ $(date '+%Y-%m-%d-%H%M')-full-backup |
バックアップ実行後に別コンソールから以下のコマンドを実行し、オブジェクトストレージサービス停止~2分後復旧という状況を発生させます。
1 |
# mc admin service stop myminio && sleep 120 && ./minio server /data/minio & |
すると、PXB 8.0.25 では以下のように「エラー直後4回リトライするものの合計5回のエラー発生で断念し異常終了となる」動作になりました。(エラー発生後1秒以内で異常終了となる)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
(...) 220111 14:30:49 xbcloud: Failed to upload object mysql-backup/2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000000. Error message: http: Server closed 220111 14:30:49 xbcloud: Retrying 2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000000 [1] 220111 14:30:49 [03] ...done 220111 14:30:49 [02] Compressing and streaming ./employees/salaries#p#p09.ibd 220111 14:30:49 xbcloud: Failed to upload object mysql-backup/2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000000. Error message: http: Server closed 220111 14:30:49 xbcloud: Retrying 2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000000 [2] 220111 14:30:49 xbcloud: Failed to upload object mysql-backup/2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000001. Error message: http: Server closed 220111 14:30:49 xbcloud: Retrying 2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000001 [1] 220111 14:30:49 xbcloud: Failed to upload object. Error: Couldn't connect to server 220111 14:30:49 xbcloud: error: failed to upload chunk: 2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000001, size: 45 220111 14:30:49 xbcloud: Failed to upload object. Error: Couldn't connect to server 220111 14:30:49 xbcloud: error: failed to upload chunk: 2022-01-11-1430-full-backup/employees/salaries#p#p05.ibd.qp.00000000000000000000, size: 2007937 220111 14:30:49 xbcloud: Failed to upload object mysql-backup/2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000000. Error message: http: Server closed 220111 14:30:49 xbcloud: Retrying 2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000000 [3] 220111 14:30:49 xbcloud: Failed to upload object. Error: Couldn't connect to server 220111 14:30:49 xbcloud: error: failed to upload chunk: 2022-01-11-1430-full-backup/employees/salaries#p#p04.ibd.qp.00000000000000000000, size: 1649083 220111 14:30:49 xbcloud: Upload failed. xtrabackup: Error writing file '<unopen fd>' (OS errno 32 - Broken pipe) [01] xtrabackup: Error: failed to copy datafile. xtrabackup: Error writing file '<unopen fd>' (OS errno 32 - Broken pipe) [03] xtrabackup: Error: failed to copy datafile. 220111 14:30:49 [02] ...done xtrabackup: Error writing file '<unopen fd>' (OS errno 32 - Broken pipe) [02] xtrabackup: Error: failed to copy datafile. 220111 14:30:49 [04] ...done xtrabackup: Error writing file '<unopen fd>' (OS errno 32 - Broken pipe) [04] xtrabackup: Error: failed to copy datafile. 220111 14:30:49 >> log scanned up to (621435984) |
当然ながらバックアッププロセスは異常終了、オブジェクトストレージ側には中途半端な状態でアップロードされているままとなってしまいます。
バックアップ実行中に S3 サービス停止 : PXB 8.0.26 (Exponential Backoff) の場合
次に 8.0.26 の確認です。まずはパッケージをアップグレードしましょう。
1 2 3 4 |
# yum update -y percona-xtrabackup-80-8.0.26 # xtrabackup --version xtrabackup: recognized server arguments: --datadir=/var/lib/mysql xtrabackup version 8.0.26-18 based on MySQL server 8.0.26 Linux (x86_64) (revision id: 4aecf82) |
パラメータ構成ファイルに Exponential Backoff 機能のパラメータとなる --max-retries
と --max-backoff
を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# vi /etc/xtrabackup.cnf [xtrabackup] stream=xbstream compress no-version-check parallel=4 [xbcloud] storage=s3 s3-endpoint='http://localhost:9000' s3-access-key='minioadmin' s3-secret-key='minioadmin' s3-bucket=mysql-backup parallel=4 max-retries=5 max-backoff=10000 curl-retriable-errors=7 http-retriable-errors=0 |
--curl-retriable-errors
と --http-retriable-errors
パラメータについて先に説明してしまいますが、今回動作確認している MinIO による疑似環境では、サービスを停止すると Curl error (7)
と http error (0)
が発生します。
xbcloud の Retriable errors デフォルト定義にはこれらのエラーが含まれていないので、エラー発生時にリトライを行ってくれません。
そのため、リトライ対象となるように今回予め追加している設定になります。
実は、発生したエラーの詳細情報は xbcloud の --verbose
を付けて実行することで以下のようにサジェスト込みで確認できますので、これを元に設定を行いました。
1 2 3 4 |
220111 16:56:32 xbcloud: Operation failed. Error: Couldn't connect to server 220111 16:56:32 xbcloud: Curl error (7) Couldn't connect to server is not configured as retriable. You can allow it by adding --curl-retriable-errors=7 parameter 220111 16:56:32 xbcloud: http error (0) is not configured as retriable. You can allow it by adding --http-retriable-errors=0 parameter 220111 16:56:32 xbcloud: error: failed to upload chunk: 2022-01-11-1656-full-backup/employees/salaries#p#p18.ibd.qp.00000000000000000001, size: 45 |
実運用でも、デフォルトのリトライ対象エラー以外に対象とすべきエラーを選定するために、この機能を使うのが有益かと考えます。
(ただし curl の実行ログが大量に出力されるので、通常運用には適さず、あくまで障害時調査やデバッグ用と考えてください)
先ほどの 8.0.25 と同じように MinIO のオブジェクトストレージサービスを停止~2分後復旧させてみます。
(長いログになりますが、ご容赦ください…)
以前のバージョンと異なり、Sleeping for XXXX ms before retrying ~~
と表示されるようになったのが確認できます。
対象のチャンクファイルのアップロードをリトライする前に XXXX ミリ秒待機する、という意味合いになります。
メッセージ末尾の [n]
はそのチャンクファイルのアップロードに失敗した回数のカウンタです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
(...) 220111 17:05:17 xbcloud: S3 error message: http: Server closed 220111 17:05:17 xbcloud: Sleeping for 2384 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSM.qp.00000000000000000001 [1] 220111 17:05:20 xbcloud: S3 error message: http: Server closed 220111 17:05:20 xbcloud: Sleeping for 2887 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log_213.sdi.qp.00000000000000000000 [1] 220111 17:05:23 xbcloud: S3 error message: http: Server closed 220111 17:05:23 xbcloud: Sleeping for 2778 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log_213.sdi.qp.00000000000000000001 [1] 220111 17:05:25 xbcloud: S3 error message: http: Server closed 220111 17:05:25 xbcloud: Sleeping for 2916 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSM.qp.00000000000000000000 [1] 220111 17:05:28 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:28 xbcloud: Sleeping for 2794 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSV.qp.00000000000000000000 [1] 220111 17:05:31 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:31 xbcloud: Sleeping for 2336 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSV.qp.00000000000000000001 [1] 220111 17:05:33 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:33 xbcloud: Sleeping for 2387 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSM.qp.00000000000000000000 [1] 220111 17:05:36 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:36 xbcloud: Sleeping for 2493 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSM.qp.00000000000000000001 [1] 220111 17:05:38 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:38 xbcloud: Sleeping for 2650 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log_214.sdi.qp.00000000000000000000 [1] 220111 17:05:41 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:41 xbcloud: Sleeping for 2422 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log_214.sdi.qp.00000000000000000001 [1] 220111 17:05:43 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:43 xbcloud: Sleeping for 2363 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSV.qp.00000000000000000000 [1] 220111 17:05:46 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:46 xbcloud: Sleeping for 2028 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSV.qp.00000000000000000001 [1] (...) |
ここから待機秒数が増加しています。(2秒台→4秒台)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
(...) 220111 17:05:48 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:48 xbcloud: Sleeping for 4691 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSM.qp.00000000000000000001 [2] 220111 17:05:52 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:52 xbcloud: Sleeping for 4060 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log_213.sdi.qp.00000000000000000000 [2] 220111 17:05:56 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:05:56 xbcloud: Sleeping for 4764 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log_213.sdi.qp.00000000000000000001 [2] 220111 17:06:01 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:01 xbcloud: Sleeping for 4927 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSM.qp.00000000000000000000 [2] 220111 17:06:06 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:06 xbcloud: Sleeping for 4541 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSV.qp.00000000000000000000 [2] 220111 17:06:11 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:11 xbcloud: Sleeping for 4427 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSV.qp.00000000000000000001 [2] 220111 17:06:15 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:15 xbcloud: Sleeping for 4173 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSM.qp.00000000000000000000 [2] 220111 17:06:19 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:19 xbcloud: Sleeping for 4737 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSM.qp.00000000000000000001 [2] 220111 17:06:24 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:24 xbcloud: Sleeping for 4212 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log_214.sdi.qp.00000000000000000000 [2] 220111 17:06:28 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:28 xbcloud: Sleeping for 4369 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log_214.sdi.qp.00000000000000000001 [2] 220111 17:06:33 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:33 xbcloud: Sleeping for 4568 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSV.qp.00000000000000000000 [2] 220111 17:06:37 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:37 xbcloud: Sleeping for 4430 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSV.qp.00000000000000000001 [2] (...) |
オブジェクトストレージサービスは依然停止中。ここから更に増加しています。(4秒台→8秒台)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
(...) 220111 17:06:42 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:42 xbcloud: Sleeping for 8783 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSM.qp.00000000000000000001 [3] 220111 17:06:50 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:50 xbcloud: Sleeping for 8531 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log_213.sdi.qp.00000000000000000000 [3] 220111 17:06:59 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:06:59 xbcloud: Sleeping for 8863 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log_213.sdi.qp.00000000000000000001 [3] 220111 17:07:08 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:07:08 xbcloud: Sleeping for 8124 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSM.qp.00000000000000000000 [3] 220111 17:07:16 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:07:16 xbcloud: Sleeping for 8068 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSV.qp.00000000000000000000 [3] 220111 17:07:24 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:07:24 xbcloud: Sleeping for 8136 ms before retrying 2022-01-11-1705-full-backup/mysql/general_log.CSV.qp.00000000000000000001 [3] 220111 17:07:32 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:07:32 xbcloud: Sleeping for 8930 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSM.qp.00000000000000000000 [3] 220111 17:07:41 xbcloud: Operation failed. Error: Couldn't connect to server 220111 17:07:41 xbcloud: Sleeping for 8803 ms before retrying 2022-01-11-1705-full-backup/mysql/slow_log.CSM.qp.00000000000000000001 [3] (...) |
サービス復旧し、失敗していたチャンクのアップロードが再開、成功しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
(...) 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/slow_log_214.sdi.qp.00000000000000000000, size: 1781 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/slow_log_214.sdi.qp.00000000000000000001, size: 39 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/slow_log.CSV.qp.00000000000000000000, size: 105 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/slow_log.CSV.qp.00000000000000000001, size: 35 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/general_log.CSM.qp.00000000000000000001, size: 38 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/general_log_213.sdi.qp.00000000000000000001, size: 42 220111 17:07:50 [03] Compressing and streaming performance_schema/events_stages_su_114.sdi to <STDOUT> 220111 17:07:50 [01] Compressing and streaming performance_schema/events_stages_su_115.sdi to <STDOUT> 220111 17:07:50 [03] ...done 220111 17:07:50 [01] ...done 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/general_log.CSV.qp.00000000000000000000, size: 111 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/general_log.CSV.qp.00000000000000000001, size: 38 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/general_log.CSM.qp.00000000000000000000, size: 150 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/general_log_213.sdi.qp.00000000000000000000, size: 1521 220111 17:07:50 xbcloud: successfully uploaded chunk: 2022-01-11-1705-full-backup/mysql/slow_log.CSM.qp.00000000000000000001, size: 35 (...) |
アップロード失敗回数が増える度、指数バックオフアルゴリズムに基づいてスリープ秒数が増加設定されます。
これにより、複数のチャンクアップロードにおけるネットワークの輻輳を回避しています。
そして、スリープ秒数の増加上限は --max-backoff
で制御できます。(--max-backoff
で指定した秒数に到達して以降は、同じ値でスリープする動作となります)
チャンクのアップロード操作失敗回数が --max-retries
に達するまで操作はリトライされ、最後のリトライで失敗すると xbcloud プロセスは終了となります。(今回の例では 3/5回 で復旧となりました)
なお、本機能のパラメータを明示的に設定していなくても、8.0.26-18.0 であれば以下のデフォルト値で動作します。
1 2 |
--max-retries = 10 --max-backoff = 300000 (5分) |
まとめ
PXB 8.0.26-18.0 では、xbcloud によるチャンクデータのマルチパートアップロードという処理特性を生かし、エラー発生時に安全かつ調整可能なリトライが出来るようになり、xbcloud によるバックアップ実行の信頼性が高まりました。
この点を懸念していてこれまで実用を見送っていたり、別の仕組みで実装していたユーザも少なからずいらっしゃるのではと思いますが、ぜひこの機会にお試しいただいてはいかがでしょうか。