MySQL の引っ越し

このブログのCMSには WordPress を利用しています。 データベースは Alibaba Cloud ECS インスタンス上にインストールしている MySQL です。 今回、この MySQL を Alibaba Cloud の ApsaraDB RDS に引っ越します。 

ツールには Alibaba Cloud が提供するマネージド型の Data Transmission Service を利用します。

引っ越しする理由ですが大した理由はありません。 1つは 昨年の Alibaba の独身の日のイベントに 安くAlibaba Cloud のプロダクトを購入出来たこと(11月に購入してやっと今から移行するのですが)、2つ目はシステムの信頼性向上のためです。 ApsaraDBに移行することで複数のゾーンに MySQL インスタンスは冗長化されバックアップも自動化できます(今回購入したBasic なので非ゾーン冗長化ですが。将来的に簡単に冗長化できるということで)。また、Web サービスを実行するフロントエンドのECS インスタンスを冗長化することでWebサービスとDBの冗長化を実現できるということもあります。

引っ越しの流れは以下です。

  1. ApsaraDB RDS の購入
  2. ApsaraDB RDS の初期設定
  3. 既存MySQL の調整
  4. Data Transmission Service による Database 移行
  5. ApsaraDB RDS での権限設定
  6. WordPress の設定変更(接続DBの切り替え)

1の ApsaraDB RDS (MySQL) の購入は2020年11月に実施済のため、手順2から以下進めていきます。

ApsaraDB for MySQL の初期設定

Alibaba Cloud コンソールにログインし、 ApsaraDB RDS の管理画面に移動します。

まずは Database の接続用のアカウントを作成します。

途中の画面は省略しますが wordpress 用と 管理目的の2つのアカウントを作成します。

ApsaraDB RDS への接続を許可する IPアドレスを Whitelist として登録します。

まずは ECS インスタンスです。

次は Data Transmission Service のIPアドレスです。この時 Data Transmission Service が使用するIPアドレスを把握する必要があります。 Alibaba Cloud Document Center にその情報はあります。 移行元の Database をインターネットに公開しそのパブリックIPアドレスに接続するパターンと移行元のDatabase が ECS インスタンス上にありプライベートIPアドレスで移行するパターンとで接続元のIPアドレスは変わります。

以下の通り、 Tokyo リージョンでは 100.104.112.0/24 からの接続を許可する必要があります。

“100.104.112.0/24” を RDS の Whitelist に追加します。

最終的に RDS の Whitelist は以下の状態です。

既存 MySQL の調整

この後の手順で Alibaba Cloud Data Transmission Service により既存の MySQL から ApsaraDB RDS (MySQL) にデータを移行するのですが、アカウントやその権限など既存の MySQL へ接続できるよう調整します。 環境に依存する部分はありますが、以下が調整の対象になります。

  1. MySQL の権限(アカウント、付与した権限、接続元IPアドレス)
  2. MySQL のバインドするIPアドレス
  3. OS の Firewall (iptables / Firewalld nado)
  4. Alibaba Cloud の Security Group

私の環境では MySQL を Internet には公開していません。 Security Group でも MySQL のポートは公開しておらず、OS の firewalld でもBlockし、また、MySQL でも ポートをバインドする IP アドレスは loopback アドレスに限定しています。 ということで1と2のみ対処を行います。 3と4ですが Data Transmission Service はプライベートネットワークからアクセスするため特に今回は設定変更は不要でした。

まずは MySQL の設定を確認します。 wordpress接続用のアカウントも 特権アカウントもIPアドレス(Data Transmission Service のIPアドレスとなる 100.104.112.135 ) での接続は出来ない状態です。

mysql> show grants for ‘wordpressuser’@’100.104.112.0/24’;
ERROR 1141 (42000): There is no such grant defined for user ‘wordpressuser’ on host ‘100.104.112.0/24’

今回は面倒なので緩くセキュリティ設定を行います。(後述しますが、以下の設定は誤りです。 netmaskは /24 ではなく 255.255.255.0 形式で指定する必要があります)

#権限付与
mysql> grant all on *.* to ‘wordpressuser’@’100.104.112.0/24’ identified by ‘<password>’;
Query OK, 0 rows affected, 1 warning (0.00 sec)

#付与した権限の確認
mysql> show grants for ‘wordpressuser’@’100.104.112.0/24’;
+—————————————————————-+
| Grants for wordpressuser@100.104.112.0 |
+—————————————————————-+
| GRANT ALL PRIVILEGES ON . TO ‘wordpressuser’@’100.104.112.0/24’ |
+—————————————————————-+
1 row in set (0.00 sec)

