giip
SES Proposal
TiDB専門家レビュー必須移行バージョン互換性インデックストランザクションサイジング

Checklist for Migrating from TiDB to Aurora MySQL

公開日 2026-08-13 · 更新日 2026-08-13 · 最終検証日 2026-08-13

結論

When migrating from TiDB to Aurora MySQL, do not assume "it's MySQL-compatible, so it will just work." Instead, verify seven things in your actual environment: ID generation (`AUTO_INCREMENT`'s non-sequential allocation and `AUTO_RANDOM`), primary key structure (clustered vs. non-clustered, `SHARD_ROW_ID_BITS`), TiDB-specific syntax and system variables, transaction behavior, statistics and index selection, character set and collation, and capacity (TiKV and InnoDB require different amounts). Since behavior changes across TiDB versions, this assumes you verify against your own environment's version rather than this article.

この文書の適用条件

対象製品TiDB (source) → Aurora MySQL (target)
確認バージョンTiDB behavior varies significantly by version, so always run `SELECT TIDB_VERSION();` to check your environment's version before verifying each item. Assumes the target is Aurora MySQL 3.x (MySQL 8.0-compatible)
適用環境TiDB (self-hosted / managed) → Amazon Aurora (AWS)
必要権限Investigation requires read access to `information_schema` and `SELECT` on the target schema. Running the migration requires read access on the dump source and write access on the target
実行影響No impact from the investigation SQL. The initial load and CDC setup put load on both the source and target
再起動Not required for investigation. Cutover downtime depends on the method chosen
最終検証日2026-08-13

そのまま実行できるコマンド

Check the source TiDB's version and key settings参照のみ
対象
TiDB (all versions)
権限
Connection privilege
変更作業
None (read-only)
Production実行
Possible
-- 対象: TiDB(バージョンにより出力が異なる)
-- 権限: 接続権限
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能

-- 1) TiDB のバージョン(VERSION() はMySQL互換の文字列、TIDB_VERSION() はTiDB固有の詳細)
SELECT VERSION() AS mysql_compat_version;
SELECT TIDB_VERSION() AS tidb_version;

-- 2) トランザクションモードと分離レベル
SHOW GLOBAL VARIABLES WHERE Variable_name IN (
    'tidb_txn_mode',
    'transaction_isolation',
    'tidb_constraint_check_in_place',
    'tidb_enable_clustered_index'
);

-- 3) 新しい照合順序フレームワークが有効かどうか
--    (無効な環境では utf8mb4_general_ci の比較挙動がMySQLと異なる)
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM mysql.tidb
WHERE VARIABLE_NAME = 'new_collation_enabled';

The version obtained here is the premise for every decision that follows. Since TiDB's defaults and supported features change across versions, prefer your own environment's output whenever it conflicts with this article. `mysql.tidb` or `tidb_enable_clustered_index` may not exist in some versions (if you get an error, you can conclude that version simply lacks the feature).

Find TiDB-specific attributes from table definitions参照のみ
対象
TiDB (all versions)
権限
Metadata read privilege on the target schema
変更作業
None (read-only)
Production実行
Possible
-- 対象: TiDB(全バージョン)
-- 権限: 対象スキーマのメタデータ参照権限
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能

-- 1) 定義そのものを出力し、AUTO_RANDOM / SHARD_ROW_ID_BITS /
--    CLUSTERED・NONCLUSTERED / PRE_SPLIT_REGIONS の有無を目視で確認する
SHOW CREATE TABLE SampleDB.sample_table;

-- 2) 主キーの構造を一覧で確認する(TIDB_PK_TYPE はTiDB独自列。
--    存在しない版ではエラーになるので、その場合は 1) を全テーブル分実行する)
SELECT TABLE_SCHEMA, TABLE_NAME, TIDB_PK_TYPE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'metrics_schema', 'sys')
ORDER BY TABLE_SCHEMA, TABLE_NAME;

-- 3) 主キーの無いテーブル(移行後のCDCで問題になる)
SELECT t.TABLE_SCHEMA, t.TABLE_NAME
FROM information_schema.TABLES t
LEFT JOIN information_schema.KEY_COLUMN_USAGE k
       ON  k.TABLE_SCHEMA    = t.TABLE_SCHEMA
       AND k.TABLE_NAME      = t.TABLE_NAME
       AND k.CONSTRAINT_NAME = 'PRIMARY'
WHERE t.TABLE_TYPE = 'BASE TABLE'
  AND t.TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'metrics_schema', 'sys')
  AND k.COLUMN_NAME IS NULL
