大規模なデータセットの MySQL シャードをTiDB Cloudに移行およびマージする
このドキュメントでは、大きな MySQL データセット (たとえば、1 TiB を超える) をさまざまなパーティションからTiDB Cloudに移行してマージする方法について説明します。完全なデータ移行の後、 TiDB データ移行 (DM)を使用して、ビジネス ニーズに応じて増分移行を実行できます。
このドキュメントの例では、複数の MySQL インスタンスにまたがる複雑なシャード移行タスクを使用し、自動インクリメント主キーの競合を処理します。この例のシナリオは、単一の MySQL インスタンス内の異なるシャード テーブルからのデータのマージにも適用できます。
例の環境情報
このセクションでは、例で使用される上流クラスター、DM、および下流クラスターの基本情報について説明します。
アップストリーム クラスタ
上流クラスタの環境情報は以下の通りです。
MySQL バージョン: MySQL v5.7.18
MySQL インスタンス 1:
- スキーマ
store_01と表[sale_01, sale_02] - スキーマ
store_02と表[sale_01, sale_02]
- スキーマ
MySQL インスタンス 2:
- スキーマ
store_01と表[sale_01, sale_02] - スキーマ
store_02と表[sale_01, sale_02]
- スキーマ
テーブル構造:
CREATE TABLE sale_01 ( id bigint(20) NOT NULL auto_increment, uid varchar(40) NOT NULL, sale_num bigint DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY ind_uid (uid) );
DM
DM のバージョンは v5.3.0 です。 TiDB DM を手動で展開する必要があります。詳細な手順については、 TiUP を使用して DMクラスタをデプロイを参照してください。
外部記憶装置
このドキュメントでは、Amazon S3 を例として使用します。
ダウンストリーム クラスター
シャードされたスキーマとテーブルは、テーブルstore.salesにマージされます。
MySQL からTiDB Cloudへの完全なデータ移行を実行する
以下は、MySQL シャードの全データをTiDB Cloudに移行およびマージする手順です。
次の例では、テーブルのデータをCSV形式にエクスポートするだけで済みます。
ステップ 1.Amazon S3 バケットにディレクトリを作成する
Amazon S3 バケットに第 1 レベルのディレクトリstore (データベースのレベルに対応) と第 2 レベルのディレクトリsales (テーブルのレベルに対応) を作成します。 salesで、各 MySQL インスタンスに第 3 レベルのディレクトリを作成します (MySQL インスタンスのレベルに対応)。例えば:
- MySQL instance1 のデータを
s3://dumpling-s3/store/sales/instance01/に移行する - MySQL instance2 のデータを
s3://dumpling-s3/store/sales/instance02/に移行します
複数のインスタンスにまたがるシャードがある場合は、データベースごとに第 1 レベルのディレクトリを 1 つ作成し、シャード テーブルごとに第 2 レベルのディレクトリを 1 つ作成できます。次に、管理を容易にするために、各 MySQL インスタンスに第 3 レベルのディレクトリを作成します。たとえば、テーブルstock_N.product_Nを MySQL インスタンス 1 と MySQL インスタンス 2 からTiDB Cloudのテーブルstock.productsに移行してマージする場合は、次のディレクトリを作成できます。
s3://dumpling-s3/stock/products/instance01/s3://dumpling-s3/stock/products/instance02/
ステップ 2. Dumpling を使用してデータを Amazon S3 にエクスポートする
Dumplingのインストール方法については、 Dumpling紹介を参照してください。
Dumplingを使用してデータを Amazon S3 にエクスポートする場合は、次の点に注意してください。
- アップストリーム クラスターの binlog を有効にします。
- 正しい Amazon S3 ディレクトリとリージョンを選択します。
- アップストリーム クラスタへの影響を最小限に抑えるために
-tオプションを設定するか、バックアップ データベースから直接エクスポートして、適切な同時実行数を選択します。このパラメーターの使用方法について詳しくは、 Dumplingのオプション一覧を参照してください。 --filetype csvと--no-schemasに適切な値を設定します。これらのパラメーターの使用方法について詳しくは、 Dumplingのオプション一覧を参照してください。
次のように CSV ファイルに名前を付けます。
- 1 つのテーブルのデータが複数の CSV ファイルに分割されている場合は、これらの CSV ファイルに数値のサフィックスを追加します。たとえば、
${db_name}.${table_name}.000001.csvと${db_name}.${table_name}.000002.csvです。数値サフィックスは連続していなくてもかまいませんが、昇順でなければなりません。また、数字の前にゼロを追加して、すべてのサフィックスが同じ長さになるようにする必要もあります。
ノート:
上記のルールに従って CSV ファイル名を更新できない場合 (たとえば、CSV ファイルのリンクが他のプログラムでも使用されている場合など) は、ファイル名を変更せずにステップ 5ファイル パターンを使用してソース データをインポートできます。単一のターゲット テーブルに。
データを Amazon S3 にエクスポートするには、次の手順を実行します。
Amazon S3 バケットの
AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYを取得します。[root@localhost ~]# export AWS_ACCESS_KEY_ID={your_aws_access_key_id} [root@localhost ~]# export AWS_SECRET_ACCESS_KEY= {your_aws_secret_access_key}MySQL instance1 から Amazon S3 バケットの
s3://dumpling-s3/store/sales/instance01/ディレクトリにデータをエクスポートします。[root@localhost ~]# tiup dumpling -u {username} -p {password} -P {port} -h {mysql01-ip} -B store_01,store_02 -r 20000 --filetype csv --no-schemas -o "s3://dumpling-s3/store/sales/instance01/" --s3.region "ap-northeast-1"パラメータの詳細については、 Dumplingのオプション一覧を参照してください。
MySQL instance2 から Amazon S3 バケットの
s3://dumpling-s3/store/sales/instance02/ディレクトリにデータをエクスポートします。[root@localhost ~]# tiup dumpling -u {username} -p {password} -P {port} -h {mysql02-ip} -B store_01,store_02 -r 20000 --filetype csv --no-schemas -o "s3://dumpling-s3/store/sales/instance02/" --s3.region "ap-northeast-1"
詳細な手順については、 データを Amazon S3 クラウド ストレージにエクスポートするを参照してください。
ステップ 3. TiDB Cloudクラスターでスキーマを作成する
次のように、 TiDB Cloudクラスターにスキーマを作成します。
mysql> CREATE DATABASE store;
Query OK, 0 rows affected (0.16 sec)
mysql> use store;
Database changed
この例では、上流のテーブルsale_01とsale_02の列 ID が自動インクリメントの主キーです。ダウンストリーム データベースでシャード テーブルをマージすると、競合が発生する場合があります。次の SQL ステートメントを実行して、ID 列を主キーではなく通常のインデックスとして設定します。
mysql> CREATE TABLE `sales` (
-> `id` bigint(20) NOT NULL ,
-> `uid` varchar(40) NOT NULL,
-> `sale_num` bigint DEFAULT NULL,
-> INDEX (`id`),
-> UNIQUE KEY `ind_uid` (`uid`)
-> );
Query OK, 0 rows affected (0.17 sec)
このような競合を解決するソリューションの詳細については、 列から PRIMARY KEY 属性を削除しますを参照してください。
ステップ 4.Amazon S3 アクセスを構成する
Amazon S3 アクセスの構成の手順に従って、ソースデータにアクセスするためのロール ARN を取得します。
次の例では、主要なポリシー構成のみを一覧表示しています。 Amazon S3 パスを独自の値に置き換えます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::dumpling-s3/*"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::dumpling-s3"
}
]
}
ステップ 5. データ インポート タスクを実行する
Amazon S3 アクセスを設定したら、次のようにTiDB Cloudコンソールでデータ インポート タスクを実行できます。
TiDB Cloudコンソールにログインしてクラスターページに移動し、左側のナビゲーション バーの上部でターゲット プロジェクトを選択します。
ターゲット クラスターを見つけて、クラスター領域の右上隅にある[...]をクリックし、 [データのインポート]を選択します。 [データのインポート]ページが表示されます。
[データのインポート]ページで、次の情報を入力します。
- データ形式: CSVを選択します。
- 場所:
AWS - バケット URI : ソース データのバケット URI を入力します。テーブルに対応する第 2 レベルのディレクトリ (この例では
s3://dumpling-s3/store/salesを使用して、 TiDB Cloud がすべての MySQL インスタンスのデータを一度にインポートしてstore.salesにマージできるようにします。 - Role ARN : 取得した Role-ARN を入力します。
- ターゲットクラスタ: クラスター名とリージョン名が表示されます。
バケットの場所がクラスターと異なる場合は、クロス リージョンのコンプライアンスを確認します。 [次へ]をクリックします。
TiDB Cloud は、指定されたバケット URI でデータにアクセスできるかどうかの検証を開始します。検証後、 TiDB Cloud はデフォルトのファイル命名パターンを使用してデータ ソース内のすべてのファイルをスキャンしようとし、次のページの左側にスキャンの概要結果を返します。
AccessDeniedエラーが発生した場合は、 S3 からのデータ インポート中のアクセス拒否エラーのトラブルシューティングを参照してください。ファイル パターンを変更し、必要に応じてテーブル フィルター ルールを追加します。
ファイル パターン: ファイル名が特定のパターンに一致する CSV ファイルを単一のターゲット テーブルにインポートする場合は、ファイル パターンを変更します。
ノート:
この機能を使用すると、1 つのインポート タスクで一度に 1 つのテーブルにのみデータをインポートできます。この機能を使用してデータを別のテーブルにインポートする場合は、インポートするたびに別のターゲット テーブルを指定して、複数回インポートする必要があります。
ファイル パターンを変更するには、 [変更]をクリックし、次のフィールドで CSV ファイルと単一のターゲット テーブルとの間のカスタム マッピング ルールを指定して、 [スキャン]をクリックします。
ソース ファイル名: インポートする CSV ファイルの名前と一致するパターンを入力します。 CSV ファイルが 1 つしかない場合は、ここにファイル名を直接入力します。 CSV ファイルの名前には、サフィックス「.csv」を含める必要があることに注意してください。
例えば:
my-data?.csv:my-dataと 1 文字 (my-data1.csvとmy-data2.csvなど) で始まるすべての CSV ファイルが同じターゲット テーブルにインポートされます。my-data*.csv:my-dataで始まるすべての CSV ファイルが同じターゲット テーブルにインポートされます。
ターゲット テーブル名: TiDB Cloudのターゲット テーブルの名前を入力します。これは
${db_name}.${table_name}形式である必要があります。たとえば、mydb.mytableです。このフィールドは特定のテーブル名を 1 つしか受け付けないため、ワイルドカードはサポートされていないことに注意してください。
テーブル フィルター: インポートするテーブルをフィルター処理する場合は、この領域でテーブル フィルタールールを 1 つ以上指定できます。
[次へ]をクリックします。
プレビューページでは、データのプレビューを表示できます。プレビューされたデータが期待どおりでない場合は、ここをクリックして csv 構成を編集するリンクをクリックして、区切り記号、区切り記号、ヘッダー、非 null、null、バックスラッシュ エスケープ、trim-last-separator などの CSV 固有の構成を更新します。 .
ノート:
区切り記号、区切り記号、およびヌルの構成では、英数字と特定の特殊文字の両方を使用できます。サポートされている特殊文字には、
\t、\b、\n、\r、\f、および\u0001が含まれます。[インポートの開始]をクリックします。
インポートの進行状況がFinishedと表示されたら、インポートされたテーブルを確認します。
データがインポートされた後、 TiDB Cloudの Amazon S3 アクセスを削除する場合は、追加したポリシーを削除するだけです。
MySQL からTiDB Cloudへの増分データ複製を実行する
Binlog に基づくデータ変更を上流クラスターの指定された位置からTiDB Cloudに複製するには、TiDB Data Migration (DM) を使用して増分複製を実行できます。
あなたが始める前に
TiDB Cloudコンソールは、増分データ複製に関する機能をまだ提供していません。増分データを移行するには、TiDB DM をデプロイする必要があります。詳細な手順については、 TiUP を使用して DMクラスタをデプロイを参照してください。
手順 1. データ ソースを追加する
新しいデータ ソース ファイル
dm-source1.yamlを作成して、アップストリーム データ ソースを DM に構成します。次のコンテンツを追加します。# MySQL Configuration. source-id: "mysql-replica-01" # Specifies whether DM-worker pulls binlogs with GTID (Global Transaction Identifier). # The prerequisite is that you have already enabled GTID in the upstream MySQL. # If you have configured the upstream database service to switch master between different nodes automatically, you must enable GTID. enable-gtid: true from: host: "${host}" # For example: 192.168.10.101 user: "user01" password: "${password}" # Plaintext passwords are supported but not recommended. It is recommended that you use dmctl encrypt to encrypt plaintext passwords. port: ${port} # For example: 3307別の新しいデータ ソース ファイル
dm-source2.yamlを作成し、次の内容を追加します。# MySQL Configuration. source-id: "mysql-replica-02" # Specifies whether DM-worker pulls binlogs with GTID (Global Transaction Identifier). # The prerequisite is that you have already enabled GTID in the upstream MySQL. # If you have configured the upstream database service to switch master between different nodes automatically, you must enable GTID. enable-gtid: true from: host: "192.168.10.102" user: "user02" password: "${password}" port: 3308ターミナルで次のコマンドを実行します。
tiup dmctlを使用して、最初のデータ ソース構成を DM クラスターに読み込みます。[root@localhost ~]# tiup dmctl --master-addr ${advertise-addr} operate-source create dm-source1.yaml上記のコマンドで使用されるパラメーターは、次のとおりです。
次に出力例を示します。
tiup is checking updates for component dmctl ... Starting component `dmctl`: /root/.tiup/components/dmctl/v6.0.0/dmctl/dmctl /root/.tiup/components/dmctl/v6.0.0/dmctl/dmctl --master-addr 192.168.11.110:9261 operate-source create dm-source1.yaml { "result": true, "msg": "", "sources": [ { "result": true, "msg": "", "source": "mysql-replica-01", "worker": "dm-192.168.11.111-9262" } ] }ターミナルで次のコマンドを実行します。
tiup dmctlを使用して、2 番目のデータ ソース構成を DM クラスターに読み込みます。[root@localhost ~]# tiup dmctl --master-addr 192.168.11.110:9261 operate-source create dm-source2.yaml次に出力例を示します。
tiup is checking updates for component dmctl ... Starting component `dmctl`: /root/.tiup/components/dmctl/v6.0.0/dmctl/dmctl /root/.tiup/components/dmctl/v6.0.0/dmctl/dmctl --master-addr 192.168.11.110:9261 operate-source create dm-source2.yaml { "result": true, "msg": "", "sources": [ { "result": true, "msg": "", "source": "mysql-replica-02", "worker": "dm-192.168.11.112-9262" } ] }
手順 2. レプリケーション タスクを作成する
レプリケーション タスク用に
test-task1.yamlファイルを作成します。Dumplingによってエクスポートされた MySQL instance1 のメタデータ ファイルで開始点を見つけます。例えば:
Started dump at: 2022-05-25 10:16:26 SHOW MASTER STATUS: Log: mysql-bin.000002 Pos: 246546174 GTID:b631bcad-bb10-11ec-9eee-fec83cf2b903:1-194801 Finished dump at: 2022-05-25 10:16:27Dumplingによってエクスポートされた MySQL instance2 のメタデータ ファイルで開始点を見つけます。例えば:
Started dump at: 2022-05-25 10:20:32 SHOW MASTER STATUS: Log: mysql-bin.000001 Pos: 1312659 GTID:cd21245e-bb10-11ec-ae16-fec83cf2b903:1-4036 Finished dump at: 2022-05-25 10:20:32タスク構成ファイル
test-task1を編集して、各データ ソースの増分レプリケーション モードとレプリケーションの開始点を構成します。## ********* Task Configuration ********* name: test-task1 shard-mode: "pessimistic" # Task mode. The "incremental" mode only performs incremental data migration. task-mode: incremental # timezone: "UTC" ## ******** Data Source Configuration ********** ## (Optional) If you need to incrementally replicate data that has already been migrated in the full data migration, you need to enable the safe mode to avoid the incremental data migration error. ## This scenario is common in the following case: the full migration data does not belong to the data source's consistency snapshot, and after that, DM starts to replicate incremental data from a position earlier than the full migration. syncers: # The running configurations of the sync processing unit. global: # Configuration name. safe-mode: false # # If this field is set to true, DM changes INSERT of the data source to REPLACE for the target database, # # and changes UPDATE of the data source to DELETE and REPLACE for the target database. # # This is to ensure that when the table schema contains a primary key or unique index, DML statements can be imported repeatedly. # # In the first minute of starting or resuming an incremental migration task, DM automatically enables the safe mode. mysql-instances: - source-id: "mysql-replica-01" block-allow-list: "bw-rule-1" route-rules: ["store-route-rule", "sale-route-rule"] filter-rules: ["store-filter-rule", "sale-filter-rule"] syncer-config-name: "global" meta: binlog-name: "mysql-bin.000002" binlog-pos: 246546174 binlog-gtid: "b631bcad-bb10-11ec-9eee-fec83cf2b903:1-194801" - source-id: "mysql-replica-02" block-allow-list: "bw-rule-1" route-rules: ["store-route-rule", "sale-route-rule"] filter-rules: ["store-filter-rule", "sale-filter-rule"] syncer-config-name: "global" meta: binlog-name: "mysql-bin.000001" binlog-pos: 1312659 binlog-gtid: "cd21245e-bb10-11ec-ae16-fec83cf2b903:1-4036" ## ******** Configuration of the target TiDB cluster on TiDB Cloud ********** target-database: # The target TiDB cluster on TiDB Cloud host: "tidb.xxxxxxx.xxxxxxxxx.ap-northeast-1.prod.aws.tidbcloud.com" port: 4000 user: "root" password: "${password}" # If the password is not empty, it is recommended to use a dmctl-encrypted cipher. ## ******** Function Configuration ********** routes: store-route-rule: schema-pattern: "store_*" target-schema: "store" sale-route-rule: schema-pattern: "store_*" table-pattern: "sale_*" target-schema: "store" target-table: "sales" filters: sale-filter-rule: schema-pattern: "store_*" table-pattern: "sale_*" events: ["truncate table", "drop table", "delete"] action: Ignore store-filter-rule: schema-pattern: "store_*" events: ["drop database"] action: Ignore block-allow-list: bw-rule-1: do-dbs: ["store_*"] ## ******** Ignore check items ********** ignore-checking-items: ["table_schema","auto_increment_ID"]
詳細なタスク構成については、 DM タスク構成を参照してください。
データ複製タスクをスムーズに実行するために、DM はタスクの開始時に事前チェックを自動的にトリガーし、チェック結果を返します。 DM は、事前チェックに合格した後にのみレプリケーションを開始します。事前チェックを手動でトリガーするには、check-task コマンドを実行します。
[root@localhost ~]# tiup dmctl --master-addr 192.168.11.110:9261 check-task dm-task.yaml
次に出力例を示します。
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /root/.tiup/components/dmctl/v6.0.0/dmctl/dmctl /root/.tiup/components/dmctl/v6.0.0/dmctl/dmctl --master-addr 192.168.11.110:9261 check-task dm-task.yaml
{
"result": true,
"msg": "check pass!!!"
}
ステップ 3. 複製タスクを開始する
tiup dmctlを使用して次のコマンドを実行し、データ複製タスクを開始します。
[root@localhost ~]# tiup dmctl --master-addr ${advertise-addr} start-task dm-task.yaml
上記のコマンドで使用されるパラメーターは、次のとおりです。
次に出力例を示します。
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /root/.tiup/components/dmctl/v6.0.0/dmctl/dmctl /root/.tiup/components/dmctl/v6.0.0/dmctl/dmctl --master-addr 192.168.11.110:9261 start-task dm-task.yaml
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"source": "mysql-replica-01",
"worker": "dm-192.168.11.111-9262"
},
{
"result": true,
"msg": "",
"source": "mysql-replica-02",
"worker": "dm-192.168.11.112-9262"
}
],
"checkResult": ""
}
タスクの開始に失敗した場合は、プロンプト メッセージを確認し、構成を修正します。その後、上記のコマンドを再実行してタスクを開始できます。
問題が発生した場合は、 DM エラー処理およびDMFAQを参照してください。
手順 4. レプリケーション タスクのステータスを確認する
DM クラスターに進行中のレプリケーション タスクがあるかどうかを確認し、タスクの状態を表示するには、 tiup dmctl使用してquery-statusコマンドを実行します。
[root@localhost ~]# tiup dmctl --master-addr 192.168.11.110:9261 query-status test-task1
次に出力例を示します。
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-replica-01",
"worker": "dm-192.168.11.111-9262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "test-task1",
"stage": "Running",
"unit": "Sync",
"result": null,
"unresolvedDDLLockID": "",
"sync": {
"totalEvents": "4048",
"totalTps": "3",
"recentTps": "3",
"masterBinlog": "(mysql-bin.000002, 246550002)",
"masterBinlogGtid": "b631bcad-bb10-11ec-9eee-fec83cf2b903:1-194813",
"syncerBinlog": "(mysql-bin.000002, 246550002)",
"syncerBinlogGtid": "b631bcad-bb10-11ec-9eee-fec83cf2b903:1-194813",
"blockingDDLs": [
],
"unresolvedGroups": [
],
"synced": true,
"binlogType": "remote",
"secondsBehindMaster": "0",
"blockDDLOwner": "",
"conflictMsg": ""
}
}
]
},
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-replica-02",
"worker": "dm-192.168.11.112-9262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "test-task1",
"stage": "Running",
"unit": "Sync",
"result": null,
"unresolvedDDLLockID": "",
"sync": {
"totalEvents": "33",
"totalTps": "0",
"recentTps": "0",
"masterBinlog": "(mysql-bin.000001, 1316487)",
"masterBinlogGtid": "cd21245e-bb10-11ec-ae16-fec83cf2b903:1-4048",
"syncerBinlog": "(mysql-bin.000001, 1316487)",
"syncerBinlogGtid": "cd21245e-bb10-11ec-ae16-fec83cf2b903:1-4048",
"blockingDDLs": [
],
"unresolvedGroups": [
],
"synced": true,
"binlogType": "remote",
"secondsBehindMaster": "0",
"blockDDLOwner": "",
"conflictMsg": ""
}
}
]
}
]
}
結果の詳細な解釈については、 クエリのステータスを参照してください。