导读
在 MySQL 迁移至 TiDB 的过程中,兼容性和性能验证至关重要。SQL-Replay 是一款实用工具,用于评估数据库的兼容性和性能,支持日志解析、查询回放、性能测量和报告生成等功能。


# Time: 2024-01-19T16:29:48.141142Z
# User@Host: t1[t1] @ [10.2.103.21] Id: 797
# Query_time: 0.000038 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1
SET timestamp=1705681788;
SELECT c FROM sbtest1 WHERE id=250438;
# Time: 240119 16:29:48
# User@Host: t1[t1] @ [10.2.103.21] Id: 797
# Query_time: 0.000038 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 1
SET timestamp=1705681788;
SELECT c FROM sbtest1 WHERE id=250438;
# Time: 231106 0:06:36
# User@Host: coplo2o[coplo2o] @ [10.0.2.34] Id: 45827727
# Query_time: 1.066695 Lock_time: 0.000042 Rows_sent: 1 Rows_examined: 7039 Thread_id: 45827727 Schema: db Errno: 0 Killed: 0 Bytes_received: 0 Bytes_sent: 165 Read_first
: 0 Read_last: 0 Read_key: 1 Read_next: 7039 Read_prev: 0 Read_rnd: 0 Read_rnd_next: 0 Sort_merge_passes: 0 Sort_range_count: 0 Sort_rows: 0 Sort_scan_count: 0 Created_tmp_
disk_tables: 0 Created_tmp_tables: 0 Start: 2023-11-06T00:06:35.589701 End: 2023-11-06T00:06:36.656396 Launch_time: 0.000000
# QC_Hit: No Full_scan: No Full_join: No Tmp_table: No Tmp_table_on_disk: No Filesort: No Filesort_on_disk: No
use db;
SET timestamp=1699200395;
SELECT c FROM sbtest1 WHERE id=250438;

