ApsaraDB RDS for MySQL は、2019年8月1日をもって TokuDB ストレージエンジンのサポートを終了しました。このトピックでは、テーブルを TokuDB エンジンから InnoDB エンジンに変換する方法について説明します。
背景情報
Percona 社は TokuDB のサポートを終了しました。これにより、既知のバグが修正されず、ビジネスに支障をきたす可能性があります。このため、Alibaba Cloud は2019年8月1日に ApsaraDB RDS for MySQL における TokuDB ストレージエンジンのサポートを終了しました。ストレージエンジンを直接変換すると DML 操作がブロックされ、同時実行性に影響を与える可能性があります。ビジネス要件を評価した上で、以下のいずれかのソリューションを選択して変換を実行してください。
TokuDB エンジンの提供終了日
2019年8月1日
適用範囲
TokuDB ストレージエンジンを使用しているインスタンスが対象です。
show engines; コマンドを実行してインスタンスのデフォルトのストレージエンジンを表示するか、 show create table <table_name>; コマンドを実行して特定のテーブルのストレージエンジンを表示できます。
注意事項
-
ストレージエンジンを変換すると、ストレージ使用量が増加します。約 TokuDB テーブルの 2 倍のサイズの空き領域を確保する必要があります。操作中は、ストレージ使用量を注意深く監視してください。
-
変換後、CPU 使用率は低下しますが、IOPS は増加します。これは、データページが圧縮されないため、同量のデータを読み取るためにより多くの I/O 操作が必要になるためです。
-
フルマイグレーションを実行する際は、アプリケーションのエンドポイントを切り替える必要があります。ビジネスへの影響を最小限に抑えるため、この操作はピーク時間外に実行することを推奨します。
-
フルマイグレーション中にデータベースのバージョンを変更する場合は、事前に互換性テストを実施することを推奨します。
推奨ソリューション
-
テーブルが小さい (100 MB 未満) 場合や、アプリケーションが短時間の中断を許容できる場合は、ソリューション1を使用してください。この方法では、テーブルのロック時間が短く、複雑なツールの設定を回避できます。
-
テーブルが大きい (5 GB 超) 場合は、ソリューション2またはソリューション3を使用してください。
-
インスタンス内のすべてのテーブルを変換する必要がある場合は、ソリューション3またはソリューション4を使用してください。
-
エンジンを変換した後、[default_storage_engine] インスタンスパラメーターを [InnoDB] に変更します。
ソリューション1
このソリューションでは、ALTER TABLE 文を使用してエンジンを直接変換します。これは最も簡単な方法ですが、テーブルに対する DML 操作をブロックするため、大きなテーブルの場合は時間がかかる可能性があります。
-
上部のナビゲーションバーで、 を選択します。
-
以下のコマンドを実行します。
ALTER TABLE test.testfs ENGINE=innodb;【SQL実行: (1)】 Alter table test.testfs engine innodb 実行に成功しました。所要時間: [18185ms]
ソリューション2
このソリューションでは、サードパーティのオンラインスキーマ変更ツールを使用して、ダウンタイムを最小限に抑えて変換を実行します。Percona 社の pt-osc や GitHub の gh-ost など、多くのツールがオンライン DDL をサポートしています。このセクションでは、gh-ost を例として使用します。詳細については、公式の gh-ost ドキュメントをご参照ください。
仕組み
gh-ost は、元のテーブルと同じスキーマを持つ一時的な「ゴースト」テーブルを作成することで動作します。元のテーブルからすべてのデータをコピーし、次にレプリケーションをシミュレートしてバイナリログを読み取り、増分変更をリアルタイムでゴーストテーブルに同期します。最後に、ピーク時間外にテーブルの名前を変更することでカットオーバーを実行します。主なパフォーマンスへの影響は、初期データコピー時の I/O 負荷であり、これはパラメーターを使用して調整できます。
-
メリット:柔軟に制御でき、カットオーバーのスケジュールを調整できます。
-
デメリット:テーブルごとにコマンドを実行する必要があり、テーブル数が多い場合は手間がかかります。
パラメーター
|
パラメーター |
説明 |
|
--initially-drop-old-table |
以前の失敗した移行で残ったテーブルをチェックし、削除します。 |
|
--initially-drop-ghost-table |
既存のゴーストテーブルをチェックし、削除します。 |
|
--aliyun-rds |
Alibaba Cloud ApsaraDB RDS for MySQL インスタンスで操作を実行することを指定します。 |
|
--assume-rbr |
バイナリログの形式が、行ベースレプリケーション (RBR) であることを指定します。 |
|
--allow-on-master |
gh-ost をプライマリデータベースで実行することを許可します。 |
|
--assume-master-host |
プライマリデータベースのエンドポイント。 |
|
--user |
データベースアカウント名。 |
|
--password |
データベースのパスワード。 |
|
--host |
データベースのエンドポイント。これはプライマリデータベースのエンドポイントと同じでなければなりません。 |
|
--database |
データベース名。 |
|
--table |
テーブル名。 |
|
--alter |
実行する DDL 文。 |
|
--chunk-size |
各バッチでコピーする行数。 |
|
--postpone-cut-over-flag-file |
カットオーバーが延期されていることを示すファイル。このファイルを削除すると、直ちにテーブルのカットオーバーが開始されます。 |
|
--panic-flag-file |
このファイルが作成されると、gh-ost プロセスは直ちに停止します。 |
|
--serve-socket-file |
対話型コマンドを受け取るためのソケットファイル。 |
|
--execute |
操作を実行するように指定します。 |
前提条件
-
オンプレミスホストまたは Elastic Compute Service (ECS) インスタンスに gh-ost がインストールされていること。
-
オンプレミスホストまたは ECS インスタンスの IP アドレスが、ApsaraDB RDS インスタンスの IP アドレスホワイトリストに追加されていること。
手順
-
オンプレミスホストまたは ECS インスタンスで、次のコマンドを実行して変換を開始し、プロセスが完了するのを待ちます。
gh-ost --user="test01" --password="Test123456" --host="rm-bpxxxxx.mysql.rds.aliyuncs.com" --database="test" --table="testfs" --alter="engine=innodb" --initially-drop-old-table --initially-drop-ghost-table --aliyun-rds --assume-rbr --allow-on-master --assume-master-host="rm-bpxxxxx.mysql.rds.aliyuncs.com" --chunk-size=500 --postpone-cut-over-flag-file="/tmp/ghostpost.postpone" --panic-flag-file="/tmp/stop.flag" --serve-socket-file="/tmp/ghost.sock" --execute2019/06/13 17:22:51 binlogsyncer.go:79: [info] create BinlogSyncer with config {999 2019/06/13 17:22:51 binlogsyncer.go:246: [info] begin to sync binlog from position 2019/06/13 17:22:51 binlogsyncer.go:139: [info] register slave for master server rm 2019/06/13 17:22:51 binlogsyncer.go:573: [info] rotate to (mysql-bin.000014, 241268 # Migrating `test`.`testfs`; Ghost table is `test`.`_testfs_gho` # Migrating `xxx`.`xxx`; xxx xxx rds.aliyuncs.com:3306; inspecting xxx # Migration started at Thu Jun 13 17:22:50 +0800 2019 # chunk-size: 500; max-lag-millis: 1500ms; dml-batch-size: 10; max-load: ; critical # throttle-additional-flag-file: /tmp/gh-ost.throttle # postpone-cut-over-flag-file: /tmp/ghostpost.postpone [set] # panic-flag-file: /tmp/stop.flag # Serving on unix socket: /tmp/ghost.sock Copy: 0/100000 0.0%; Applied: 0; Backlog: 0/1000; Time: 0s(total), 0s(copy); stream Copy: 0/100000 0.0%; Applied: 0; Backlog: 0/1000; Time: 1s(total), 1s(copy); stream Copy: 1500/100000 1.5%; Applied: 0; Backlog: 0/1000; Time: 2s(total), 2s(copy); str Copy: 3000/100000 3.0%; Applied: 0; Backlog: 0/1000; Time: 3s(total), 3s(copy); str Copy: 5500/100000 5.5%; Applied: 0; Backlog: 0/1000; Time: 4s(total), 4s(copy); str Copy: 7500/100000 7.5%; Applied: 0; Backlog: 0/1000; Time: 5s(total), 5s(copy); str Copy: 9000/100000 9.0%; Applied: 0; Backlog: 0/1000; Time: 6s(total), 6s(copy); str Copy: 10500/100000 10.5%; Applied: 0; Backlog: 0/1000; Time: 7s(total), 7s(copy); s Copy: 13500/100000 13.5%; Applied: 0; Backlog: 0/1000; Time: 8s(total), 8s(copy); s Copy: 15500/100000 15.5%; Applied: 0; Backlog: 0/1000; Time: 9s(total), 9s(copy); s Copy: 17500/100000 17.5%; Applied: 0; Backlog: 0/1000; Time: 10s(total), 10s(copy); -
左側のメニューでテーブルを表示します。
_ghoと_ghcで終わる一時テーブルが表示されます。test データベースのテーブルリストに、gh-ost によって作成された一時テーブル_testfs_ghcと_testfs_ghoが表示され、変換が進行中であることがわかります。 -
テーブルのカットオーバーを開始するには、
rm /tmp/ghostpost.postponeコマンドを実行します。 以下の出力が表示されます。Copy: 100000/100000 100.0%; Applied: 0; Backlog: 0/1000; Time: 9m0s(total), 56s(copy); streamer: mysql-bin.000015:520562237; Copy: 100000/100000 100.0%; Applied: 0; Backlog: 0/1000; Time: 9m30s(total), 56s(copy); streamer: mysql-bin.000015:520674422; # Migrating `test`.`testfs`; Ghost table is `test`.`_testfs_gho` # Migrating xxx xxx xxx mysql.rds.aliyuncs.com:3306; inspecting xxx xxx xxx xxx mysql.rds.aliyuncs.com:3306 # Migration started at Thu Jun 13 17:22:50 +0800 2019 # chunk-size: 500; max-lag-millis: 1500ms; dml-batch-size: 10; max-load: ; critical-load: ; nice-ratio: 0.000000 # throttle-additional-flag-file: /tmp/gh-ost.throttle # postpone-cut-over-flag-file: /tmp/ghostpost.postpone # panic-flag-file: /tmp/stop.flag # Serving on unix socket: /tmp/ghost.sock Copy: 100000/100000 100.0%; Applied: 0; Backlog: 0/1000; Time: 9m31s(total), 56s(copy); streamer: mysql-bin.000015:520681377; 2019/06/13 17:32:23 binlogsyncer.go:107: [info] syncer is closing... 2019/06/13 17:32:23 binlogstreamer.go:47: [error] close sync with err: sync is been closing... 2019/06/13 17:32:23 binlogsyncer.go:122: [info] syncer is closed説明出力のエラーメッセージは無視してかまいません。カットオーバーは完了しています。
-
テーブルスキーマを確認し、データを検証します。
説明データが正しいことを確認した後、gh-ost によって元のテーブルからリネームされた
_testfs_delテーブル (命名規則は_<元のテーブル名>_del) を削除できます。show create table `testfs`;を実行してテーブルスキーマを表示し、AUTO_INCREMENTの値が100001であることを確認してください。これは、すべてのデータが保持されていることを示します。
ソリューション3
このソリューションでは、Alibaba Cloud Data Transmission Service (DTS) を使用して、元のテーブルから InnoDB エンジンを使用する一時テーブルにデータを同期します。その後、ピーク時間外にテーブル名の変更を実行します。このソリューションは、多数のテーブルを同時に変換する場合に適しています。
-
上部のナビゲーションバーで、を選択します。
-
次のコマンドを実行して、InnoDB エンジンを使用する一時テーブルを作成します:
CREATE TABLE `testfs_tmp` ( `id` int(11) NOT NULL AUTO_INCREMENT, `vc` varchar(8000) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=innodb DEFAULT CHARSET=utf8; -
データ同期インスタンスを購入しますデータ同期インスタンスを購入します。
説明データ同期インスタンスは有料サービスです。詳細については、「Data Transmission Service の料金」をご参照ください。
-
DTS コンソールの左側のメニューで、データ同期 をクリックします。
-
購入したデータ同期インスタンスを見つけ、[操作] 列で [同期チャネルの設定] をクリックします。
-
ソースインスタンスとターゲットインスタンスを設定します。
セクション
パラメーター
説明
ソースインスタンスの詳細
インスタンスタイプ
RDS インスタンス を選択します。
インスタンスID
変換したい TokuDB テーブルが含まれる RDS インスタンスを選択します。
暗号化
[非暗号化] または SSL セキュア接続 を選択します。SSL セキュア接続 を選択した場合は、まず SSL 暗号化を有効にする必要があります。このオプションは CPU 使用率を大幅に増加させます。
ターゲットインスタンスの詳細
インスタンスタイプ
RDS インスタンス を選択します。
インスタンスID
変換したい TokuDB テーブルが含まれる RDS インスタンスを選択します。
暗号化
[非暗号化] または SSL セキュア接続 を選択します。SSL セキュア接続 を選択した場合は、まず SSL 暗号化を有効にする必要があります。このオプションは CPU 使用率を大幅に増加させます。
このページには、[同期ジョブ名] フィールドと [インスタンスリージョン] ドロップダウンリスト (例:中国 (杭州)) も含まれています。設定後、[ホワイトリストを設定して次へ] をクリックします。
-
[ホワイトリストを設定して次へ] をクリックします。
-
同期アカウントが作成されるのを待ち、次へ をクリックします。
-
同期オブジェクトを設定します:[同期タイプ] を [一方向同期 (DML+DDL)] に設定し、[既存のターゲットテーブルの処理モード] を [事前チェックとエラー報告] に設定します。左側の [ソースオブジェクト] ペインで、test002 データベースの testfs テーブルを選択し、右側の [選択したオブジェクト] ペインに移動して、オブジェクトにカーソルを合わせて 編集 をクリックします。
-
データベース名 を、以前に作成した testfs_tmp に変更し、OK をクリックします。
-
次へ をクリックします。
-
[初期フルデータ同期] のみを選択し ([スキーマ移行] は選択せずに)、事前チェックして開始する をクリックします。
-
事前チェックが完了するのを待ち、閉じる をクリックします。
-
データ同期のレイテンシーが 0 ms になるまで待ちます。同期タスクのステータスが [同期中] に変わり、データ同期が開始されたことを示します。
-
DMS SQL ウィンドウで、テーブル名を切り替えるには、以下のコマンドを実行します。
RENAME TABLE `testfs` TO `testfs_del`, `testfs_tmp` TO `testfs`;説明-
テーブルが切り替えられた後、DTS タスクはエラーを報告します。これは想定される動作です。
-
データを検証した後、追加料金が発生しないよう、できるだけ早くデータ同期インスタンスをリリースしてください。
-
ソリューション4
このソリューションでは、DTS を使用してデータベースのフルマイグレーションを新しいインスタンスに実行します。このアプローチは、インスタンスのアップグレードも計画している場合や、アプリケーションがカットオーバーのためのより長いダウンタイムを許容できる場合に適しています。
-
ソースインスタンスからスキーマを
CREATE TABLE文としてエクスポートします。スクリプトで、各テーブルのENGINE句を変更します。説明たとえば、
create table t1(id int,name varchar(10)) engine=tokudb;をcreate table t1(id int,name varchar(10)) engine=innodb;に変更します。 -
ApsaraDB RDS for MySQL インスタンスを作成し、変更したスクリプトを実行して InnoDB エンジンでデータベースとテーブルを作成します。
-
DTS を使用して、ソースインスタンスから新しいインスタンスにデータを同期しますソースインスタンスから新しいインスタンスにデータを同期します。
説明DTS タスクを設定する際は、[初期フルデータ同期] のみを選択してください。
-
同期レイテンシーがゼロであることを確認した後、アプリケーションのエンドポイントを新しいインスタンスに切り替えます。