ORDER BY t.TABLE_SCHEMA, t.TABLE_NAME;

`AUTO_RANDOM` is specific to TiDB and has no MySQL equivalent. A column using it needs to be replaced with a different design on the Aurora MySQL side (a sequential `BIGINT`, application-side ID generation, a UUID scheme, etc.) — consider both value compatibility and digit count. `SHARD_ROW_ID_BITS` and `PRE_SPLIT_REGIONS` are settings for TiKV's distributed placement and have no equivalent concept on Aurora (this doesn't mean you can simply ignore them — consider what happens after migration to the access pattern that needed that setting).

Check usage of foreign keys, generated columns, and partitions参照のみ
対象
TiDB (all versions)
権限
Metadata read privilege on the target schema
変更作業
None (read-only)
Production実行
Possible
-- 対象: TiDB(全バージョン)
-- 権限: 対象スキーマのメタデータ参照権限
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能

-- 1) 外部キー定義の有無(定義があっても実際に強制されているかは版に依存する)
SELECT CONSTRAINT_SCHEMA, TABLE_NAME, CONSTRAINT_NAME,
       REFERENCED_TABLE_NAME, UPDATE_RULE, DELETE_RULE
FROM information_schema.REFERENTIAL_CONSTRAINTS
ORDER BY CONSTRAINT_SCHEMA, TABLE_NAME;

-- 2) 生成列(GENERATED COLUMN)
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, EXTRA, GENERATION_EXPRESSION
FROM information_schema.COLUMNS
WHERE GENERATION_EXPRESSION IS NOT NULL
  AND GENERATION_EXPRESSION <> ''
ORDER BY TABLE_SCHEMA, TABLE_NAME;

-- 3) パーティション定義
SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, PARTITION_METHOD, PARTITION_EXPRESSION
FROM information_schema.PARTITIONS
WHERE PARTITION_NAME IS NOT NULL
ORDER BY TABLE_SCHEMA, TABLE_NAME, PARTITION_ORDINAL_POSITION;

TiDB has, for a long time, accepted foreign key syntax without actually enforcing the constraint. Since whether it's enforced depends on the version, check the real behavior in your environment by trying a violating INSERT rather than just checking whether a definition exists. If it was not enforced before, data inserts that previously succeeded may start failing once foreign keys are enforced on the Aurora MySQL side.

Measure the data volume to migrate (don't use it as-is to size the target)参照のみ
対象
TiDB (all versions)
権限
Read access to `information_schema`
変更作業
None (read-only)
Production実行
Possible
-- 対象: TiDB(全バージョン)
-- 権限: information_schema の参照権限
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能
SELECT
    TABLE_SCHEMA,
    TABLE_NAME,
    TABLE_ROWS                                            AS estimated_rows,
    ROUND(DATA_LENGTH  / 1024 / 1024 / 1024, 2)           AS data_gb,
    ROUND(INDEX_LENGTH / 1024 / 1024 / 1024, 2)           AS index_gb,
    TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
  AND TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'metrics_schema', 'sys')
ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC;

