記事の一覧

TiDB とは?MySQL 互換の分散 DB の仕組みと移行の注意

TiDB は MySQL 互換の分散 SQL データベースです。TiDB・PD・TiKV・TiFlash の構成、TiDB Cloud のプランの違い、MySQL との違い (AUTO_INCREMENT、トランザクション、未対応の機能) と移行の注意点を整理します。

TiDB は MySQL と同じように SQL で使えて、データが増えたらサーバーを足して広げられるデータベースです。MySQL のシャーディング (データを複数の DB に手で分けること) に限界を感じたチームや、読み書きの多いサービスで名前を聞くことが増えました。この記事では TiDB の仕組み、TiDB Cloud のプランの違い、MySQL との違いと移行するときの注意点をまとめます。

内容は 2026 年 11 月時点の PingCAP (TiDB の開発元) の公式ドキュメントで確かめています。セルフホストの TiDB は最新の LTS (長期サポート版) である v8.5 を前提にしています。

TiDB とは

TiDB は PingCAP が開発しているオープンソースの分散 SQL データベースです。主な特徴は次の 3 つです。

1 つ目は MySQL との互換性です。MySQL のプロトコルで接続でき、MySQL 5.7 と 8.0 の一般的な機能や構文に高い互換性があります。アプリケーションからは MySQL のドライバや ORM をそのまま使って接続できます。

2 つ目は水平スケールです。データは自動で小さな単位に分けられ、複数のサーバーに散らばって保存されます。データやアクセスが増えたら、サーバーを足すことで処理できる量を増やせます。アプリケーション側でシャーディングを作り込む必要はありません。

3 つ目は HTAP (Hybrid Transactional/Analytical Processing) です。注文の登録のような細かい読み書き (トランザクション処理) と、売上の集計のような大きな分析を、同じデータベースで処理できます。

TiDB の構成: TiDB・PD・TiKV・TiFlash

TiDB は役割の違う 4 種類のサーバーでできています。

コンポーネント 役割
TiDB server SQL を受け付ける層。MySQL のプロトコルで接続を受け、SQL を解析・最適化して、分散した実行計画を作る。データは持たない
PD (Placement Driver) クラスタ全体の管理役。どのデータがどこにあるかのメタデータを持ち、トランザクションの ID を払い出し、データの配置を調整する
TiKV 行指向でデータを保存する、分散したキーバリューのストレージ。トランザクションに対応する
TiFlash 列指向でデータを保存するストレージ。分析のクエリを速くする

TiDB server はデータを持たない (ステートレスな) ので、接続やクエリが増えたら台数を足すだけで広げられます。PD は 3 台以上の奇数台で構成することが推奨されています。

TiKV: データを分けて 3 つ持つ

TiKV では、データは Region と呼ばれるキーの範囲ごとに分けて保存されます。各 Region は既定で 3 つのレプリカ (複製) を持ち、Raft という合意のアルゴリズムで内容をそろえます。1 台のサーバーが止まっても、残りのレプリカで処理を続けられます。データが増えると Region が分かれ、PD が Region をサーバー間で移して負荷をならします。

TiFlash: 分析用の列指向のコピー

TiFlash は TiKV のデータを列指向の形でもう 1 つ持つためのストレージです。TiKV から非同期でデータを受け取りますが、読み取るときに複製の進み具合を確かめるので、TiKV と同じスナップショット分離の一貫性で読めます。

TiFlash へのコピーは自動では始まりません。分析に使うテーブルを指定してレプリカを作ります。

-- orders テーブルの TiFlash レプリカを 1 つ作る
ALTER TABLE orders SET TIFLASH REPLICA 1;

-- 複製の進み具合を確かめる (AVAILABLE が 1 なら使える)
SELECT TABLE_NAME, REPLICA_COUNT, AVAILABLE, PROGRESS
FROM information_schema.tiflash_replica
WHERE TABLE_SCHEMA = 'shop' AND TABLE_NAME = 'orders';

レプリカがあると、オプティマイザがコストを見積もって、TiKV (行指向) と TiFlash (列指向) のどちらを読むかを自動で選びます。1 つのクエリの中で両方を使うこともあります。

TiDB Cloud のプラン

TiDB は自分のサーバーで動かすこともできますが、PingCAP が運用するマネージドサービスの TiDB Cloud もあります。AWS、Google Cloud、Microsoft Azure、Alibaba Cloud の上で提供されていて、使えるプランはクラウドによって違います。

主なプランは次のとおりです (2026 年 11 月時点、公式ドキュメントより)。

