TiDB データ移行 (DM) のベスト プラクティス
TiDB データ移行 (DM)はPingCAPが開発したデータ移行ツールです。 MySQL、Percona MySQL、MariaDB、Amazon RDS for MySQL、Amazon Auroraなどの MySQL 互換データベースから TiDB への完全および増分データ移行をサポートします。
DM は次のシナリオで使用できます。
- 単一の MySQL 互換データベース インスタンスから TiDB への完全および増分データ移行を実行する
- 小さなデータセット (1 TiB 未満) の MySQL シャードを TiDB に移行してマージする
- 業務データの中間プラットフォーム、業務データのリアルタイム集約などのデータハブシナリオでは、DMをデータ移行のミドルウェアとして利用
このドキュメントでは、DM をエレガントかつ効率的に使用する方法と、DM を使用する際のよくある間違いを回避する方法を紹介します。
パフォーマンスの制限
パフォーマンスアイテム | 制限 |
---|---|
最大作業ノード | 1000 |
最大タスク数 | 600 |
最大 QPS | 30,000 QPS/ワーカー |
最大Binlogスループット | 20 MB/秒/ワーカー |
タスクごとのテーブル数の制限 | 無制限 |
- DM は 1000 個の作業ノードの同時管理をサポートし、タスクの最大数は 600 です。作業ノードの高可用性を確保するには、いくつかの作業ノードをスタンバイ ノードとして予約する必要があります。スタンバイ ノードの推奨数は、移行タスクを実行している作業ノードの数の 20% から 50% です。
- 単一の作業ノードは、理論的には最大 30K QPS/ワーカーのレプリケーション QPS をサポートできます。スキーマやワークロードによって異なります。アップストリームのバイナリログを処理する能力は、最大 20 MB/秒/ワーカーです。
- DM をデータ レプリケーション ミドルウェアとして長期間使用する場合は、DM コンポーネントの展開アーキテクチャを慎重に設計する必要があります。詳細については、 DM-master と DM-worker をデプロイを参照してください。
データ移行前
データ移行の前に、ソリューション全体の設計が重要です。次のセクションでは、ビジネスの観点と実装の観点から、ベスト プラクティスとシナリオについて説明します。
ビジネス側のベスト プラクティス
ワークロードを複数のノードに均等に分散するために、分散データベースの設計は従来のデータベースとは異なります。このソリューションでは、移行コストの削減と、移行後のロジックの正確性の両方を確保する必要があります。次のセクションでは、データ移行前のベスト プラクティスについて説明します。
スキーマ設計における AUTO_INCREMENT のビジネスへの影響
TiDB のAUTO_INCREMENT
は、MySQL のAUTO_INCREMENT
と互換性があります。ただし、分散データベースとして、TiDB には通常、複数のコンピューティング ノード (クライアント エンドのエントリ) があります。アプリケーション データが書き込まれると、ワークロードが均等に分散されます。これにより、テーブルにAUTO_INCREMENT
列がある場合、列の自動インクリメント ID が不連続になる可能性があります。詳細については、 自動増加を参照してください。
ビジネスが自動インクリメント ID に大きく依存している場合は、 SEQUENCE関数の使用を検討してください。
クラスタ化インデックスの使用
テーブルを作成するときに、主キーがクラスター化インデックスまたは非クラスター化インデックスのいずれかであることを宣言できます。以下のセクションでは、それぞれの選択肢の長所と短所について説明します。
クラスタ化インデックス
クラスタ化インデックスは、データ ストレージのハンドル ID (行 ID) として主キーを使用します。主キーを使用してクエリを実行すると、テーブル ルックアップを回避できるため、クエリのパフォーマンスが効果的に向上します。ただし、テーブルが書き込み集中型で、主キーが
AUTO_INCREMENT
を使用する場合、 ホットスポット問題を書くが発生する可能性が非常に高く、クラスターのパフォーマンスが平凡になり、単一のストレージ ノードのパフォーマンスのボトルネックになります。非クラスター化インデックス +
shard row id bit
非クラスター化インデックスと
shard row id bit
を使用すると、AUTO_INCREMENT
を使用するときの書き込みホットスポットの問題を回避できます。ただし、このシナリオでのテーブル ルックアップは、主キーを使用してクエリを実行するときのクエリ パフォーマンスに影響を与える可能性があります。クラスター化インデックス + 外部分散 ID ジェネレーター
クラスター化インデックスを使用して ID を連続させたい場合は、Snowflake アルゴリズムや Leaf などの外部分散 ID ジェネレーターの使用を検討してください。アプリケーション プログラムはシーケンス ID を生成します。これにより、ID がある程度連続していることを保証できます。また、クラスター化インデックスを使用する利点も保持されます。ただし、アプリケーションをカスタマイズする必要があります。
クラスタ化インデックス +
AUTO_RANDOM
このソリューションは、クラスター化インデックスを使用する利点を保持し、書き込みホットスポットの問題を回避できます。カスタマイズに必要な労力が少なくなります。書き込みデータベースとして TiDB を使用するように切り替えるときに、スキーマ属性を変更できます。後続のクエリで、ID 列を使用してデータを並べ替える必要がある場合は、
AUTO_RANDOM
ID 列と左シフト 5 ビットを使用して、クエリ データの順序を確保できます。例えば:CREATE TABLE t (a bigint PRIMARY KEY AUTO_RANDOM, b varchar(255)); Select a, a<<5 ,b from t order by a <<5 desc
次の表は、各ソリューションの長所と短所をまとめたものです。
シナリオ | 推奨される解決策 | 長所 | 短所 |
---|---|---|---|
非クラスター化インデックスを使用してテーブルを作成し、 SHARD_ROW_ID_BIT を設定します。主キー列としてSEQUENCE を使用します。 | データ書き込みのホットスポットを回避し、ビジネス データの継続性と単調な増加を確保できます。 | ||
非クラスター化インデックスを使用してテーブルを作成し、 SHARD_ROW_ID_BIT を設定します。アプリケーション ID ジェネレーターを使用して、主キー ID を生成します。 | データ書き込みホットスポットを回避し、データ書き込みのパフォーマンスを保証し、ビジネス データの増分を保証できますが、継続性は保証できません。 | ||
クラスター化インデックスを使用してテーブルを作成し、主キー列にAUTO_RANDOM を設定します。 | AUTO_INCREMENT からAUTO_RANDOM へスムーズに切り替えられます。 | ||
TiDB は読み取り専用データベースとして機能します。 | 非クラスター化インデックスを使用してテーブルを作成し、 SHARD_ROW_ID_BIT を設定します。主キー列をデータ ソースと一致させます。 | 主キーのクエリ パフォーマンスが影響を受けます。 |
MySQL シャードの重要なポイント
分割とマージ
DM to 小さなデータセットの MySQL シャードを TiDB に移行してマージするを使用することをお勧めします。
データの結合以外に、もう 1 つの典型的なシナリオはデータのアーカイブです。データは常に書き込まれています。時間の経過とともに、大量のデータが徐々にホット データからウォーム データ、さらにはコールド データに変化します。幸いなことに、TiDB ではデータに別の配置ルールを設定できます。ルールの最小粒度はパーティションです。
したがって、書き込みが集中するシナリオでは、データをアーカイブし、ホット データとコールド データを別々のメディアに保存する必要があるかどうかを最初から評価する必要があることをお勧めします。データをアーカイブする必要がある場合は、移行前にパーティショニング ルールを設定できます (TiDB はテーブルの再構築操作をまだサポートしていません)。将来、テーブルを再作成してデータをインポートする必要がなくなります。
悲観モードと楽観モード
DM はデフォルトで悲観モードを使用します。 MySQL シャードを移行およびマージするシナリオでは、アップストリーム シャード スキーマの変更により、ダウンストリーム データベースへの DML 書き込みがブロックされる可能性があります。すべてのスキーマが変更されて同じ構造になるまで待ってから、ブレークポイントから移行を続行する必要があります。
上流のスキーマの変更に時間がかかる場合、上流のBinlogがクリーンアップされる可能性があります。リレー ログを有効にして、この問題を回避できます。詳細については、 リレーログを使用するを参照してください。
アップストリームのスキーマ変更によってデータ書き込みをブロックしたくない場合は、オプティミスティック モードの使用を検討してください。この場合、DM は上流のシャード スキーマの変更を検出してもデータの移行をブロックしませんが、データの移行は続行します。ただし、DM がアップストリームとダウンストリームで互換性のないフォーマットを見つけた場合、移行タスクは停止します。この問題は手動で解決する必要があります。
次の表は、楽観モードと悲観モードの長所と短所をまとめたものです。
シナリオ | 長所 | 短所 |
---|---|---|
悲観モード (デフォルト) | ダウンストリームに移行されたデータが間違っていないことを確認できます。 | 多数のシャードがある場合、移行タスクは長時間ブロックされるか、上流のバイナリログがクリーンアップされている場合は停止することさえあります。リレー ログを有効にして、この問題を回避できます。詳細については、[リレー ログを使用する](#use-the relay-log) を参照してください。 |
楽観モード | アップストリーム スキーマの変更により、データ移行のレイテンシーが発生することはありません。 | このモードでは、スキーマの変更に互換性があることを確認します (増分列にデフォルト値があるかどうかを確認します)。矛盾したデータを見逃す可能性があります。詳細については、 オプティミスティック モードでのシャード テーブルからのデータのマージと移行を参照してください。 |
その他の制限と影響
アップストリームとダウンストリームのデータ型
TiDB はほとんどの MySQL データ型をサポートしています。ただし、一部の特殊な型はまだサポートされていません ( SPATIAL
など)。データ型の互換性については、 データ型を参照してください。
文字セットと照合
TiDB v6.0.0 以降、照合のための新しいフレームワークがデフォルトで使用されます。以前のバージョンでは、TiDB で utf8_general_ci、utf8mb4_general_ci、utf8_unicode_ci、utf8mb4_unicode_ci、gbk_chinese_ci、および gbk_bin をサポートする場合は、クラスターの作成時にnew_collations_enabled_on_first_bootstrap
からtrue
の値を設定して明示的に宣言する必要があります。詳細については、 照合のための新しいフレームワークを参照してください。
TiDB のデフォルトの文字セットは utf8mb4 です。上流および下流のデータベースとアプリケーションには utf8mb4 を使用することをお勧めします。上流のデータベースが文字セットまたは照合順序を明示的に指定している場合、TiDB がそれをサポートしているかどうかを確認する必要があります。
TiDB v6.0.0 以降、GBK がサポートされています。詳細については、次のドキュメントを参照してください。
展開のベスト プラクティス
DM-master と DM-worker をデプロイ
DM は、DM マスター ノードと DM ワーカー ノードで構成されます。
DM-master は、移行タスクのメタデータを管理し、DM-worker ノードをスケジュールします。これは、DM プラットフォーム全体の中核です。したがって、DM マスターをクラスターとしてデプロイして、DM プラットフォームの高可用性を確保できます。
DM-worker は、上流および下流の移行タスクを実行します。 DM-worker ノードはステートレスです。最大 1000 個の DM-worker ノードをデプロイできます。 DM を使用する場合は、高可用性を確保するためにアイドル状態の DM-worker を予約することをお勧めします。
移行タスクを計画する
MySQL シャードを移行およびマージする場合、アップストリームのシャードのタイプに従って移行タスクを分割できます。たとえば、 usertable_1~50
とLogtable_1~50
が 2 つのタイプのシャードである場合、2 つの移行タスクを作成できます。移行タスク テンプレートを簡素化し、データ移行の中断による影響を効果的に制御できます。
大規模なデータセットの移行については、次の提案を参照して、移行タスクを分割できます。
アップストリームで複数のデータベースを移行する必要がある場合は、データベースの数に応じて移行タスクを分割できます。
アップストリームの書き込み負荷に応じてタスクを分割します。つまり、アップストリームで DML 操作が頻繁に行われるテーブルを別の移行タスクに分割します。別の移行タスクを使用して、DML 操作を頻繁に行わずにテーブルを移行します。この方法は、特にアップストリームのテーブルに大量のログが書き込まれている場合に、移行の進行を高速化できます。しかし、大量のログを含むこのテーブルがビジネス全体に影響しない場合でも、この方法はうまく機能します。
移行タスクを分割しても、データの最終的な整合性のみが保証されることに注意してください。リアルタイムの一貫性は、さまざまな理由により大幅に逸脱する可能性があります。
次の表では、さまざまなシナリオでの DM-master と DM-worker の推奨される展開計画について説明します。
シナリオ | DMマスターの導入 | DM ワーカーの展開 |
---|---|---|
1 つの DM マスター ノードをデプロイ | アップストリーム データ ソースの数に応じて、1 ~ N 個の DM-worker ノードをデプロイします。通常、1 つの DM-worker ノードが推奨されます。 | |
長時間のデータ移行中に DM クラスターの可用性を確保するために、3 つの DM マスター ノードを展開することをお勧めします。 | データ ソースまたは移行タスクの数に応じて、DM ワーカー ノードをデプロイします。稼働中の DM-worker ノードに加えて、1~3 個のアイドル状態の DM-worker ノードをデプロイすることをお勧めします。 | |
長期データ複製 | 3 つの DM-master ノードをデプロイする必要があります。 DM マスター ノードをクラウドにデプロイする場合は、異なるアベイラビリティ ゾーン (AZ) にデプロイしてみてください。 | データ ソースまたは移行タスクの数に応じて、DM ワーカー ノードをデプロイします。実際に必要な DM-worker ノード数の 1.5~2 倍の数をデプロイする必要があります。 |
アップストリーム データ ソースの選択と構成
DM は、完全なデータ移行を実行するときにデータベース全体の完全なデータをバックアップし、並列論理バックアップ方式を使用します。 MySQL のバックアップ中に、グローバル読み取りロックが追加されますFLUSH TABLES WITH READ LOCK
。アップストリーム データベースの DML および DDL 操作は、短時間ブロックされます。したがって、アップストリームでバックアップ データベースを使用して完全なデータ バックアップを実行し、データ ソースの GTID 機能を有効にすることを強くお勧めします ( enable-gtid: true
)。このようにして、アップストリームからの影響を回避し、アップストリームのマスター ノードに切り替えて、増分移行中のレイテンシーを短縮できます。アップストリームの MySQL データ ソースを切り替える手順については、 アップストリーム MySQL インスタンス間の DM-worker 接続の切り替えを参照してください。
次の点に注意してください。
アップストリーム データベースのマスター ノードでのみ、完全なデータ バックアップを実行できます。
このシナリオでは、構成ファイル
mydumpers.global.extra-args: "--consistency none"
でconsistency
パラメーターをnone
に設定して、マスター ノードにグローバル読み取りロックを追加しないようにすることができます。ただし、これはフル バックアップのデータの整合性に影響を与える可能性があり、アップストリームとダウンストリームの間でデータの不整合が生じる可能性があります。バックアップ スナップショットを使用して、完全なデータ移行を実行します (AWS での MySQL RDS およびAurora RDS の移行にのみ適用されます)。
移行するデータベースが AWS MySQL RDS またはAurora RDS の場合、RDS スナップショットを使用して Amazon S3 のバックアップ データを直接 TiDB に移行し、データの一貫性を確保できます。詳細については、 Amazon Auroraから TiDB にデータを移行するを参照してください。
構成の詳細
大文字化
TiDB スキーマ名は、デフォルトでは大文字と小文字が区別されません (つまり、 lower_case_table_names:2
)。しかし、アップストリームの MySQL データベースのほとんどは、デフォルトで大文字と小文字を区別する Linux システムを使用しています。この場合、スキーマがアップストリームから正しく移行されるように、DM タスク構成ファイルでcase-sensitive
からtrue
を設定する必要があります。
たとえば、アップストリームにTable
などの大文字のテーブルとtable
などの小文字のテーブルの両方を持つデータベースがある場合、スキーマの作成時にエラーが発生します。
ERROR 1050 (42S01): Table '{tablename}' already exists
フィルター規則
データ ソースの構成を開始するとすぐに、フィルター ルールを構成できます。詳細については、 データ移行タスクConfiguration / コンフィグレーションガイドを参照してください。フィルター規則を構成する利点は次のとおりです。
- ダウンストリームが処理する必要があるBinlogイベントの数を減らして、移行の効率を向上させます。
- 不必要なリレー ログ ストレージを減らして、ディスク領域を節約します。
ノート:
MySQL シャードを移行およびマージするときに、データ ソースでフィルター ルールを構成している場合は、データ ソースと移行タスクの間でルールが一致していることを確認する必要があります。一致しない場合、移行タスクが増分データを長時間受信できないという問題が発生する可能性があります。
リレーログを使用する
MySQL のマスター/スタンバイ メカニズムでは、スタンバイ ノードがリレー ログのコピーを保存して、非同期レプリケーションの信頼性と効率を確保します。 DM は、DM-worker でのリレー ログのコピーの保存もサポートしています。保存場所や有効期限などの情報を設定できます。この機能は、次のシナリオに適用されます。
完全および増分データの移行中に、完全なデータの量が多い場合、アップストリームのバイナリログがアーカイブされる時間よりもプロセス全体に時間がかかります。これにより、増分レプリケーション タスクが正常に開始されなくなります。リレー ログを有効にすると、完全な移行が開始されたときに DM-worker がリレー ログの受信を開始します。これにより、増分タスクの失敗が回避されます。
DM を使用して長時間のデータ レプリケーションを実行すると、さまざまな理由で移行タスクが長時間ブロックされることがあります。リレー ログを有効にすると、移行タスクのブロックによってアップストリームの binlog がリサイクルされるという問題に効果的に対処できます。
リレーログの使用にはいくつかの制限があります。 DM は高可用性をサポートします。 DM-worker に障害が発生すると、アイドル状態の DM-worker インスタンスを稼働中のインスタンスに昇格させようとします。アップストリームのバイナリログに必要な移行ログが含まれていない場合、中断が発生する可能性があります。できるだけ早くリレー ログを新しい DM-worker ノードにコピーし、対応するリレー メタ ファイルを変更するには、手動で介入する必要があります。詳細については、 トラブルシューティングを参照してください。
アップストリームで PT-osc/GH-ost を使用する
通常、MySQL の日常的な運用と保守では、PT-osc/GH-ost などのツールを使用してオンラインでスキーマを変更し、ビジネスへの影響を最小限に抑えます。ただし、プロセス全体が MySQL Binlogに記録されます。そのようなデータを下流の TiDB に移行すると、多くの不要な書き込み操作が発生し、効率的でも経済的でもありません。
この問題を解決するために、移行タスクを構成するときに、DM は PT-osc や GH-ost などのサードパーティ データ ツールをサポートします。このようなツールを使用すると、DM は冗長なデータを移行せず、データの一貫性を確保します。詳細については、 GH-ost/PT-osc を使用するデータベースからの移行を参照してください。
移行中のベスト プラクティス
このセクションでは、移行中に発生する可能性がある問題のトラブルシューティング方法を紹介します。
アップストリームとダウンストリームでスキーマが一致していない
一般的なエラーは次のとおりです。
messages: Column count doesn't match value count: 3 (columns) vs 2 (values)
Schema/Column doesn't match
通常、このような問題は、下流の TiDB でインデックスが変更または追加されたことが原因で発生するか、下流にさらに列が存在することが原因です。このようなエラーが発生した場合は、上流と下流のスキーマが一致していないかどうかを確認してください。
このような問題を解決するには、DM にキャッシュされたスキーマ情報を更新して、ダウンストリームの TiDB スキーマと一致させます。詳細については、 移行するテーブルのテーブル スキーマの管理を参照してください。
下流にさらに列がある場合は、 より多くの列を持つ下流の TiDB テーブルにデータを移行するを参照してください。
DDL の失敗により移行タスクが中断されました
DM は、移行タスクを中断させる DDL ステートメントのスキップまたは置換をサポートしています。詳細については、 失敗した DDL ステートメントの処理を参照してください。
データ移行後のデータ検証
データ移行後にデータの整合性を検証することをお勧めします。 TiDB は、データ検証を完了するのに役立つ同期差分インスペクターを提供します。
sync-diff-inspector は、DM タスクを通じてデータの整合性をチェックするテーブル リストを自動的に管理できるようになりました。以前の手動構成と比較して、より効率的です。詳細については、 DM レプリケーション シナリオでのデータ チェックを参照してください。
DM v6.2.0 以降、DM は増分レプリケーションの継続的なデータ検証をサポートしています。詳細については、 DM での継続的なデータ検証を参照してください。
長期データ複製
DM を使用して長期間のデータ レプリケーション タスクを実行する場合は、メタデータをバックアップする必要があります。一方では、移行クラスターを再構築する機能が保証されます。一方、移行タスクのバージョン管理を実装できます。詳細については、 データ ソースのエクスポートとインポート、およびクラスターのタスクConfiguration / コンフィグレーションを参照してください。