俺です。
只今絶賛移行厨です。

Percona Xtrabackup(innobackupex)のバックアップファイルを用いたRestore Aurora DB Cluster from S3機能を使って移行する手順の一例を記載します。

結論から伝えますと最強のようです。最高アンドさいこうからの最強!

参考

概要

対象

MySQL on EC2または仮想サーバやオンプレミスで稼働するMySQL Server

対象バージョン: 5.5から5.6.22まで

5.6.23以上はサポート対象外の可能性が高いです。
当初Amazon Linux 2016.03でインストール可能なMySQL Server 5.6.32でリストア検証を行いましたが、正常にリストアできませんでした。

Aurora Launch時に以下の様なエラーが発生します。

b616d799-088c-5cf2-5f3e-c0239ffc6885

内容と制限事項

  • Percona Xtrabackupで取得したデータベースファイルをRDS Auroraへリストアします。
  • RDS AuroraのSnapshot Restore同様に新規にRDS Auroraインスタンスが作成されます。
  • 稼働中のRDS AuroraへXtrabackupのデータファイルをリストアすることはできません。

以下の情報はリストアされません

ドキュメントより抜粋

  • ユーザーアカウント
  • 関数
  • ストアドプロシージャ
  • タイムゾーン情報

クソいいところとクソイケてないところ

  • データファイルベースのリストアのためmysqldumpリストアよりクッソ高速です。
  • Xtrabackupはバックアップ時にMasterLogFileとPositionをxtrabackup_infoファイルに記録しているのでRestore – Aurora DB Cluster from S3でリストアした後にソースデータベースとレプリケーションを確立できます。
  • Xtrabackupで取得したデータベースにMyISAM Engineのテーブルが存在してもRDS AuroraへリストアされるタイミングでInnoDB変換が自動的に行われます。
  • リストア中のログ詳細出力機能がありません。(リストアに用いるXtrabackupファイルを保存するS3のアクセスログを有効にしておくことでファイルのGETリクエストのログが記録されるので、若干わかるレベル)
  • 正常にリストアされるかはLaunch完了してshow databases/show table statusするまで確認できません。

構成図

(2)はオプションです。
同一VPC内のMySQL on EC2からRDS Auroraへリストアする場合は不要です。
stunnelの設定は過去ネタを参照してください。

200828af-a0b8-22b0-cceb-92aafbfac341

ソースデータベース環境の準備

  • ソースデータベースのmy.cnf

パラメータはまあ適当に

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mysqld according to the
# instructions in http://fedoraproject.org/wiki/Systemd

server-id=1
character_set_server=utf8mb4
log_bin
innodb_buffer_pool_size=2G
#innodb_file_per_table
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[mysql]

レプリケーションユーザの作成

mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY ' ';
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

移行用データベースとテーブルの準備

  • データベース
mysql> show databases;
+---------------------------------+
| Database                        |
+---------------------------------+
| information_schema              |
| mysql                           |
| orenodb                         |
| performance_schema              |
+---------------------------------+
6 rows in set (0.00 sec)
  • テーブル

MyISAMエンジンのテーブルと、InnoDBエンジンのテーブルを作成します。

mysql> show table status;
+--------+--------+---------+------------+------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| Name   | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length  | Index_length | Data_free | Auto_increment | Create_time         | Update_time         | Check_time | Collation          | Checksum | Create_options | Comment |
+--------+--------+---------+------------+------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
| myisam | MyISAM |      10 | Fixed      |    1 |              7 |           7 | 1970324836974591 |         1024 |         0 |           NULL | YYYY-MM-DD HH:MI:SS | YYYY-MM-DD HH:MI:SS | NULL       | utf8mb4_general_ci |     NULL |                |         |
| test   | InnoDB |      10 | Compact    |    0 |              0 |       16384 |                0 |            0 |         0 |           NULL | YYYY-MM-DD HH:MI:SS | NULL                | NULL       | utf8mb4_general_ci |     NULL |                |         |
+--------+--------+---------+------------+------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------+
2 rows in set (0.00 sec)

Percona Xtrabackupのインストール

ソースデータベースのデータファイルをバックアップを実行するサーバにインストールします。
ソースデータベースと同等のディスク容量を保持しているサーバが良いです。
今回の検証ではAmazon Linuxを使っているのでPercona XtrabackupドキュメントのInstalling Percona XtraBackup on Red Hat Enterprise Linux and CentOSを参照してxtrabckupをインストールします。

