はじめに
TiDB v8.5.0 のリリースとともに、TiProxyのTraffic Replay機能がプレビューになりました。これは下記の記事にあるように、本番環境のトラフィックを開発環境で再現したいといったニーズに対応するツールになります。
この記事ではTiDB Playgroundを利用して、この機能を試してみます。
- はじめに、
primary
のデータをreplica
にコピーして、データの状態を揃えます - 次に
primary
のTiProxyでトラフィックをキャプチャします - 最後に
replica
のTiproxyでそのトラフィックを実行します
準備
この記事では、本番を模した primary
と、開発環境を模した replica
の2つのTiDB Playgroundを利用します。TiDB Playgroundは通常は起動ごとにデータをクリアしますが、タグをつけることでデータを保存することができます。
Primary クラスタの準備
まずPrimaryクラスタを起動します。TiProxyを利用するので、--tiproxy
オプションと、タグを保存する -T
オプションをつけていることに注意してください。
> tiup playground v8.5.0 --tiproxy 1 -T primary
Start pd instance: v8.5.0
Start tikv instance: v8.5.0
Start tidb instance: v8.5.0
Start tiproxy instance: v1.3.0
Waiting for tidb and tiproxy instances ready
127.0.0.1:4000 ... Done
127.0.0.1:6000 ... Done
Start tiflash instance: v8.5.0
Waiting for tiflash instances ready
127.0.0.1:3930 ... Done
🎉 TiDB Playground Cluster is started, enjoy!
Connect TiDB: mysql --host 127.0.0.1 --port 4000 -u root
Connect TiProxy: mysql --host 127.0.0.1 --port 6000 -u root
TiDB Dashboard: http://127.0.0.1:2379/dashboard
Grafana: http://127.0.0.1:3000
今回は tpcc ベンチをリプレイします。別のコンソールから tiup bench
を起動し、Primaryクラスタにデータを準備します。
tiup bench tpcc -H 127.0.0.1 -P 6000 -D tpcc --warehouses 4 prepare
データが準備できたら、dumplingでデータを出力しておきます。このデータは replica
クラスタにimportされます。
> tiup dumpling -h 127.0.0.1 -P 4000 -u root \
-B tpcc -o dumpling/ --filetype sql
ここまでできたら、Ctrl-CでPrimaryクラスタを落とします。
Replicaクラスタの準備
Replicaクラスタを起動します。
tiup playground v8.5.0 --tiproxy 1 -T replica
先ほどdumplingでexportしたsqlファイルを実行します。そんなに量が多くないので、シェルスクリプト等で順次実行すれば良いです。こんなスクリプトを作りました。
#!/bin/bash
# change it to your mysql command
MYSQL_CMD="mysql --host 127.0.0.1 --port 4000 -u root"
# check if directory is provided
if [ -z "$1" ]; then
echo "Usage: $0 <directory>"
exit 1
fi
DIR=$1
if [ ! -d "$DIR" ]; then
echo "Directory $DIR does not exist."
exit 1
fi
cd "$DIR"
# schema creation
for s in *-schema-create.sql
do
$MYSQL_CMD < $s
echo "running $s finished"
done
# table creation and data import
for s in *-schema.sql
do
# get database name from first part of file name
DB_NAME=$(echo $s | cut -d'.' -f1)
$MYSQL_CMD -D $DB_NAME < $s
echo "create db $DB_NAME finished"
TABLE_NAME=$(echo $s | cut -d'-' -f1)
echo "importing $TABLE_NAME"
for r in $TABLE_NAME.*.sql
do
$MYSQL_CMD -D $DB_NAME < $r
echo "import $r finished"
# sleep 3
done
echo "import $TABLE_NAME finished"
$MYSQL_CMD -D $DB_NAME -e 'analyze table '"$TABLE_NAME"';'
done
データがインポートできたら、Ctrl-C でreplicaクラスタを落とします。
トラフィックのキャプチャ
それではトラフィックをキャプチャしていきます。まずはPrimaryクラスタを起動します。
tiup playground v8.5.0 --tiproxy 1 -T primary
TiProxyでデータのキャプチャを開始します。tiupでTiProxyをインストールすると、同時にtiproxyctlコマンドもインストールされますが、パスが通っていません。tiup --binary tiproxy
でそのパスを表示するのでそれを利用して実行しています。
TiProxyのAPIエンドポイントを指定しますが、デフォルトは3080です。キャプチャ時間を --duration
で指定します。
`tiup --binary tiproxy`ctl traffic capture --host 127.0.0.1 --port 3080 --output="$PWD/traffic" --duration=5m
outputのパスはフルパスにする必要があります。相対パスにすると、TiProxyのホーム(~/.tiup/data/tiproxy-0/
) 以下に作成されてしまいます。
キャプチャはバックグラウンドで動きます。すかさずtpccベンチマークを走らせます。
tiup bench tpcc -H 127.0.0.1 -P 6000 -D tpcc --warehouses 4 --threads 4 --time 3m run
キャプチャの状況は traffic show
で確認できます。
`tiup --binary tiproxy`ctl traffic show --host 127.0.0.1 --port 3080
5分立つとキャプチャが終了しますが、終了通知などはないので、traffic show
でprogressが100%になったのを確認してください。
trafficディレクトリに、traffic.log
というファイルができています。これがキャプチャされた実行ログです。
# Time: 2024-12-22T22:27:05.690914+09:00
# Conn_ID: 18
# Cmd_type: StmtPrepare
# Payload_len: 128
SELECT c_discount, c_last, c_credit, w_tax FROM customer, warehouse WHERE w_id = ? AND c_w_id = w_id AND c_d_id = ? AND c_id = ?
...
PrimaryをCtrl-Cでシャットダウンします。
キャプチャのリプレイ
キャプチャをリプレイしてみます。まずは、replicaクラスタの起動です。
tiup playground v8.5.0 --tiproxy 1 -T replica
別のコンソールから、リプレイを実行します。
`tiup --binary tiproxy`ctl traffic replay --host 127.0.0.1 --port 3080 --input="$PWD/traffic" --username="root"
username
オプションは必須です。このユーザーを使ってリプレイのSQLが実行されます。
リプレイはバックグラウンドで実行されます。状況はまた traffic show
コマンドで確認できます。
`tiup --binary tiproxy`ctl traffic show --host 127.0.0.1 --port 3080
[
{
"type": "replay",
"status": "done",
"start_time": "2024-12-23 11:39:16.270616 +0900 JST m=+157.953784751",
"end_time": "2024-12-23 11:42:16.286003 +0900 JST m=+337.968426751",
"input": ".../traffic",
"username": "root",
"speed": 1,
"progress": "100%"
}
]
基本的にリプレイは同じタイミングでSQLを実行します。
エラーの確認
リプレイのエラーは tiproxy_traffic_replay
のfailテーブルに保存されています。この例ではエラーが発生しませんでした。
mysql> SELECT * FROM tiproxy_traffic_replay.fail LIMIT 1\G
Empty set (0.01 sec)
環境のクリーンアップ
すべて完了したら、環境を削除します。
tiup clean primary
tiup clean replica
おわりに
TiProxyのTraffic Replay機能について説明しました。この機能はまだプレビューでTiDB Cloudでは利用することができませんが、OSS版/TiUP では利用できますので、ぜひ試してみてください。