はじめに
仮想マシン上にホストしていたMySQLをAzure Databaseに移行する機会があったのですが、準備作業に手間がかかったので、ToDoとしてまとめておきます。
前提
-
ソース
Ubuntu 18.04
MySQL 5.7 -
ターゲット
Azure Database for MySQL (ver 5.7)
SKU Standard
Private Link & Private Endpoint
構成
設定変更が必要だったのですが、要件の都合上ダウンタイムが許容されないため移行用のソースDB(レプリカ)を作成し、データ同期を行いました。
やること
詳細はこちらを参照ください。
以降ポイント抑えて紹介します。
- 設定変更
次の構成を使用して、ソースDBの my.ini (Windows) または my.cnf (Unix) ファイルのバイナリ ログを有効にします。(要再起動)
[mysqld]
...
binlog_format = row
log_slave_updates = 1
...
- 移行用ユーザを作成
ソースDBに対し移行用ユーザを用意します。※ユーザ名とパスワードは適宜変更ください
CREATE USER 'dms'@'%' IDENTIFIED BY 'secret';
GRANT REPLICATION SLAVE ON *.* TO 'dms'@'%';
GRANT REPLICATION CLIENT ON *.* TO 'dms'@'%';
GRANT ALL PRIVILEGES ON <migration db>.* TO 'dms'@'%';
FLUSH PRIVILEGES;
- ターゲットDBインスタンスの作成
Azure Databaseを作成します。詳細はこちらを参照ください。
作成する際、一部のパラメータの変更します。
innodb_lock_wait_timeout = 1073741824
-
Private Link&Private Endpoint設定
こちら必須ではないですが、Azure Databaseに対しVNet内からのアクセスしか許容しないようなセキュアな要件が必要なケースは推奨です。詳細はこちらを参照し作成ください。 -
外部キー解除
ソースDB内に外部キーが存在しているかチェックします。
クエリ後半の...KCU.REFERENCED_TABLE_SCHEMA = 'SchemaName'...
のSchemaNameは適宜DB名に変更ください。
存在しているようでしたら抽出結果のdropクエリを発行し、解除ください。
移行完了後、再度外部キーを設定する時のために設定(Add)クエリを控えるように。
SET group_concat_max_len = 8192;
SELECT SchemaName, GROUP_CONCAT(DropQuery SEPARATOR ';\n') as DropQuery, GROUP_CONCAT(AddQuery SEPARATOR ';\n') as AddQuery
FROM
(SELECT
KCU.REFERENCED_TABLE_SCHEMA as SchemaName,
KCU.TABLE_NAME,
KCU.COLUMN_NAME,
CONCAT('ALTER TABLE ', KCU.TABLE_NAME, ' DROP FOREIGN KEY ', KCU.CONSTRAINT_NAME) AS DropQuery,
CONCAT('ALTER TABLE ', KCU.TABLE_NAME, ' ADD CONSTRAINT ', KCU.CONSTRAINT_NAME, ' FOREIGN KEY (`', KCU.COLUMN_NAME, '`) REFERENCES `', KCU.REFERENCED_TABLE_NAME, '` (`', KCU.REFERENCED_COLUMN_NAME, '`) ON UPDATE ',RC.UPDATE_RULE, ' ON DELETE ',RC.DELETE_RULE) AS AddQuery
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU, information_schema.REFERENTIAL_CONSTRAINTS RC
WHERE
KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
AND KCU.REFERENCED_TABLE_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA
AND KCU.REFERENCED_TABLE_SCHEMA = 'SchemaName') Queries
GROUP BY SchemaName;
- トリガー解除
移行時のデータ整合性担保の為に一時的にトリガーを解除します。表示された結果内容を発行します。
SELECT Concat('DROP TRIGGER ', Trigger_Name, ';') FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'your_schema';
- LOBのデータ型確認
mediumtext / longtext / blob /mediumblob / longblob
型のカラムを探し、32KB(32768byte)を超えていないか確認です。超えている場合、ターゲットDBにおいて切り捨てられるため、ソースDBに対し、下記クエリでデータの長さを確認します。
SELECT max(length(foo)) as LEN from hoge;
移行プロジェクトを作成する際、移行ウィザードの[移行の設定の構成]のステップでLOBに関する設定変更が可能ですので、こちらでLOBのデータ長を入力ください。
- スキーマの移行
ソースDBからDBスキーマをエクスポートします。
mysqldump -h [servername] -u [username] -p[password] --databases [db name] --no-data > [schema file path]
ex) mysqldump -h 192.168.0.4 -u foo -p --databases soruce --no-data > ~/import.dump
エクスポートしたスキーマ内に DEFINER
が含まれているかを find
コマンド等でチェックし、存在する場合は除外します。
ex) sed -i -e 's/DEFINER=`root`@`localhost`//g' [schema file path]
ターゲットDBへインポート
mysql -h [servername] -u [username] -p[password] [database] < [schema file path]
ex) mysql -h hoge.mysql.database.azure.com -u foo -p target < ~/import.dump
その他
- ターゲットDBの価格レベル(インスタンスサイズ)の変更は可能か?
可能でした。
当初コスト抑制のため、最小スペック(GP 2vCore)でターゲットを立てましたが、本番稼働ではメモリ最適化タイプへの価格レベル変更が必要でした。
切り替え前に価格レベルの変更を行ってみましたが、特に問題なくできました。
DMS側で何かエラーが発生していた形跡はなかったと記憶してます。
参考
https://docs.microsoft.com/ja-jp/azure/dms/tutorial-mysql-azure-mysql-online
https://docs.microsoft.com/ja-jp/azure/dms/known-issues-troubleshooting-dms