xtrabackupはlibevが依存パッケージなのでEPELリポジトリも有効にしましょう。

$ sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
$ sudo yum install percona-xtrabackup-24 --enablerepo=epel
読み込んだプラグイン:priorities, update-motd, upgrade-helper
amzn-main/latest                                                                                               | 2.1 kB     00:00
amzn-updates/latest                                                                                            | 2.3 kB     00:00
epel/x86_64/metalink                                                                                           | 4.0 kB     00:00
percona-release-noarch/latest                                                                                  | 2.5 kB     00:00
percona-release-x86_64/latest/x86_64                                                                           | 2.5 kB     00:00
956 packages excluded due to repository priority protections
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ percona-xtrabackup-24.x86_64 0:2.4.4-1.el6 を インストール
--> 依存性の処理をしています: libev.so.4()(64bit) のパッケージ: percona-xtrabackup-24-2.4.4-1.el6.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ libev.x86_64 0:4.03-3.el6 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

======================================================================================================================================
 Package                              アーキテクチャー      バージョン                    リポジトリー                           容量
======================================================================================================================================
インストール中:
 percona-xtrabackup-24                x86_64                2.4.4-1.el6                   percona-release-x86_64                8.1 M
依存性関連でのインストールをします:
 libev                                x86_64                4.03-3.el6                    epel                                  113 k

トランザクションの要約
======================================================================================================================================
インストール  1 パッケージ (+1 個の依存関係のパッケージ)

総ダウンロード容量: 8.2 M
インストール容量: 32 M
Is this ok [y/d/N]: y
Downloading packages:
警告: /var/cache/yum/x86_64/latest/epel/packages/libev-4.03-3.el6.x86_64.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID 0608b895: NOKEY
libev-4.03-3.el6.x86_64.rpm の公開鍵がインストールされていません
(1/2): libev-4.03-3.el6.x86_64.rpm                                                                             | 113 kB     00:00
警告: /var/cache/yum/x86_64/latest/percona-release-x86_64/packages/percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm: ヘッダー V4 DSA/SHA1 Signature、鍵 ID cd2efd2a: NOKEY
percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm の公開鍵がインストールされていません
(2/2): percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm                                                            | 8.1 MB     00:01
--------------------------------------------------------------------------------------------------------------------------------------
合計                                                                                                  3.9 MB/s | 8.2 MB  00:00:02
file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Percona から鍵を取得中です。
Importing GPG key 0xCD2EFD2A:
 Userid     : "Percona MySQL Development Team "
 Fingerprint: 430b df5c 56e7 c94e 848e e60c 1c4c bdcd cd2e fd2a
 Package    : percona-release-0.1-3.noarch (@/percona-release-0.1-3.noarch)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-Percona
上記の処理を行います。よろしいでしょうか? [y/N]y
file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 から鍵を取得中です。
Importing GPG key 0x0608B895:
 Userid     : "EPEL (6)  "
 Fingerprint: 8c3b e96a f230 9184 da5c 0dae 3b49 df2a 0608 b895
 Package    : epel-release-6-8.9.amzn1.noarch (installed)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
上記の処理を行います。よろしいでしょうか? [y/N]y
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : libev-4.03-3.el6.x86_64                                                                               1/2
  インストール中          : percona-xtrabackup-24-2.4.4-1.el6.x86_64                                                              2/2
  検証中                  : percona-xtrabackup-24-2.4.4-1.el6.x86_64                                                              1/2
  検証中                  : libev-4.03-3.el6.x86_64                                                                               2/2

インストール:
  percona-xtrabackup-24.x86_64 0:2.4.4-1.el6

依存性関連をインストールしました:
  libev.x86_64 0:4.03-3.el6

完了しました!

RDS Auroraへリストアするための準備

移行用S3バケットの作成

移行先AWSアカウントでS3バケットを作成します

  • orenomigration のようなかんじ。世界で唯一の最高にかっこよくてハゲちらかして吐ききれる名前のS3バケットを作ります
  • バケットポリシーはデフォルトでよいです
  • RDS AuroraがLaunch時に正常にXtrabackupファイルを取得できているかチェックするためのS3 Accesslogを有効にしましょう