次に、”mysqld.cnf” の”bind-address” に ECS インスタンスのプライベート IP アドレスを追加します。 ファイルを保存後、”systemctl restart mysql.service” で MySQL を再起動します。

#
Instead of skip-networking the default is now to listen only on
localhost which is more compatible and is not less secure.
bind-address = 127.0.0.1
bind-address = 172.24.203.118

Data Transmission Service による Database 移行

Alibaba Cloud コンソールにログインし、 Data Transmission Service の管理画面にアクセスします。 

そこから “Create Migration Task” をクリックします。

まずは、移行元の既存の MySQL に接続するための情報を指定します。 今回は”User-Created Database in ECS Instance“を指定することで、インターネットに MySQL を公開することなく移行することが可能です。

“Test Connectivity” から Data Transmission Service から 移行元の MySQL への接続性を確認します。 “Passed” と表示されれば問題ありません。

失敗するときは原因の説明のウィンドウが表示されます。 例えば以下の例では、接続元IPアドレスを MySQL に正しく設定していないことがわかります (Access denied for user ‘wordpressuser’@’100.104.112.135’)。

次は移行先となる ApsaraDB RDS の情報を指定します。そのあとで”Test Connectivity” で接続性を確認します。 “Passed” と表示されれば OKです。

次に、移行する Database を指定します。 

今回は”sys”は移行対象とせず、”wordpress”のみ移行対象とします。