プラン どんなものか 課金の単位
Starter 複数の利用者で基盤を共有する、自動でスケールするプラン。開発者や小さなチーム向け RU (Request Unit)
Essential 負荷が増えていくアプリケーション向け。自動でスケールする ストレージと RCU (Request Capacity Unit)
Premium 大規模で、性能の安定が求められる業務向け。顧客管理の暗号鍵やプライベートネットワークに対応 ストレージと RCU
Dedicated 本番向け。複数のゾーンにまたがる高可用性。TiDB・TiKV・TiFlash のノードの大きさと数を自分で決める ノードの構成に応じた料金
BYOC (パブリックプレビュー) 管理の部分は PingCAP が持ち、データを扱う部分は自社のクラウドアカウントで動かす (公式ページで確認)

Starter (MySQL 互換) には、組織ごとに最初の 5 つのインスタンスまで、1 インスタンスあたり月 5,000 万 RU、行指向のストレージ 5 GiB、列指向のストレージ 5 GiB の無料枠があります。試すだけならここから始められます。このほか、分析用の Lake などのサービスもあります。料金の単価は変わることがあるので、公式の価格ページで確かめてください。

手元で試す

ローカルで動かしてみたいときは、TiUP というツールで試験用のクラスタを起動できます。

curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
# 表示された案内に従ってシェルの設定を読み込み直したあと
tiup playground

別のターミナルから、MySQL のクライアントで接続します。TiDB の既定のポートは 4000 です。

mysql --host 127.0.0.1 --port 4000 -u root

MySQL との違い

TiDB は MySQL の改造版ではなく、一から作られたデータベースです。そのため、MySQL と同じ SQL が通っても、動きが違うところがあります。移行の前に知っておきたい違いを挙げます。

使えない機能

公式ドキュメントで「未対応」とされている主な機能は次のとおりです。

分類 未対応のもの
サーバー側のロジック ストアドプロシージャとストアドファンクション、トリガー、イベント、ユーザー定義関数
インデックスとデータ型 空間 (SPATIAL/GIS) の関数・型・インデックス、降順インデックス。FULLTEXT はセルフホストと Dedicated では構文を受け付けるだけ
SQL の構文 CREATE TABLE ... AS SELECT、SELECT ... INTO @変数、SKIP LOCKED、XA
管理用のコマンド CHECK TABLE、REPAIR TABLE、OPTIMIZE TABLE など

ストアドプロシージャやトリガーに処理を書いているシステムは、その処理をアプリケーション側に移す必要があります。ジョブのキューを SELECT ... FOR UPDATE SKIP LOCKED で実装している場合も、作りを見直すことになります。

AUTO_INCREMENT の値は連番にならない

TiDB の AUTO_INCREMENT は、値が重複しないことは保証されますが、連番になるとは限りません。値は TiDB server ごとにまとめて払い出されるので、複数の TiDB server から挿入すると番号が飛びます。「ID が連続している」「ID の順に作られた」ことに頼っている処理は見直します。

また、連続した値を主キーにすると、新しい行がすべて同じ Region に入るため、書き込みが 1 台のサーバーに集中します (ホットスポット)。公式ドキュメントでは、書き込みの多いテーブルの主キーには AUTO_RANDOM を勧めています。

CREATE TABLE orders (
  id BIGINT PRIMARY KEY AUTO_RANDOM,
  customer_id BIGINT NOT NULL,
  amount INT NOT NULL,
  created_at DATETIME NOT NULL
);

AUTO_RANDOM は BIGINT の主キーにだけ付けられ、あとから ALTER TABLE で付けたり外したりはできません。テーブルを作る段階で決めておきます。

トランザクションの動き

TiDB の分離レベルは、MySQL との互換のために REPEATABLE-READ と表示されますが、中身はスナップショット分離です。トランザクションは、開始時点までに確定したデータを読みます。MySQL の REPEATABLE READ とは動きが違い、公式ドキュメントでは、ファントムやライトスキュー (2 つのトランザクションがそれぞれ別の行を読んで判断し、両方の書き込みが通ってしまう現象) が起こりうると説明されています。「在庫を読んでから減らす」のように、読んだ値をもとに判断する処理は、SELECT ... FOR UPDATE で行をロックしているかを確かめます。

ロックの方式には、楽観的 (コミットのときに衝突を調べる) と悲観的 (更新の時点で行をロックする) があり、v3.0.8 以降に作ったクラスタは悲観的が既定です。MySQL の InnoDB に近い動きになりますが、細かな違いはあります。

もう 1 つ、1 つのトランザクションの大きさに上限があります。既定では合計 100 MB まで (設定 txn-total-size-limit で変更可) で、1 行は 6 MB までです。数百万行を 1 つの DELETE や UPDATE で処理しているバッチは、件数を区切って実行するように直す必要があります。