- 下载 SQL-Replay 可执行程序
mkdir replay && cd replay && wget https://github.com/Bowen-Tang/sql-replay/releases/download/0.3.2/0.3.2.zip
unzip 0.3.2.zip
#安装 golang (1.20 及以上)
#下载项目
git clone https://github.com/Bowen-Tang/sql-replay
#编译 sql-replay
cd sql-replay
go mod tidy
go build
- 开启上游 MySQL slow log
需要注意的是慢日志 long_query_time 设置为 0 会导致大量的慢日志写入,在高并发场景下,可能会对性能有较大的影响(20%+)
--开启慢查询日志
set global slow_query_log=on;
--设置慢查询时间为 0
SET GLOBAL long_query_time = 0;
--获取<慢查询日志路径>
show variables like 'slow_query_log_file';
2.1.2 使用 Parse-tshark
- 在需要抓取流量的 MySQL 上安装抓包程序 tshark
# Centos 7 自带的版本较低,但也能工作,建议编译安装 3.2.3 版本
yum install -y wireshark
- 或者下载 parse-tshark 可执行程序
mkdir parse-tshark && cd parse-tshark && wget https://github.com/Bowen-Tang/parse-tshark/releases/download/0.1.2/parse-tshark-v0.1.2.zip
unzip parse-tshark-v0.1.2.zip
# Install golang (1.20 and above)
# Download project
git clone https://github.com/Bowen-Tang/parse-tshark
# Compile parse-tshark
cd parse-tshark
go mod tidy
go build
CREATE TABLE `test`.`replay_info` (
`sql_text` longtext DEFAULT NULL,
`sql_type` varchar(16) DEFAULT NULL,
`sql_digest` varchar(64) DEFAULT NULL,
`query_time` bigint(20) DEFAULT NULL,
`rows_sent` bigint(20) DEFAULT NULL,
`execution_time` bigint(20) DEFAULT NULL,
`rows_returned` bigint(20) DEFAULT NULL,
`error_info` text DEFAULT NULL,
`file_name` varchar(64) DEFAULT NULL
);
2.2 生成真实业务流量文件
tail -n 10 <慢查询日志路径>
cd ~/parse-tshark
sudo tshark -i eth0 -f "tcp port 3306" -a duration:3600 -b filesize:2000000 -b files:200 -w ts.pcap
./parse-tshark -mode getmysql -dbinfo 'username:password@tcp(localhost:3306)/information_schema' -output host.ini
for i in `ls -rth ts*.pcap`
do
sudo tshark -r $i -Y "mysql.query or ( tcp.srcport==3306)" -d tcp.port==3306,mysql -o tcp.calculate_timestamps:true -T fields -e tcp.stream -e tcp.len -e tcp.time_delta -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e frame.time_epoch -e mysql.query -E separator='|' >> tshark.log
done
2.3.1 使用 SQL-Replay
./sql-replay -mode parse -slow-in <慢查询日志路径> -slow-out <慢查询输出JSON文件路径>
./parse-tshark -mode parse2file -parsemode 1 -tsharkfile ./tshark.log -hostfile ./host.ini -replayfile ./tshark.out -defaultuser user_null -defaultdb db_null
# 回放所有用户、所有 SQL
./sql-replay -mode replay -db <TiDB 连接字符串> -speed <回放速度> -slow-out <慢查询输出JSON文件路径> -replay-out <回放输出路径>/<回放任务名称> -username all -sqltype all -dbname all
提示:
通过设置 speed 为 n,提高 SQL 回放频率,可以提升 SQL 回放的速度。
当数据库中就一个 database,一个 user 时,使用 -username all -dbname all 来回放。
当数据库中有多个 database、多个 user 时,建议启动多个 SQL-Replay 进程并行回放(否则将出现大量 SQL 报错),每个进程对应不同的 -username 和 -dbname(注意 -db 中的用户名、数据库名也需保持一致)。
2.5 加载回放结果
使用 load 模式将回放结果加载到指定的数据库表中进行进一步分析。其中,<回放输出路径>可以为 SQL-Replay 或 parse-tshark 两种模式的回放 SQL 输出文件。
./sql-replay -mode load -db <TiDB 连接字符串> -out-dir <回放输出路径> -replay-name <回放任务名称> -table replay_info
select count(1) from replay_info where file_name like 'sb1_all.%' limit 11
2.6 生成报告
./sql-replay -mode report -db <TiDB 连接字符串> -replay-name <回放任务名称> -port <Web报告端口>



Q
Q
是否支持流量放大?
没有设计自动的流量放大功能,如果仅需要放大读流量,可以通过启动多个回放程序来加大读流量的方式实现流量放大。
Q
SQL 回放的顺序和上游完全一致么?
SQL 回放顺序并不完全与真实执行顺序相等。
Q
客户长链接和短连接有什么影响么?
在短连接的情况下,可能存在连接数过多的问题
Q
对于海量数据(20TB+)的场景,如何进行真实流量压测?
仿真流量测试在大数据量场景下,还是建议可以全量数据和流量进行测试。如果因为时间周期、成本、重要程度、复杂程度等因素综合考虑无法全量数据压测,建议按照业务主维度(例如游戏服的玩家、订单系统的订单)的 1/4 或者 1/2 等数据进行压测,并且压测时需要将流量放大指定倍数到全流量级别,以便尽量模拟线上的场景,另外就算这样做了,还是可能会存在和线上真实流量较大的偏差,比如其它维度(例如商家维度查询)的跨主维度查询时的数据量可能只有真实流量的 1/4 或者 1/2,从而导致测试数据有一定的偏差。
Q
云上 RDS MySQL 都支持么?
云上 RDS 的慢查询日志格式不尽相同,不一定支持(需要验证慢日志格式);暂不支持 MariaDB,当前无法获取 connection_id,后续加上。
Q
回放时会遇到 too many open files
当 connection_id 值过多(>4096)时,进行回放时会遇到 too many open files 错误,临时解决办法:回放前 ulimit -n 1000000。



TiKV 源码解析系列文章(二十一)Region Merge 源码解析
💡 点击文末【阅读原文】,立即下载试用 TiDB!
、