移行用S3バケットへのVPCエンドポイント作成

  • RDS AuroraをLaunchするサブネットがS3バケットへアクセスできるようにS3 VPC Endpointを作成します

IAM Service Roleの作成とPolicyの設定(オプション)

Restoreでxtrabckupファイルを読み込むためのIAM Roleを作成します。
この設定はLaunchタイミングで指定できるため必ずしも事前に行う必要はありません。

  • Role
IAM Role Name Trust Relationships
xtrabackup-role rds.amazonaws.com
  • Inline Policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::orenomigration"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::orenomigration/backup_archives/*"
            ]
        }
    ]
}

移行作業

ソースデータベースでXtrabackupの実行

注意点: --streamオプションを指定してtar/xbstream形式でバックアップを取得したものをS3に保存しないとリストアできませんでした。

今回の例ではマスタで実行します。ホットバックアップ扱いなので最高。
バックアップスレーブサーバから取得する場合はlog-slave-updatesを有効にしておくとマスタ<-バックアップスレーブ<-RDS Auroraとチェーンレプリケーションできそうですね。

$ sudo mkdir /s3-restore
$ innobackupex --user=root --no-timestamp --stream=tar /s3-restore/backup | \
split -d --bytes=512000 - /s3-restore/backup_archives/backup.tar
160910 19:27:35 innobackupex: Starting the backup operation

IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".
..省略..
Using server version 5.6.22-log
innobackupex version 2.4.4 based on MySQL server 5.7.13 Linux (x86_64) (revision id: df58cf2)
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /var/lib/mysql
xtrabackup: open files limit requested 0, set to 1024
xtrabackup: using the following InnoDB configuration:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:12M:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 2
xtrabackup:   innodb_log_file_size = 50331648
InnoDB: Number of pools: 1
YYMMDD HH24:MI:SS >> log scanned up to (86118369257)
..省略..
YYMMDD HH24:MI:SS [00] Writing xtrabackup_info
YYMMDD HH24:MI:SS [00]        ...done
xtrabackup: Transaction log of lsn (85899943219) to (109465256896) was copied.
YYMMDD HH24:MI:SS completed OK!

backupデータをS3へ転送

$ aws s3 sync /s3-restore/ s3://orenomigration

RDS Auroraへのリストア

  • メニュー選択

5c3f44e9-92d6-f815-bda3-371799539719

  • XtrabackupファイルのあるS3エンドポイントの設定とRoleの設定

527b2c01-0021-332d-7f36-3cfa7da3f181

  • リストアするRDS Auroraのインスタンスタイプ設定

cb777357-ea34-bf90-b320-5792492e7ef5

  • その他Launchパラメータの設定

事前にソースデータベースのmy.cnfとcharacter_setやtime_zoneを移植したパラメータグループを作っておくと良さそうです

a8546a91-044c-ce18-c395-259a81da5dfa

  • Launch

RDS Auroraが起動するまで待ちます。
RDS AuroraがS3へアクセスしてXtrabackupのデータベースファイルの取得
Prepare->Migrationと行われます。

リストア後のチェック

  • orenodbデータベースがリストアされています
  • テーブルもMyISAMエンジンのテーブルはInnoDBに変換されています
  • データもリストアされています

最高

mysql -u user -p -h  
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| migrationtest      |
| mysql              |
| orenodb            |
| performance_schema |
+--------------------+
5 rows in set (0.01 sec)

mysql> use orenodb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables
    -> ;
+-------------------+
| Tables_in_orenodb |
+-------------------+
| myisam            |
| test              |
+-------------------+
2 rows in set (0.00 sec)

mysql> show table status;
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+--------------------+----------+--------------------+---------+
| Name   | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation          | Checksum | Create_options     | Comment |
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+--------------------+----------+--------------------+---------+
| myisam | InnoDB |      10 | Dynamic    |    0 |              0 |       16384 |               0 |            0 |         0 |           NULL | NULL        | NULL        | NULL       | utf8mb4_general_ci |     NULL | row_format=DYNAMIC |         |
| test   | InnoDB |      10 | Compact    |    0 |              0 |       16384 |               0 |            0 |         0 |           NULL | NULL        | NULL        | NULL       | utf8mb4_general_ci |     NULL |                    |         |
+--------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+--------------------+----------+--------------------+---------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM myisam, test;
+------+------+
| a    | a    |
+------+------+
|  100 |   10 |
+------+------+
1 row in set (0.00 sec)