そのほかの違い

  • 既定の照合順序は utf8mb4_bin で、MySQL 8.0 の既定 (utf8mb4_0900_ai_ci) と違います。大文字と小文字を区別するかどうかで、検索や一意制約の結果が変わることがあります
  • 外部キーは v6.6.0 で導入され、v8.5.0 で正式な機能 (GA) になりました。親の行にロックがかかるので、同じ親を参照する書き込みが多いと競合が増えることがあります
  • GROUP BY は並び順を保証しません。順序が必要なら ORDER BY を書きます
  • EXPLAIN の出力の形は MySQL と違います。読み方は MySQL の EXPLAIN の読み方 と共通する部分もありますが、TiDB の公式ドキュメントも参照してください
  • performance_schema のテーブルはほとんど結果を返しません。監視には TiDB のダッシュボードや Prometheus・Grafana を使います

MySQL から移行するときの進め方

移行に使うツール

PingCAP は MySQL から TiDB への移行のためのツールを用意しています。

ツール 用途
TiDB Data Migration (DM) MySQL 互換の DB から TiDB へ、全データの移行と、その後の変更の継続的な反映を行う
Dumpling MySQL や TiDB から、全データを SQL や CSV のファイルに書き出す
TiDB Lightning 書き出したファイルや CSV、Parquet を、大量に高速で TiDB に読み込む
sync-diff-inspector MySQL プロトコルの DB 同士で、データが一致しているかを比べる

止められる時間を短くしたいなら、DM で全データを移したあと変更を追いかけて反映し続け、切り替えのときだけ書き込みを止める方法が使えます。データが大きく、時間をかけて止められるなら、Dumpling と Lightning で一括して移す方法もあります。TiDB Cloud にも、データの移行や取り込みの機能があります。

移行の前に確かめること

移行の前に、次の点を今の MySQL で確かめておくと、作業の見通しが立てやすくなります。

  1. ストアドプロシージャ、トリガー、イベントを使っていないか (information_schema.ROUTINES、TRIGGERS、EVENTS を確認する)
  2. SKIP LOCKED、CREATE TABLE ... AS SELECT、空間インデックスや FULLTEXT 検索など、未対応の構文や機能を使っていないか
  3. ID が連番であることや、ID の大小が作成順であることに頼る処理がないか
  4. 1 回で大量の行を更新・削除するバッチがないか
  5. 照合順序の違いで、検索や一意制約の結果が変わる列がないか
  6. 遅いクエリの実行計画が TiDB でも同じように効率よく動くか (主なクエリを TiDB で EXPLAIN ANALYZE して確かめる)

ステージング環境で、本番に近いデータ量とアクセスで試すのが確実です。切り替えたあとも、しばらくは遅いクエリやエラーの推移を注意して見ます。

TiDB が向いている場面

TiDB が候補になるのは、次のような場面です。

  • MySQL のデータや書き込みが 1 台では受けきれなくなり、シャーディングを自前で作るか迷っている
  • MySQL で書いたアプリケーションを大きく変えずに、スケールできる DB に移りたい
  • 業務のデータに対して、レプリカや別の分析基盤を作らずに集計をかけたい (TiFlash)
  • 1 台のサーバーやゾーンが止まっても、自動で処理を続けたい

逆に、データが 1 台の MySQL に十分収まり、ストアドプロシージャなどに処理が多く書かれているシステムでは、移行の手間に見合うかを慎重に比べたほうがよいでしょう。Aurora や RDS の MySQL のまま、インデックスやクエリを見直すことで足りる場合もあります。遅いクエリの見つけ方は MySQL のスロークエリの見つけ方 にまとめています。

移行したあとのデータを見張るには

分散データベースに移ると、DB そのものの状態は TiDB のダッシュボードや Grafana で詳しく見られるようになります。一方で、移行のあとに「注文の件数が以前と比べて減っていないか」「処理待ちのジョブが溜まっていないか」といった業務データの確認は、別に用意しておく必要があります。移行の直後は、ID の採番や照合順序の違いが原因で、エラーにならないまま一部の処理だけがおかしくなることもあります。

手作業で続けるなら、確認用の SQL を cron で定期的に実行し、結果を移行前の値と比べて、外れたら通知する形が手軽です。業務データの監視の考え方は データベース監視とは にまとめています。

この確認を AI に任せる方法もあります。Scandock は TiDB に対応したデータベースの監視サービスで、接続文字列を登録すると、AI がテーブルの構成と実データを読んで、注文数や決済の成否、ジョブの滞留など何を監視するかを決めます。固定の閾値ではなく値の推移を踏まえて異常かどうかを判断し、異常のときは読み取り専用のクエリで原因を調べて、根拠と対処案をつけて通知します。

参考

関連する記事