次のPrecheck で Error となりました。 “Error: Get schema list failed, reason[Access denied for user ‘wordpressuser’@’100.104.112.52’ (using password:YES)” とのことで、移行元のMySQL に対して指定したアカウントでは接続が拒否されたようです。

上記のエラーは単純に 移行元のMySQL で “flush privileges” を実行していなかったためでした。 

やっと Precheck の処理が開始されたのですが、またエラーです。 “Check whether the DTS server can connect to the source database.” とのことで、Data Transmission Service から移行元へのMySQLの接続に問題があるようです。 

エラーの詳細を確認します。 “The username or password of the source database is incorrect.” とのこと。

前のステップでの接続テストでは成功していたのですが、、、失敗とのこと。 移行元の MySQL のログを確認します。 最終行の Access denied に着目します。送信元 “100.104.112.0” からの接続を拒否したとのこと。  しかし、ホストアドレスが”0″ はちょっと気持ちわるいですね。 まあ、各パブリッククラウドとも仮想ネットワークはオンプレミスのネットワークとは似て非なる世界ではありますが。

root@bigriver3:/var/log/mysql# tail error.log
2021-01-03T01:38:11.422140Z 2099 [Note] Got an error reading communication packets
2021-01-03T01:38:21.460368Z 2101 [Note] Got an error reading communication packets
2021-01-03T01:39:04.100342Z 2100 [Note] Aborted connection 2100 to db: ‘unconnected’ user: ‘wordpressuser’ host: ‘100.104.112.135’ (Got an error reading communication packets)
2021-01-03T01:39:10.939456Z 2104 [Note] Got an error reading communication packets
2021-01-03T01:39:49.736212Z 2106 [Note] Got an error reading communication packets
2021-01-03T01:40:01.466310Z 2108 [Note] Got an error reading communication packets
2021-01-03T01:40:01.854061Z 2109 [Note] Access denied for user ‘wordpressuser’@’100.104.112.0’ (using password: YES)

再度、MySQL に割り当てた権限を確認します。 subnet mask は 24 bit を指定しています。 

mysql> show grants for ‘wordpressuser’@’100.104.112.0/24’;
+——————————————————————-+
| Grants for wordpressuser@100.104.112.0/24 |
+——————————————————————-+
| GRANT ALL PRIVILEGES ON . TO ‘wordpressuser’@’100.104.112.0/24’ |
+——————————————————————-+
1 row in set (0.00 sec)

もしかしてと思い、MySQL のマニュアルを確認します。 netmask は “/24″ ではなく”255.255.255.0” と指定する必要がありました。もしくは “%” を利用したワイルドカード表記。

再度、MySQL のアクセス権を以下の通り見直しました。

mysql> show grants for ‘wordpressuser’@’100.104.112.0/255.255.255.0’;
+——————————————————————————+
| Grants for wordpressuser@100.104.112.0/255.255.255.0 |
+——————————————————————————+
| GRANT ALL PRIVILEGES ON . TO ‘wordpressuser’@’100.104.112.0/255.255.255.0’ |
+——————————————————————————+
1 row in set (0.00 sec)

Data Transmission Service に戻り再度 Precheck を実行します。成功しました。

ここで Data Transmission Service のインスタンスにどのタイプを購入するか選択します。 small でも大丈夫だとは思いますが、既定の medium のまま進めます。

Data Transmission Service の購入後に Migration Task はすぐに開始されます。 データ量が少ないこともあり1分ほどで完了しました。

View Details から移行データの詳細も確認可能です。

ApsaraDB RDS での権限設定

Data Transmission Service による移行が完了したことで、ApsaraDB RDS 上にDatabase が作成されました。 この Database に WordPress から接続するアカウントに適切な権限を付与します。

ApsaraDB RDS の管理画面から Accounts に移動し、Edit Account Permissions から今回対象となる database “wordpress” に権限を付与します。

wordpress の設定変更 (接続DBの切り替え)

最後にwordpress の設定を変更し、接続する MySQL を今回移行した ApsaraDB RDS に切り替えます。 太字にした3か所を変更します。 DB_USER と DB_PASSWORD は ApsaraDB RDS に作成したアカウントを指定します。 DB_HOST には ApsaraDB RDS の Internal Endpoint のアドレスを指定します。

wp-config.php

// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */
define(‘DB_NAME’, ‘wordpress’);
/** MySQL database username */
define(‘DB_USER’, ‘wordpressuser‘);
/** MySQL database password */
define(‘DB_PASSWORD’, ‘<password>‘);
/** MySQL hostname */
define(‘DB_HOST’, ‘rm-0iwy89d077of47i0v70070.mysql.japan.rds.aliyuncs.com‘);
/** Database Charset to use in creating database tables. */
define(‘DB_CHARSET’, ‘utf8’);
/** The Database Collate type. Don’t change this if in doubt. */
define(‘DB_COLLATE’, ”);

移行元の MySQL のサービスを停止し、自動起動も無効化します。

root@bigriver3:~# systemctl stop mysql.service
root@bigriver3:~# systemctl disable mysql.service
Synchronizing state of mysql.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable mysql
root@bigriver3:~# systemctl status mysql.service
● mysql.service – MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; disabled; vendor preset: e
Active: inactive (dead)
Dec 26 11:29:23 bigriver3 systemd[1]: Starting MySQL Community Server…
Dec 26 11:29:25 bigriver3 systemd[1]: Started MySQL Community Server.
Jan 01 20:51:23 bigriver3 systemd[1]: Stopping MySQL Community Server…
Jan 01 20:51:25 bigriver3 systemd[1]: Stopped MySQL Community Server.
Jan 01 20:51:25 bigriver3 systemd[1]: Starting MySQL Community Server…
Jan 01 20:51:25 bigriver3 systemd[1]: Started MySQL Community Server.
Jan 03 10:45:55 bigriver3 systemd[1]: Stopping MySQL Community Server…
Jan 03 10:45:57 bigriver3 systemd[1]: Stopped MySQL Community Server.

接続先が切り替わったかどうかは tcpdump でパケットキャプチャして確認します。 172.24.203.127.mysql に接続していることがわかります。 172.24.203.127 は ApsaraDB RDS の Internal Endpoint のプライベートIPアドレスです。

これで切り替えは完了です。

まとめ

今回、 ECS インスタンス上の MySQL を ApsaraDB RDS に移行できること、その際に Data Transmission Service を利用することで簡単かつ確実にそしてほぼコストをかけずに実施できることが確認できました。 Incremental での同期も可能なため、大容量のデータベースの場合は事前に初回同期を実施し、あとは本番切り替えまでは毎日差分同期を実行するというような切り替え方式を利用することも可能です。

今回は移行で利用しましたが、バックアップサイトに配置したデータベースとの同期などにも使えます(今回利用した Migration Task ではなくData Synchronization Task を利用)。  ま

また、 Data Transmission Service では異なるアーキテクチャ間の移行も可能です。  MySQL から MySQL はもちろん PostgreSQL や Oracle、その他Alibaba Cloud のPolarDB や AnalyticsDB 、DRDS など様々なデータベースの移行パスを提供しています。 移行元は MySQL だけではなく MS SQL Server や PostgreSQL 、Oracle などこちらも豊富なオプションを提供しています。詳細は Document Centerを確認してみてください。

以上