大規模データセットの 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クラスタをデプロイ参照してください。
外部storage
このドキュメントでは、Amazon S3 を例として使用します。
下流クラスター
シャードされたスキーマとテーブルはテーブルstore.sales
にマージされます。
MySQLからTiDB Cloudへの完全なデータ移行を実行する
以下は、MySQL シャードの全データをTiDB Cloudに移行してマージする手順です。
次の例では、テーブル内のデータをCSV形式でエクスポートするだけです。
ステップ1. Amazon S3バケットにディレクトリを作成する
Amazon S3 バケットに、第 1 レベルのディレクトリstore
(データベースのレベルに対応) と第 2 レベルのディレクトリsales
(テーブルのレベルに対応) を作成します。5 sales
、各 MySQL インスタンスの第 3 レベルのディレクトリを作成します (MySQL インスタンスのレベルに対応)。例:
- MySQLインスタンス1のデータを
s3://dumpling-s3/store/sales/instance01/
に移行する - MySQLインスタンス2のデータを
s3://dumpling-s3/store/sales/instance02/
に移行する
複数のインスタンスにまたがるシャードがある場合は、データベースごとに 1 つの第 1 レベルのディレクトリを作成し、シャードされたテーブルごとに 1 つの第 2 レベルのディレクトリを作成できます。次に、管理を容易にするために、各 MySQL インスタンスに第 3 レベルのディレクトリを作成します。たとえば、MySQL インスタンス 1 と MySQL インスタンス 2 のテーブルstock_N.product_N
を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 インスタンス 1 から 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 インスタンス 2 から 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クラウドstorageにデータをエクスポートする参照してください。
ステップ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コンソールにログインし、プロジェクトのクラスターページに移動します。
ヒント:
複数のプロジェクトがある場合は、
左下隅にある をクリックして、別のプロジェクトに切り替えます。 ターゲット クラスターの名前をクリックして概要ページに移動し、左側のナビゲーション ペインで[インポート] をクリックします。
S3 からデータをインポートを選択します。
このクラスターにデータを初めてインポートする場合は、 「Amazon S3 からのインポート」を選択します。
「Amazon S3 からのデータのインポート」ページで、次の情報を入力します。
- インポートファイル数:複数のファイルを選択します。
- 含まれるスキーマ ファイル: [いいえ]を選択します。
- データ形式: CSVを選択します。
- フォルダー URI : ソース データのバケット URI を入力します。テーブルに対応する第 2 レベルのディレクトリ (この例では
s3://dumpling-s3/store/sales/
) を使用すると、 TiDB Cloud はすべての MySQL インスタンスのデータを一度にstore.sales
にインポートしてマージできます。 - バケットアクセス> AWS ロール ARN : 取得したロール ARN を入力します。
バケットの場所がクラスターと異なる場合は、クロスリージョンのコンプライアンスを確認してください。
TiDB Cloud は、指定されたバケット URI のデータにアクセスできるかどうかの検証を開始します。検証後、 TiDB Cloud は、デフォルトのファイル名パターンを使用してデータ ソース内のすべてのファイルをスキャンし、次のページの左側にスキャンの概要結果を返します。1 エラー
AccessDenied
発生した場合は、 S3 からのデータインポート中に発生するアクセス拒否エラーのトラブルシューティングを参照してください。[接続]をクリックします。
[宛先]セクションで、ターゲット データベースとテーブルを選択します。
複数のファイルをインポートする場合は、 [詳細設定] > [マッピング設定]を使用して、各ターゲット テーブルとそれに対応する CSV ファイルのカスタム マッピング ルールを定義できます。その後、提供されたカスタム マッピング ルールを使用してデータ ソース ファイルが再スキャンされます。
ソース ファイルの URI と名前を[ソース ファイルの URI と名前]に入力するときは、次の形式
s3://[bucket_name]/[data_source_folder]/[file_name].csv
になっていることを確認してください。たとえば、s3://sampledata/ingest/TableName.01.csv
。ソース ファイルを一致させるためにワイルドカードを使用することもできます。例:
s3://[bucket_name]/[data_source_folder]/my-data?.csv
: そのフォルダー内のmy-data
で始まり、その後に 1 文字 (my-data1.csv
やmy-data2.csv
など) が続くすべての CSV ファイルが同じターゲット テーブルにインポートされます。s3://[bucket_name]/[data_source_folder]/my-data*.csv
: フォルダー内のmy-data
で始まるすべての CSV ファイルが同じターゲット テーブルにインポートされます。
サポートされているのは
?
と*
のみであることに注意してください。注記:
URI にはデータ ソース フォルダーが含まれている必要があります。
必要に応じて CSV 構成を編集します。
また、 「CSV 構成の編集」をクリックして、バックスラッシュ エスケープ、セパレーター、区切り文字を構成し、よりきめ細かい制御を行うこともできます。
注記:
セパレーター、区切り文字、および null の設定では、英数字と特定の特殊文字の両方を使用できます。サポートされている特殊文字には、
\t
、\b
、\n
、\r
、\f
、および\u0001
があります。[インポートの開始]をクリックします。
インポートの進行状況が「完了」と表示されたら、インポートされたテーブルを確認します。
データがインポートされた後、 TiDB Cloudの Amazon S3 アクセスを削除する場合は、追加したポリシーを削除するだけです。
MySQLからTiDB Cloudへの増分データレプリケーションを実行する
アップストリーム クラスターの指定された位置からbinlogに基づいてデータの変更をTiDB Cloudに複製するには、TiDB Data Migration (DM) を使用して増分レプリケーションを実行します。
始める前に
増分データを移行し、MySQL シャードをTiDB Cloudにマージする場合、 TiDB Cloud はまだ MySQL シャードの移行とマージをサポートしていないため、TiDB DM を手動でデプロイする必要があります。詳細な手順については、 TiUPを使用して DMクラスタをデプロイ参照してください。
ステップ1. データソースを追加する
DM にアップストリーム データ ソースを構成するために、新しいデータ ソース ファイル
dm-source1.yaml
を作成します。次のコンテンツを追加します。# 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ターミナルで次のコマンドを実行します。1
tiup dmctl
使用して、最初のデータ ソース構成を DM クラスターにロードします。[root@localhost ~]# tiup dmctl --master-addr ${advertise-addr} operate-source create dm-source1.yaml上記のコマンドで使用されるパラメータは次のように記述されます。
パラメータ 説明 --master-addr
dmctl
が接続されるクラスター内の任意の DM マスター ノードの{advertise-addr}
例: 192.168.11.110:9261operate-source create
データ ソースを DM クラスターにロードします。 出力例は次のとおりです。
tiup is checking updates for component dmctl ... Starting component `dmctl`: /root/.tiup/components/dmctl/${tidb_version}/dmctl/dmctl /root/.tiup/components/dmctl/${tidb_version}/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" } ] }ターミナルで次のコマンドを実行します。1
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/${tidb_version}/dmctl/dmctl /root/.tiup/components/dmctl/${tidb_version}/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/${tidb_version}/dmctl/dmctl /root/.tiup/components/dmctl/${tidb_version}/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
上記のコマンドで使用されるパラメータは次のように記述されます。
パラメータ | 説明 |
---|---|
--master-addr | dmctl が接続されるクラスター内の任意の DM マスター ノードの{advertise-addr} 例: 192.168.11.110:9261 |
start-task | 移行タスクを開始します。 |
出力例は次のとおりです。
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /root/.tiup/components/dmctl/${tidb_version}/dmctl/dmctl /root/.tiup/components/dmctl/${tidb_version}/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": ""
}
}
]
}
]
}
結果の詳細な解釈についてはクエリステータス参照してください。