ここまででRDS AuroraのデータをXtrabackup実行時点の状態にリストアして起動することができました。

ソースデータベースとRDS Auroraのレプリケーション

テストデータベースの作成

orenodb以外に2つ作ります。

mysql>create database oregakangaetakuraudoikouyounodb;
mysql>create database oregakangaetasaikyounodb;

テストデータの生成

この記事を参考にして
itemテーブルを作成し、ダミーデータを生成します。

ソースデータベースとRDS Auroraでレプリケーションの実行

S3に転送したtarファイルを展開するか、
ソースデータベースサーバ上にあるtarファイルを展開して
xtrabackup_infoファイルのbinlog_posエントリをチェックします。
これにinnobackupexコマンド実行時のbinlogファイル名とpositionが記録されています

innobackupex実行時に出力されたxtrabackup_infoの確認

$ cat xtrabackup_info
uuid = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX
name =
tool_name = innobackupex
tool_command = --user=root --no-timestamp --stream=tar /s3-restore/backup
tool_version = 2.4.4
ibbackup_version = 2.4.4
server_version = 5.6.22-log
start_time = YYYY-MM-DD HH24:MI:SS
end_time = YYYY-MM-DD HH24:MI:SS
lock_time = 0
★binlog_pos = filename 'log-bin.000007', position '593'
innodb_from_lsn = 0
innodb_to_lsn = 1635907
partial = N
incremental = N
format = tar
compact = N
compressed = N
encrypted = N

RDS Auroraでレプリケーションの設定

mysql> CALL mysql.rds_set_external_master ('', 3306,'repl', '', ' CALL mysql.rds_start_replication;
+-------------------------+
| Message                 |
+-------------------------+
| Slave running normally. |
+-------------------------+
1 row in set (1.01 sec)

Query OK, 0 rows affected (1.01 sec)

RDS Auroraのレプリケーション確認

見事レプリケーションをはることができました

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: XXX.XXX.XXX.XXX
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log-bin.000008
          Read_Master_Log_Pos: 120
               Relay_Log_File: relaylog.000002
                Relay_Log_Pos: 8803
        Relay_Master_Log_File: log-bin-bin.000007
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table: mysql.rds_history,mysql.rds_replication_status,mysql.rds_sysinfo
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 9101
              Relay_Log_Space: 46351
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 161628
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: 94bf64f0-781a-11e6-a209-0672f0bff909
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Sending data
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
1 row in set (0.01 sec)
  • レプリケーション反映の確認

レプリケーションによってデータベースが移行されはじめました

mysql> show databases;
+---------------------------------+
| Database                        |
+---------------------------------+
| information_schema              |
| migrationtest                   |
| mysql                           |
| oregakangaetakuraudoikouyounodb |
| oregakangaetasaikyounodb        |
| orenodb                         |
| performance_schema              |
+---------------------------------+
7 rows in set (0.01 sec)
  • テーブルのデータ件数確認

レプリケーションにより、Xtrabackup時点で作られていたテーブルtest, myisam以外にitemというテーブルが作られました。
レプリケーションは追いついてないのでデータ件数は少ないかんじです。

mysql> use orenodb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------+
| Tables_in_orenodb |
+-------------------+
| item              |
| myisam            |
| test              |
+-------------------+
3 rows in set (0.00 sec)

mysql> SELECT COUNT(*) FROM item;
+----------+
| COUNT(*) |
+----------+
|    16384 |
+----------+
1 row in set (0.02 sec)

RDS Auroraへの切替

  • データベースへアクセスするアプリケーション/バッチなど全て停止します。
  • Master_Log_FileとRead_Master_Log_Posがソースデータベースのshow master status結果とおなじになるまで待ちます。
  • mysqlクライアントからRDS Auroraに接続してCALL mysql.rds_reset_external_masterを実行します
  • アプリケーション/バッチを実行するためのデータベースエンドポイントを全て書き換えます。
  • アプリケーション/バッチを再開します

俺のリストアを用いることでクッソ遅くて鼻ほじって待ってたら鼻血がでるまであったmysqldumpによるRDS Auroraへの移行も高速にできると考えられます。

次はソースデータベースをマスタ/スレーブ構成にして、試したいと思います。

最高!

元記事はこちら

Xtrabackupを使ったRDS Auroraへの移行パス、名付けて~俺のリストア(orenorestore)~