TiDB's `TABLE_ROWS` and `DATA_LENGTH` are estimates based on statistics. Since TiKV keeps multiple replicas and also compresses data, you cannot use this value as-is for Aurora's (InnoDB's) required storage. Estimate the target capacity from the actual ratio measured by loading representative tables.

Produce a dump for the initial load
対象
TiDB (Dumpling)
権限
`SELECT` on the dump target schema (TiDB side)
変更作業
None (source is read-only), but it adds read load
Production実行
Carry out during a window that can tolerate the load
# 対象: TiDB(Dumpling によるダンプ)
# 権限: ダンプ対象スキーマへの SELECT(TiDB側)
# 変更作業: なし(移行元は参照のみ)。ただし読み取り負荷がかかる
# Production 実行: 負荷を許容できる時間帯で実施すること

# まず1テーブルだけダンプして所要時間と出力サイズを実測する
tiup dumpling \
  --host 192.0.2.10 \
  --port 4000 \
  --user sample_user \
  --filetype sql \
  --threads 8 \
  --rows 200000 \
  --filter 'SampleDB.sample_table' \
  --output /var/tmp/dump-sample

# 出力サイズと所要時間を確認する(この実測値だけが計画の根拠になる)
du -sh /var/tmp/dump-sample

Measure with a few tables first, then extrapolate to the whole. Specifying `--rows` splits a table for parallel output. Raising `--threads` increases load on the source, so start low while in production. Option names can change between Dumpling versions, so check with `tiup dumpling --help`.

Plan the change-data-capture (CDC) setup
対象
TiCDC (TiDB side) or AWS DMS
権限
Operational privileges on TiCDC, or DMS IAM privileges and endpoint credentials
変更作業
Yes (configures change data delivery; affects both source and target)
Production実行
A configuration change on the production source. Pre-verification and a rollback procedure are mandatory
# 対象: TiCDC(TiDB側)または AWS DMS
# 権限: TiCDC の操作権限、または DMS の IAM 権限とエンドポイント資格情報
# 変更作業: あり(変更データ配信の構成)
# Production 実行: 本番ソースへの設定変更。事前検証と切り戻し手順を用意してから実施

# TiCDC で MySQL 互換のシンク(= Aurora MySQL)へ変更を流す例。
# CLI のオプション名はTiDB/TiCDCのバージョンで変わる(--pd と --server など)ため、
# 必ず自環境のバージョンのドキュメントで確認すること。
tiup ctl cdc changefeed create \
  --server "http://192.0.2.10:8300" \
  --changefeed-id "example-changefeed" \
  --sink-uri "mysql://sample_user@example-rds-endpoint:3306/"

# 作成後は状態と遅延を確認する
tiup ctl cdc changefeed list --server "http://192.0.2.10:8300"

The TiCDC CLI's option names have changed across versions (e.g., `--pd` to `--server`). Don't use the exact form shown here — match it to your own environment's version documentation. If using AWS DMS against a source TiDB, check with the actual DMS version you'll use whether TiDB is supported as a source and which mode (full-load only / including CDC) is available (this article does not state this definitively). Don't write the password directly on the command line — use an environment variable or a config file.

結果の読み方

意味確認するポイント
tidb_versionTiDB's actual versionThe premise for every compatibility decision. Prefer your own environment's version over this article
tidb_txn_modeTransaction mode (optimistic / pessimistic)If optimistic, the app may be written assuming a conflict error is returned at commit time
new_collation_enabledWhether the new collation framework is enabledIf disabled, comparison behavior for utf8mb4-family collations differs from MySQL. Duplicate detection may change after migration
TIDB_PK_TYPEWhether the primary key is clusteredPerformance characteristics assumed under clustering are not guaranteed to be reproduced on Aurora
estimated_rowsEstimated row count based on statisticsNot an exact count. Cross-check against a verification `COUNT(*)`
data_gb / index_gbData and index size as reported by TiDBIncludes TiKV replication and compression, so it can't be used as-is for Aurora's required capacity
REFERENCED_TABLE_NAMEWhat a foreign key referencesCheck whether it is actually enforced by testing, not just whether a definition exists
GENERATION_EXPRESSIONExpression for a generated columnCheck individually whether function support matches on the target

こういう状況で使います

  • SQL that worked on TiDB produces an error in the Aurora MySQL test environment
  • Continuity of ID generation changes after migration, conflicting with application assumptions
  • The same index exists, but only after migration does the execution plan change and slow down
  • Data that violates a foreign key already exists and cannot be loaded into the target
  • The target's storage estimate diverges significantly from the source's reported value
  • String comparison or sorting results changed before and after migration

考えられる原因(可能性の高い順)

  1. 01

    `AUTO_INCREMENT` allocation works differently

    Because TiDB allocates ID ranges in bulk to each node, IDs can be non-sequential. An application that assumes "higher ID = later insertion order" needs re-review regardless of which side it runs on. Since the exact behavior depends on version and configuration, measure sequentiality in your own environment.

  2. 02

    MySQL has no equivalent of `AUTO_RANDOM`

    This is a TiDB-specific feature for avoiding hotspots. When migrating to Aurora MySQL, the value-generation scheme itself needs to be redesigned. Also check whether existing ID values can be carried over as-is.

  3. 03

    The clustered-primary-key assumption differs

    InnoDB is clustered by the primary key by default, while TiDB lets you choose clustered or non-clustered. A non-clustered table's per-access-pattern performance characteristics change after migration.

  4. 04

    Transaction behavior differs

    Optimistic transactions detect conflicts at commit time, while pessimistic transactions take locks at execution time. Which one was in use changes how lock waits and errors manifest after migration.

  5. 05

    TiDB-specific syntax, system variables, or hints are in use

    System variables starting with `TIDB_`, TiDB-specific optimizer hints, and `ADMIN`-family administrative commands don't work on MySQL. Full-text search the application and batch SQL to find them.

  6. 06

    The statistics and index selection mechanism differs

    Since the optimizer is a different implementation, the execution plan chosen can differ even with the same index configuration. Treat "the same SQL is now slow" after migration as expected, and plan to re-verify execution plans for representative queries on the target.

  7. 07

    The storage structure differs

    TiKV keeps replicas and also compresses data. Since the assumptions differ from InnoDB, you cannot mechanically convert the source's usage into the target's required capacity.

確認手順

  1. 1

    Retrieve TiDB's version and key settings

    参照のみ

    Check `TIDB_VERSION()`, `tidb_txn_mode`, and the state of the collation framework. Every subsequent decision is premised on this result.

  2. 2

    Save `SHOW CREATE TABLE` for every table

    参照のみ

    Some TiDB-specific attributes appear only in the definition statement. Save all of them and search for `AUTO_RANDOM` / `SHARD_ROW_ID_BITS` / `NONCLUSTERED`.

  3. 3

    Full-text search the application SQL for TiDB-specific elements

    参照のみ

    Search for `TIDB_`, custom hints, and `ADMIN` commands. These aren't visible from the DB side, so they need to be found in the code.

  4. 4

    Test in a verification environment whether foreign keys are actually enforced

    Run a violating INSERT and check whether it errors. This cannot be determined from the definition alone.

  5. 5

    Test-load a representative table on the target and measure the capacity ratio

    This measured value alone is the basis for estimating the target's storage.

  6. 6

    Run representative queries on the target and compare execution plans and timing

    There is no guarantee of the same performance as the source. Include time in the plan to handle queries that show a difference individually.

対応方法

すぐに実施できる低リスクの対応

  • Pin down the version and list the differences

    参照のみ

    Judge based on "this specific version of TiDB," not "TiDB" in general. The list of differences becomes the backbone of the migration plan.

  • Separate what will and will not be migrated

    参照のみ

    If temporary tables or large analytical tables can be excluded from migration, the burden of the initial load drops significantly.

事前検討が必要な変更

  • Replace the design of `AUTO_RANDOM` columns

    Decide on the target-side ID-generation scheme (sequential, application-generated, UUID-based) and check whether existing values can be carried over and whether the digit count fits application assumptions. Involves application-side changes.

  • Provision keys for tables with no primary key

    When synchronizing differences via CDC, a table with no primary key causes apply errors. Define a key before migration.

  • Re-verify execution plans for representative queries on the target

    Reserve a verification period in the plan on the assumption that indexes will need to be added or changed on the target.

  • Standardize the character set and collation to the target's baseline

    Collation differences change comparison results. See the related article for utf8mb4 migration checks.

再起動・サービス影響を伴う変更

  • Carry out the initial load

    Dump with Dumpling or similar and load it into the target. Always estimate the duration from a sample measurement.

  • Set up change data capture (TiCDC / DMS)

    This is a configuration addition on the production source. Decide how lag will be monitored and the rollback procedure before carrying this out.

専門家のレビューが必要な作業

  • Carry out the cutover

    専門家レビュー必須

    Decide the order and ownership of stopping writes, confirming the difference has caught up, verifying consistency, switching the connection target, and the rollback decision, before carrying it out. This is an area driven by pre-agreed procedure and human judgment, not automation.

!注意事項

  • TiDB's behavior varies by version. Whenever this article's description conflicts with your own environment's output, always prefer your environment's output.
  • "MySQL-compatible" does not mean "identical." Syntax being accepted is a different matter from producing the same result and the same performance.
  • Do not convert the source's `DATA_LENGTH` directly into Aurora's required storage. TiKV's value assumes replicas and compression.
  • A foreign key may not be enforced even if it is defined. If it becomes enforced on the target, existing data loading or existing processing can start failing.
  • This article does not give a duration for the migration. Since it depends on table composition, data volume, network, and parallelism, always estimate it from a sample measurement.
  • Cutover is a hard-to-reverse operation. Define the point of no return beforehand and decide who makes the call before carrying it out.

バージョン・環境による違い

Differences across TiDB versionsThe default for clustered primary keys, the collation framework, foreign key enforcement, and TiCDC CLI options all vary by version. Avoid definitive statements and refer to the official documentation matching the result of `SELECT TIDB_VERSION();`.
When the target is Aurora MySQL 3.x (MySQL 8.0-compatible)Since the default collation becomes a `utf8mb4_0900_ai_ci`-family collation, comparison behavior can differ from the source's collation. Verify that duplicate detection does not change on columns with a unique constraint.
When the target is Aurora MySQL 2.x (MySQL 5.7-compatible)If syntax added in MySQL 8.0 (window functions, CTEs, etc.) was used on the TiDB side, it will not work on the target. A full SQL inventory is needed.

これで解決しない場合に確認すること

  • Check the application's driver and timeout settings

    Changing the connection target can change reconnection and timeout behavior.

  • Decide where analytical workloads go

    If analytical queries were co-located on TiDB, Aurora alone may not provide the same performance characteristics. Consider a read replica or a separate platform.

  • Re-measure batch processing parallelism and duration

    Since the storage structure changes, the same degree of parallelism is not guaranteed to be optimal.

  • Rebuild operational procedures (backup, monitoring, privilege management) for the target

    TiDB-specific procedures cannot be used as-is. Include creating operational procedures in the migration plan.

  • Check the conditions and procedure for rolling back

    Document, before the cutover, how far back you can roll back and what gets discarded if you do.

この文書の根拠と限界

一般的な技術説明

Based on the publicly documented differences between TiDB and MySQL (Aurora MySQL) and general verification practices for cross-engine database migration. Since TiDB's behavior varies significantly by version, this article shows what to check rather than asserting any specific behavior. It does not include any specific customer's migration case or actual duration figures.

よくある質問

TiDB is MySQL-compatible, so can it be migrated as-is?

Not necessarily. What's compatible is the connection protocol and most SQL syntax; ID generation behavior, primary key structure, transaction behavior, statistics and index selection, and storage assumptions all differ. Treat syntax being accepted as separate from getting the same result and the same performance, and verify each item individually.

What should be done about columns using AUTO_RANDOM?

Since MySQL has no equivalent feature, the ID-generation scheme itself needs to be redesigned. Decide whether to use sequential IDs, application-side generation, or a UUID scheme, and check whether existing ID values can be carried over as-is and whether the digit count fits application assumptions.

How much storage is needed on the target?

It cannot be determined from the source's reported value. Since TiKV keeps replicas and also compresses data, its assumptions differ from InnoDB's. Actually load representative tables into the target and estimate the total from that ratio.

Can this be run in production?

All the investigation SQL is read-only and can be run on a production TiDB. A Dumpling dump adds read load and needs a scheduled window; configuring TiCDC or DMS is a configuration change on the production source. Carry out the cutover following a pre-agreed procedure.

What happens to foreign keys?

On TiDB, a foreign key may be defined but not actually enforced. Since whether it's enforced depends on the version, insert violating data to check the actual behavior. If it was not enforced, existing processing may start failing once foreign keys become active on the target.

How should the results be interpreted?

Classify each checklist item into one of three categories: "no difference," "needs an application change," or "needs a design change." If there is even one item requiring a design change, the migration becomes a project that includes application modification, not just a data move. Build the schedule on that premise.

この文書がカバーする質問

  • How to check index differences between MySQL-compatible databases
  • Want to know why AUTO_INCREMENT is not sequential in TiDB
  • Data volume estimation when migrating from TiDB to RDS
  • Does a TiDB foreign key behave the same as in MySQL

リスク表示の意味

  • 参照のみデータと設定を変更しません。
  • 影響は限定的ですが、権限と負荷の確認が必要です。
  • 性能・ロック・コストに影響する可能性があります。
  • 障害・データ損失・復旧作業が発生する可能性があります。
  • 専門家レビュー必須本番適用前に別途レビューが必須です。

GIIPの対応範囲

The migration decision itself can proceed just by filling out this article's checklist in your own environment. What's burdensome is the period after cutover spent continuously catching "problems that didn't show up on the source." For a period after cutover, GIIP tracks the execution time, execution plan, and error rate of representative queries alongside their pre-migration values, isolating only the ones that show degradation as something to act on. The migration work itself is decided by a person, while the ongoing comparison and initial investigation afterward are handled by an AI agent.

執筆・技術検証

GIIP プロダクション運用チーム

大規模Webサービス、SQL Server、Oracle、AWS、Azureの設計・移行・運用に約30年従事。x12largeクラスのAWS RDS for SQL Server環境12セット、約12万テーブルのOracle環境、約3TBのTiDBからAurora MySQLへの移行を経験。現在も複数のクラウドデータベースと約30のWebサービスを、AIエージェントと人間の専門家が継続的に監視・運用しています。

関連するナレッジ

関連サービス

Request a migration assessment from TiDB

同じ確認を複数の環境で継続する必要がある場合は、運用体制ごと相談できます。

Request a migration assessment from TiDB

ナレッジベース一覧へ