1. 前言
1.1 企业 & 行业 & 业务介绍
我司主营电力、水利行业的系统集成与软件开发,业务涉及实时监控、数据分析和设备管理等。
1.2 目前遇到的数据库挑战
传统数据库面临海量数据压力,事务处理(OLTP)与分析查询(OLAP)分离导致架构复杂、成本高昂、实时性差。
1.3 参加活动的原因
为探索架构转型,我们体验了TiDB敏捷模式,旨在测试其分布式HTAP数据库能否解决我们混合负载、弹性扩展的痛点。
1.4 敏捷模式的体验总结
敏捷模式部署极其快捷(约15分钟),快速创建多集群。
1.5 敏捷模式是否能应对该挑战
敏捷模式虽为单机部署,但完整展现了TiDB的核心特性,成功验证了其技术可行性,为我们后续选型提供了关键参考。
2. 平凯数据库敏捷模式功能体验
2.1数据迁移体验
| 工具 | 数据量 | 上游数据库 | 下游数据库 |
|---|---|---|---|
| TiDB DM | ~40G | MySQL 8.0.28 | 平凯数据库敏捷模式v7.1.8 |
测试目的:测试MySQL的test_db测试库迁移到平凯数据库是否顺利
2.1.1 准备上游数据库测试数据
安装sysbench
# 安装依赖
sudo yum install -y make automake libtool pkgconfig libaio-devel
sudo yum install -y mysql-devel openssl-devel
# 源码安装
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo yum -y install sysbench
# 验证安装
sysbench --version
生成测试数据
sysbench oltp_common \
--db-driver=mysql \
--mysql-host=localhost \
--mysql-port=3306 \
--mysql-user=root \
--mysql-password=Huang123. \
--mysql-db=test_db \
--tables=20 \
--table-size=10000000 \
--threads=8 \
prepare
mysql没有test_db要创建
create database test_db;
SELECT
TABLE_SCHEMA AS `Database`,
ROUND(SUM(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024/ 1024, 2) AS `Size (GB)`
FROM
information_schema.TABLES
WHERE
TABLE_SCHEMA = 'test_db';
+----------+-----------+
| Database | Size (GB) |
+----------+-----------+
| test_db | 40.73 |
+----------+-----------+
2.1.2 安装DM
安装 TiUP DM 组件
tiup install dm dmctl
如果出现仓库无法下载情况,重新加入本地仓库即可
[tidb@localhost ~]$ tiup install dm dmctl
Please check for root manifest file, you may download one from the repository mirror, or try `tiup mirror set` to force reset it.
Error: initial repository from mirror(https://tiup-mirrors.pingcap.com/) failed: error loading manifest root.json: open /home/tidb/.tiup/bin/root.json: no such file or directory
[tidb@localhost ~]$ tiup mirror set http://192.168.66.140:8080/mirror/v2/repo
WARN: adding root certificate via internet: http://192.168.66.140:8080/mirror/v2/repo/root.json
You can revoke this by remove /home/tidb/.tiup/bin/5f1d1ff1b3e2d645.root.json
Successfully set mirror to http://192.168.66.140:8080/mirror/v2/repo
编辑初始化配置文件vim topology.yaml
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/dm-deploy"
data_dir: "/dm-data"
server_configs:
master:
log-level: info
worker:
log-level: info
master_servers:
- host: 192.168.66.140
name: master1
ssh_port: 22
port: 8261
config:
log-level: info
worker_servers:
- host: 192.168.66.140
ssh_port: 22
port: 8262
config:
log-level: info
monitoring_servers:
- host: 192.168.66.140
ssh_port: 22
port: 9091
deploy_dir: "/tidb-deploy/prometheus-9091"
data_dir: "/tidb-data/prometheus-9091"
log_dir: "/tidb-deploy/prometheus-9091/log"
grafana_servers:
- host: 192.168.66.140
port: 3001
deploy_dir: /tidb-deploy/grafana-3001
列出仓库中有哪些dm-master版本可用
tiup list dm-master
选择一个版本部署dm集群(root用户执行)
tiup dm deploy dm-test v7.1.8-5.2-20250630 ./topology.yaml --user root
启动dm集群
tiup dm start dm-test
检查 dm-test 集群情况
tiup dm display dm-test
dm-master状态是Healthy|L,dm-worker状态是Free则正常启动

2.1.3 创建迁移用户授予权限
上游数据库 (MySQL)
create user dm_user@'%' identified by '123456';
GRANT RELOAD,REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO dm_user@'%';
GRANT SELECT ON test_db.* TO dm_user@'%';
下游数据库 (TiDB)
create user dm_user@'%' identified by '123456';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,INDEX,REFERENCES ON test_db.* TO dm_user@'%';
GRANT ALL ON dm_meta.* TO dm_user@'%';
GRANT ALL PRIVILEGES ON lightning_task_info.* TO 'dm_user'@'%';
2.1.4 创建数据源
新建 source1.yaml 文件
# 唯一命名,不可重复。
source-id: "mysql-01"
# DM-worker 是否使用全局事务标识符 (GTID) 拉取 binlog。使用前提是上游 MySQL 已开启 GTID 模式。若上游存在主从自动切换,则必须使用 GTID 模式。
enable-gtid: true
from:
host: "192.168.66.150" # 例如:172.16.10.81
user: "dm_user"
password: "123456" # 支持但不推荐使用明文密码,建议使用 dmctl encrypt 对明文密码进行加密后使用
port: 3306
在终端中执行下面的命令后,使用 tiup dmctl 将数据源配置加载到 DM 集群中:
tiup dmctl --master-addr 192.168.66.140:8261 operate-source create source1.yaml
--master-addr:dmctl 要连接的集群的任意 DM-master 节点的 {advertise-addr}
operate-source create:向 DM 集群加载数据源
2.1.5 创建迁移任务
新建 task.yaml 文件
# 任务名,多个同时运行的任务不能重名。
name: "test"
# 任务模式,可设为
# full:只进行全量数据迁移
# incremental: binlog 实时同步
# all: 全量 + binlog 迁移
task-mode: "all"
# 下游 TiDB 配置信息。
target-database:
host: "192.168.66.140"
port: 4001
user: "dm_user"
password: "123456" # 支持但不推荐使用明文密码,建议使用 dmctl encrypt 对明文密码进行加密后使用
# 当前数据迁移任务需要的全部上游 MySQL 实例配置。
mysql-instances:
-
# 上游实例或者复制组 ID。
source-id: "mysql-01"
# 需要迁移的库名或表名的黑白名单的配置项名称,用于引用全局的黑白名单配置,全局配置见下面的 `block-allow-list` 的配置。
block-allow-list: "listA"
# 黑白名单全局配置,各实例通过配置项名引用。
block-allow-list:
listA: # 名称
do-tables: # 需要迁移的上游表的白名单。
- db-name: "test_db" # 需要迁移的表的库名。
tbl-name: "*" # 需要迁移的表的名称。
2.1.6 启动任务
启动数据迁移任务之前,建议使用 check-task 命令检查配置是否符合 DM 的配置要求,以避免后期报错。
tiup dmctl --master-addr 192.168.66.140:8261 check-task task.yaml
使用 tiup dmctl 执行以下命令启动数据迁移任务。
tiup dmctl --master-addr 192.168.66.140:8261 start-task task.yaml
2.1.7 查看任务状态
tiup dmctl --master-addr 192.168.66.140:8261 query-status test
先dump 从上游 MySQL 导出全量数据到本地磁盘。progress百分百表示导出完成。
然后load 读取 dump 处理单元导出的数据文件,然后加载到下游 TiDB。progress百分百表示加载完成。
dump时间会比load时间快很多。

还可以使用上面dm集群的grafana监控
http://192.168.66.140:3001/

2.1.8 停止任务
如果不停止任务他会一直在同步状态
tiup dmctl --master-addr 192.168.66.140:8261 stop-task test
2.1.9 迁移体验总结
优点:整体迁移过程丝滑流畅,mysql迁移TiDB功能完善成熟。 缺点:命令配置繁琐复杂;迁移功能没有集成在TEM中,没有体现迁移在TEM中的优势。
望官方能集成迁移在TEM中,简化配置步骤,做到图形化配置,一键迁移。
2.2 MySQL 兼容性
2.2.1 SQL 语法兼容性测试
目标:验证常用和复杂的 SQL 语法是否被支持。
| 测试项 | 测试SQL | 结果(TiDB vs MySQL) |
|---|---|---|
| DDL | CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(50)); | 创建成功,表结构一致 |
| DML | INSERT INTO t1 VALUES (1, 'Alice'), (2, 'Bob'); | 数据插入成功 |
| DQL | SELECT * FROM t1 WHERE id = 1; | 查询结果一致 |
| CTE(公共表表达式) | WITH cte AS (SELECT * FROM t1) SELECT * FROM cte; | 执行成功,结果一致 |
| 窗口函数 | SELECT id, name, RANK() OVER (ORDER BY id DESC) FROM t1; | 执行成功,排名结果一致 |
| 复杂JOIN | SELECT * FROM t1 a LEFT JOIN t1 b ON a.id = b.id; | 执行成功,结果一致 |
2.2.2 函数兼容性测试
目标:验证常用内置函数的可用性和结果正确性。
| 测试项 | 测试SQL | 结果(TiDB vs MySQL) |
|---|---|---|
| 字符串函数 | SELECT CHAR_LENGTH('中国'), CONCAT('A', NULL), INSTR('ABC', 'B'); | 返回值一致 |
| 日期函数 | SELECT NOW(), DATE_ADD('2023-01-01', INTERVAL 1 MONTH); | 返回时间和日期计算一致 |
| 数值函数 | SELECT ROUND(123.456, 2), ABS(-1), RAND(); | 返回值一致(RAND() 的随机性序列可能不同) |
| 聚合函数 | CREATE TABLE t_agg (id INT, val INT); INSERT INTO t_agg VALUES (1, 3), (2, 5), (3, 1); SELECT COUNT(*), COUNT(val), SUM(val) FROM t_agg; | 聚合结果一致 |
2.2.3 分区表兼容性测试
目标:验证分区表的管理和查询路由。
| 测试项 | 测试SQL | 结果(TiDB vs MySQL) |
|---|---|---|
| 创建分区表 | CREATE TABLE t_part (id INT, dt DATE) PARTITION BY RANGE COLUMNS(dt) ( PARTITION p0 VALUES LESS THAN ('2023-01-01'), PARTITION p1 VALUES LESS THAN ('2024-01-01') ); | 执行成功 |
| 分区修剪 | EXPLAIN SELECT * FROM t_part WHERE dt = '2023-06-01'; | 都访问p1分区 |
| 管理分区 | ALTER TABLE t_part ADD PARTITION (PARTITION p2 VALUES LESS THAN ('2025-01-01')); | 执行成功 |
2.2.4 视图兼容性测试
目标:验证视图的创建和查询。
| 测试项 | 测试SQL | 结果(TiDB vs MySQL) |
|---|---|---|
| 创建视图 | CREATE VIEW v1 AS SELECT id, name FROM t1 WHERE id > 1; | 执行成功 |
| 查询视图 | SELECT * FROM v1; | 查询结果与基表查询 SELECT id, name FROM t1 WHERE id > 1; 一致 |
2.2.5 存储过程兼容性测试
目标:验证存储过程的基本功能。
| 测试项 | 测试SQL | 结果(TiDB vs MySQL) |
|---|---|---|
| 创建存储过程 | <br>DELIMITER // <br>CREATE PROCEDURE simple_proc(IN p_id INT) <br>BEGIN <br> SELECT * FROM t1 WHERE id = p_id; <br>END // <br>DELIMITER ;<br> |
MySQL成功创建存储过程,TiDB创建失败 |
| 调用存储过程 | CALL simple_proc(1); | MySQL成功调用,TiDB调用失败 |
2.2.6 索引兼容性测试
目标:验证索引的创建、使用和优化器选择。
| 测试项 | 测试SQL | 结果(TiDB vs MySQL) |
|---|---|---|
| 创建索引 | CREATE INDEX idx_name ON t1(name);CREATE UNIQUE INDEX idx_unique ON t1(id); | 执行成功 |
| 使用索引 | EXPLAIN SELECT * FROM t1 WHERE name = 'Alice'; | 都使用了idx_name索引 |
| 前缀索引 | CREATE INDEX idx_prefix ON t1(name(3));EXPLAIN ANALYZE SELECT * FROM t1 WHERE name LIKE 'Alic%'; | 支持创建,且查询使用了相同索引 |
2.2.6 数据类型兼容性测试
目标:验证各种数据类型的定义、存储和计算是否准确。
| 测试项 | 测试SQL | 结果(TiDB vs MySQL) |
|---|---|---|
| 数值类型 | CREATE TABLE t_num (a TINYINT, b DECIMAL(10, 2)); INSERT INTO t_num VALUES (127, 123.456);INSERT INTO t_num VALUES (128, 123.456); | TINYINT插入128溢出都报错,DECIMAL结果都是123.46 |
| 时间类型 | CREATE TABLE t_time (a DATETIME, b TIMESTAMP); INSERT INTO t_time VALUES ('2023-01-01 12:00:00', NOW()); SELECT * FROM t_time; | 时间显示格式和值时区转换行为一致 |
| 字符串类型 | CREATE TABLE t_str (a CHAR(10), b VARCHAR(10)); INSERT INTO t_str VALUES ('abc ', 'abc '); SELECT CONCAT('(', a, ')'), CONCAT('(', b, ')') FROM t_str; | 尾部空格处理行为一致 |
| JSON类型 | CREATE TABLE t_json (j JSON); INSERT INTO t_json VALUES ('{"key": "value"}'); SELECT j->>"$.key" FROM t_json; | JSON 语法和查询结果一致 |
2.2.7 MySQL兼容性体验总结
平凯数据库兼容大部分MySQL语法和功能,但有小部分功能(比如存储过程)不支持或者语法不一致。
2.3 测试压缩比
测试目的:相同数据对比压缩后的MySQL和平凯数据库的空间大小。
2.3.1 准备测试数据
[root@localhost opt]# ll sbtest1.csv -h
-rw-r--r--. 1 root root 2.0G Sep 4 16:19 sbtest1.csv
2.3.2 MySQL导入数据
create database test_db;
create table test_db.sbtest1(id int, k varchar(255), c varchar(255), pad varchar(255));
LOAD DATA INFILE '/opt/sbtest1.csv' INTO TABLE test_db.sbtest1 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;
记得MySQL配置文件加上参数secure-file-priv=/opt/
2.3.2 平凯数据库导入数据
使用TiDB Lightning工具导入csv数据 1.安装TiDB Lightning
tiup install tidb-lightning
2.创建目标表结构
cat > test_db-schema-create.sql << EOF
create database test_db;
EOF
cat > test_db.sbtest1-schema.sql << EOF
create table test_db.sbtest1(id int, k varchar(255), c varchar(255), pad varchar(255));
EOF
[root@localhost Lightning]# pwd
/opt/Lightning
[root@localhost Lightning]# ll
total 2000880
-rw-r--r-- 1 root root 2048888917 Sep 4 22:06 test_db.sbtest1.csv
-rw-r--r-- 1 root root 88 Sep 4 23:31 test_db.sbtest1-schema.sql
-rw-r--r-- 1 root root 25 Sep 4 23:31 test_db-schema-create.sql
3.编写配置文件
新建文件 tidb-lightning.toml
vim tidb-lightning.toml
[lightning]
level = "info"
file = "tidb-lightning.log"
[tikv-importer]
backend = "tidb"
sorted-kv-dir = "/mnt/ssd/sorted-kv-dir"
[mydumper]
data-source-dir = "/opt/Lightning"
[mydumper.csv]
separator = ','
delimiter = '"'
terminator = "\r\n"
header = true
not-null = true
null = '\N'
backslash-escape = false
trim-last-separator = false
[tidb]
host = "192.168.66.140"
port = 4001
user = "root"
password = "xKYT?0US2QUb"
status-port = 10081
pd-addr = "192.168.66.140:2381"
4.执行导入
tiup tidb-lightning -config tidb-lightning.toml
2.3.3 手动compact TiKV数据
先停止tikv服务

手动compact TiKV数据
tiup ctl:v7.1.8-5.2-20250630 tikv --data-dir /tidb1/tidb-data/tikv-20161 compact -d kv
再启动tikv服务
查看compact后TiKV数据目录test_db数据库空间大小(因为没有其他库的数据,所以可以把db下的空间等同于test_db库的占用磁盘空间大小)
[root@localhost Lightning]# du -sh /tidb1/tidb-data/tikv-20161/db/
1.3G /tidb1/tidb-data/tikv-20161/db/
提示!:如何查看tikv数据目录位置
tiup cluster list
tiup cluster display test-tidb-cluster
还可以在TEM看

2.3.4 查看MySQL数据目录大小
查看数据目录位置
mysql> show variables like 'datadir';
+---------------+--------------+
| Variable_name | Value |
+---------------+--------------+
| datadir | /data/mysql/ |
+---------------+--------------+
1 row in set (0.01 sec)
查看test_db数据库的空间大小
[root@localhost ~]# du -sh /data/mysql/test_db/
2.3G /data/mysql/test_db/
2.3.5 体验压缩比总结
| MySQL | 平凯数据库 | 结果 | |
|---|---|---|---|
| 磁盘空间 | 2.3G | 1.3G | 相同数据源下平凯数据库比MySQL少了差不多44%的磁盘空间,平凯数据库胜 |
平凯数据库部分场景确实做到了降本增效,非常厉害! 平凯数据库LSM数据结构相对于MySQL的b-tree的优势在于插入,参考[[#2.7 敏捷模式性能表现]]
2.4 在线 DDL 操作易用性
测试目的:测试增加/删除字段、修改字段默认值、修改数据精度(char/datetime)、类型变更(int->bigint)、创建索引等在线DDL操作易用性。
2.4.1 添加字段
ALTER TABLE test_db.sbtest1 ADD COLUMN email VARCHAR(255) DEFAULT 'unknown@tidb.io';
ALTER TABLE test_db.sbtest1 ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP();
ALTER TABLE test_db.sbtest1 ADD COLUMN age INT;
查看DDL任务队列状态
mysql> ADMIN SHOW DDL JOBS;
+--------+---------------------+---------------------+---------------+--------------+-----------+----------+-----------+----------------------------+----------------------------+----------------------------+--------+-------------+
| JOB_ID | DB_NAME | TABLE_NAME | JOB_TYPE | SCHEMA_STATE | SCHEMA_ID | TABLE_ID | ROW_COUNT | CREATE_TIME | START_TIME | END_TIME | STATE | COMMENTS |
+--------+---------------------+---------------------+---------------+--------------+-----------+----------+-----------+----------------------------+----------------------------+----------------------------+--------+-------------+
| 154 | test_db | sbtest1 | add column | public | 141 | 143 | 0 | 2025-09-05 11:10:04.421000 | 2025-09-05 11:10:04.421000 | 2025-09-05 11:10:04.421000 | synced | |
2.4.2 修改字段默认值
ALTER TABLE test_db.sbtest1 ALTER COLUMN email SET DEFAULT 'unknown@tidb.iov2';
mysql> ADMIN SHOW DDL JOBS;
+--------+---------------------+---------------+-------------------+--------------+-----------+----------+-----------+----------------------------+----------------------------+----------------------------+--------+-------------+
| JOB_ID | DB_NAME | TABLE_NAME | JOB_TYPE | SCHEMA_STATE | SCHEMA_ID | TABLE_ID | ROW_COUNT | CREATE_TIME | START_TIME | END_TIME | STATE | COMMENTS |
+--------+---------------------+---------------+-------------------+--------------+-----------+----------+-----------+----------------------------+----------------------------+----------------------------+--------+-------------+
| 155 | test_db | sbtest1 | set default value | public | 141 | 143 | 0 | 2025-09-05 11:33:06.521000 | 2025-09-05 11:33:06.521000 | 2025-09-05 11:33:06.521000 | synced | |
mysql> insert into test_db.sbtest1(id,k,c,pad) values(10000002,'5036310','123','234');
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_db.sbtest1 order by id desc limit 1;
+----------+---------+------+------+-------------------+
| id | k | c | pad | email |
+----------+---------+------+------+-------------------+
| 10000002 | 5036310 | 123 | 234 | unknown@tidb.iov2 |
+----------+---------+------+------+-------------------+
1 row in set (0.62 sec)
2.4.3 修改字段精度/长度
ALTER TABLE test_db.sbtest1 MODIFY COLUMN email VARCHAR(200);
ALTER TABLE test_db.sbtest1 MODIFY COLUMN created_at DATETIME(3);
mysql> ADMIN SHOW DDL JOBS;
+--------+---------+------------+-------------------+--------------+-----------+----------+-----------+----------------------------+----------------------------+----------------------------+--------+-------------+
| JOB_ID | DB_NAME | TABLE_NAME | JOB_TYPE | SCHEMA_STATE | SCHEMA_ID | TABLE_ID | ROW_COUNT | CREATE_TIME | START_TIME | END_TIME | STATE | COMMENTS |
+--------+---------+------------+-------------------+--------------+-----------+----------+-----------+----------------------------+----------------------------+----------------------------+--------+-------------+
| 158 | test_db | sbtest1 | modify column | public | 141 | 143 | 10000002 | 2025-09-05 11:56:09.621000 | 2025-09-05 11:56:09.621000 | 2025-09-05 11:58:06.270000 | synced | |
| 157 | test_db | sbtest1 | modify column | public | 141 | 143 | 0 | 2025-09-05 11:55:27.571000 | 2025-09-05 11:55:27.571000 | 2025-09-05 11:55:27.620000 | synced | |
这里不太懂为什么修改email VARCHAR(200)会影响行数10000002,其他修改是0
mysql> desc test_db.sbtest1;
+------------+--------------+------+------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+------+---------+-------+
| id | int | YES | | NULL | |
| k | varchar(255) | YES | MUL | NULL | |
| c | varchar(255) | YES | | NULL | |
| pad | varchar(255) | YES | | NULL | |
| email | varchar(180) | YES | | NULL | |
| created_at | datetime(3) | YES | | NULL | |
| age | int | YES | | NULL | |
+------------+--------------+------+------+---------+-------+
2.4.4 类型变更
ALTER TABLE test_db.sbtest1 MODIFY COLUMN age BIGINT;
mysql> desc test_db.sbtest1;
+------------+--------------+------+------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+------+---------+-------+
| id | int | YES | | NULL | |
| k | varchar(255) | YES | MUL | NULL | |
| c | varchar(255) | YES | | NULL | |
| pad | varchar(255) | YES | | NULL | |
| email | varchar(180) | YES | | NULL | |
| created_at | datetime(3) | YES | | NULL | |
| age | bigint | YES | | NULL | |
+------------+--------------+------+------+---------+-------+
2.4.5 添加索引
ALTER TABLE test_db.sbtest1 ADD INDEX idx_age_email(age, email);
测试DDL中能否使用DML
select * from test_db.sbtest1;
结果DDL不阻塞DML
测试查询是否使用索引
mysql> explain select * from test_db.sbtest1 where age = 1 and email='hhh';
+-------------------------------+---------+-----------+------------------------------------------------+-------------------------------------------+
| id | estRows | task | access object | operator info |
+-------------------------------+---------+-----------+------------------------------------------------+-------------------------------------------+
| IndexLookUp_10 | 1.00 | root | | |
| ├─IndexRangeScan_8(Build) | 1.00 | cop[tikv] | table:sbtest1, index:idx_age_email(age, email) | range:[1 "hhh",1 "hhh"], keep order:false |
| └─TableRowIDScan_9(Probe) | 1.00 | cop[tikv] | table:sbtest1 | keep order:false |
+-------------------------------+---------+-----------+------------------------------------------------+-------------------------------------------+
3 rows in set (0.01 sec)
2.4.6 体验在线 DDL 操作易用性总结
MySQL的在线DDL有部分DDL操作会有短暂的排他锁,如果对MySQL在线DDL的底层不熟悉可能会造成事故。而TIDB有天然的在线DDL优势,对业务影响更加小,操作更加简单,不用考虑底层细节。
2.5 高可用/容灾
2.5.1 故障恢复测试
2.5.1.1 模拟节点级别故障恢复
使用[[#2.6.1 节点扩展]]的集群三节点高可用环境
2.5.1.1.1 启用 TiProxy
配置TiProxy故障转移
1.在单独的拓扑文件中配置 TiProxy,例如 tiproxy.toml:
server_configs:
tiproxy:
ha.virtual-ip: "192.168.66.188/24"
ha.interface: "ens33"
tiproxy_servers:
- host: 192.168.66.140
deploy_dir: "/tiproxy-deploy"
port: 6000
status_port: 3080
- host: 192.168.66.143
deploy_dir: "/tiproxy-deploy"
port: 6000
status_port: 3080
- host: 192.168.66.144
deploy_dir: "/tiproxy-deploy"
port: 6000
status_port: 3080
- host: 192.168.66.145
deploy_dir: "/tiproxy-deploy"
port: 6000
status_port: 3080
2.扩容 TiProxy。
tiup cluster scale-out production_cluster tiproxy.toml
之后连接客户端连接地址192.168.66.188:6000即可
使用 VIP 进行数据库连接测试,确保一切正常。

2.5.1.1.2 模拟节点故障
1.客户端连接测试
进行查询

2.模拟灾难
在记录完 t0 后,立即模拟灾难发生。(关闭vip所在节点)
shutdown -h now
3.客户端再次查询 再次查询成功表示有高可用,vip漂移需要一点时间,会有一点延迟
2.6 可扩展性
2.6.1 节点扩展
测试从单节点扩展到三节点时,系统的性能变化和数据一致性,确保无缝扩展的能力 测试方法:保持压测状态,期间进行节点扩展 观察系统的性能变化方法:观察QPS,延迟是否波动大 数据一致性判断方法:观察grafana的集群的pd->region health的miss-peer-region-count是否由大于0慢慢变为0。
1.进行压测[[#2.7.2.2 OLAP测试]]
2.进入集群点击扩容,选择PingKaiDB Fusion扩容到两个主机
扩展完成

3.观察QPS和延迟

可以看出扩展节点对系统的性能影响是比较小的
4.观察region health
可以看到miss-peer-region-count最终是0
2.6.2 功能扩展
2.6.2.1 添加组件TiCDC
使用TEM快速创建两个集群,一个生产环境集群,一个副本集群,使用TICDC进行同步

上游生产集群 ->TiCDC同步 ->下游备集群
设置上游生产集群的GC时间,默认10分钟,不然实验没做完,GC时间到了,同步不了。
UPDATE mysql.tidb SET VARIABLE_VALUE = '30m0s' WHERE VARIABLE_NAME = 'tikv_gc_life_time';
2.6.2.1.1 安装TiCDC
使用 TiUP 在生产 TiDB 集群上新增 TiCDC 组件
1.编写一个名为 scale-out.yml 的配置文件,包含需要扩容的节点的配置信息。
cdc_servers:
- host: 192.168.66.140
gc-ttl: 86400
data_dir: /tidb-data/cdc-8300
- host: 192.168.66.141
gc-ttl: 86400
data_dir: /tidb-data/cdc-8300
- host: 192.168.66.142
gc-ttl: 86400
data_dir: /tidb-data/cdc-8300
host:指定部署到哪台机器,字段值填 IP 地址gc-ttl:TiCDC 在 PD 设置的服务级别 GC safepoint 的 TTL (Time To Live) 时长,单位为秒,默认值为 86400,即 24 小时data_dir:指定数据目录。
2.在 TiUP 中控机上执行命令进行扩容:
tiup cluster scale-out production_cluster scale-out.yml
3.查看生产集群组件
tiup cluster display production_cluster

2.6.2.1.2 同步到下游
TiCDC 工具只负责复制增量数据,需要使用 Dumpling/TiDB Lightning 工具或者 BR 工具进行全量数据的初始化。 经过全量数据的初始化后,需要将 start-ts 指定为上游备份时的 TSO。
使用[[#2.6.2.3 添加组件BR]]进行全量初始化备集群。
为了看出效果,全量备份后再加一下增量数据,看是否能全量加增量全部同步

1.全量恢复到下游备集群 把[[#2.6.2.3.2 对集群进行快照备份]]进行恢复到下游备集群
tiup br restore full --pd "192.168.66.144:2379" \
--storage "s3://tem-bucket?access-key=myminioadmin&secret-access-key=minio-secret-key-change-me&endpoint=http://192.168.66.121:9000"
--pd:为备集群的pd地址

2.获取上游备份时的 TSO [[#2.6.2.3.2 查询快照备份的时间点信息]]
3.创建同步任务
/root/.tiup/components/cdc/v7.1.8-5.2-20250630/cdc cli changefeed create \
--server=http://192.168.66.140:8300 \
--sink-uri="mysql://root:9%3FOknyciGL2dE@192.168.66.144:4000/" \
--changefeed-id="simple-replication-task" \
--start-ts=460654926277115916
--server:TiCDC 集群中任意一个 TiCDC 服务器的地址--changefeed-id:同步任务的 ID,格式需要符合正则表达式^[a-zA-Z0-9]+(\-[a-zA-Z0-9]+)*$。如果不指定该 ID,TiCDC 会自动生成一个 UUID(version 4 格式)作为 ID。--sink-uri:同步任务下游的地址。注意9%3FOknyciGL2dE为密码的URL编码(有特殊字符需要URL编码)--start-ts:指定 changefeed 的开始 TSO
同步完成

查看同步任务
/root/.tiup/components/cdc/v7.1.8-5.2-20250630/cdc cli changefeed list --server=http://192.168.66.140:8300
停止同步任务
/root/.tiup/components/cdc/v7.1.8-5.2-20250630/cdc cli changefeed pause --server=http://192.168.66.140:8300 --changefeed-id simple-replication-task
2.6.2.2 添加组件TiFlash
可以在TEM中点开集群,直接扩容TiFlash

点击添加节点

选择TiFlash扩容

打上勾选,确定

按库构建 TiFlash 副本
ALTER DATABASE sbtest SET TIFLASH REPLICA 1;
查看库同步进度
SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = 'sbtest';
2.6.2.3 添加组件BR
2.6.2.3.1 准备环境
1.准备一个对象存储系统,我这里选用自建的MinIO作为备份存储系统
| endpoint | access-key | secret-access-key | bucket |
|---|---|---|---|
| http://192.168.66.121:9000 | myminioadmin | minio-secret-key-change-me | tem-bucket |
2.被备份的集群创建一些测试数据

2.6.2.3.2 安装br
tiup install br
2.6.2.3.3 对集群进行快照备份
tiup br backup full \
--pd "192.168.66.143:2379" \
--storage "s3://tem-bucket?access-key=myminioadmin&secret-access-key=minio-secret-key-change-me&endpoint=http://192.168.66.121:9000" \
--log-file backupfull.log
需要pd的地址是为了获取tikv的分布位置
2.6.2.3.4 查询快照备份的时间点信息
恢复时需要备份的TSO,怎么查看?
查看某个快照备份对应的快照时间点TSO
tiup br validate decode --field="end-version" \
--storage "s3://tem-bucket?access-key=myminioadmin&secret-access-key=minio-secret-key-change-me&endpoint=http://192.168.66.121:9000" | tail -n1
2.7 敏捷模式性能表现
测试对比平凯数据库敏捷模式单机版和MySQL单机版的OLTP性能表现
2.7.1 环境准备
MySQL和平凯数据库的环境要一致:
| Mysql | 平凯数据库 | |
|---|---|---|
| CPU/内存 | 8c16g | 8c16g |
| 硬盘 | 100g硬盘 | 100g硬盘 |
| 版本 | v8.0.28 | v7.1.8-5.2-20250630 |
| OLTP工具 | sysbench | sysbench |
| OLAP工具 | go-tpc | go-tpc |
2.7.2 执行测试
2.7.2.1 OLTP测试
1.安装sysbench 参考[[#2.1.1 准备上游数据库测试数据]]
2.准备数据 对 MySQL 准备数据
sysbench oltp_common --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password='Huang123.' --mysql-db=test --tables=5 --table-size=25000000 --db-driver=mysql prepare
对 TiDB 准备数据
sysbench oltp_common --mysql-host=192.168.66.143 --mysql-port=4000 --mysql-user=root --mysql-password='jYGz*keSu3aGi3' --mysql-db=test --tables=5 --table-size=25000000 --db-driver=mysql prepare
--mysql-host: TiDB Server地址
3.运行测试 MySQL 只读测试
sysbench oltp_read_only --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password='Huang123.' --mysql-db=test --tables=5 --table-size=25000000 --threads=128 --db-driver=mysql --time=600 run
--time:测试时间(秒)
只写测试
sysbench oltp_write_only --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password='Huang123.' --mysql-db=test --tables=5 --table-size=25000000 --threads=128 --db-driver=mysql --time=600 run
读写混合测试
sysbench oltp_read_write --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password='Huang123.' --mysql-db=test --tables=5 --table-size=25000000 --threads=128 --db-driver=mysql --time=600 run
TiDB 只读测试
sysbench oltp_read_only --mysql-host=192.168.66.143 --mysql-port=4000 --mysql-user=root --mysql-password='jYGz*keSu3aGi3' --mysql-db=test --tables=5 --table-size=25000000 --threads=128 --db-driver=mysql --time=600 run
只写测试
sysbench oltp_write_only --mysql-host=192.168.66.143 --mysql-port=4000 --mysql-user=root --mysql-password='jYGz*keSu3aGi3' --mysql-db=test --tables=5 --table-size=25000000 --threads=128 --db-driver=mysql --time=600 run
读写混合测试
sysbench oltp_read_write --mysql-host=192.168.66.143 --mysql-port=4000 --mysql-user=root --mysql-password='jYGz*keSu3aGi3' --mysql-db=test --tables=5 --table-size=25000000 --threads=128 --db-driver=mysql --time=600 run
4.数据采集 记录测试点:QPS 并发数:128
| 并发数\测试类型 | 只读 | 只写 | 读写混合 |
|---|---|---|---|
| MySQL | 50994160 | 3980580 | 12334720 |
| 平凯数据库 | 14583552 | 9212658 | 9423720 |
| 降71% | 升57% | 降24% | |

2.7.2.2 OLAP测试
测试环境内存不是很充足的最好不要测试下面平凯数据库OLAP测试(至少64g)
平凯数据库 1.安装go-tpc
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/pingcap/go-tpc/master/install.sh | sh
source /root/.bash_profile
2.准备数据
# 此命令会自动创建表结构并导入数据
go-tpc tpch --host 192.168.66.143 --port 4000 --user root -p y9MpJMcFq?Pwu -D tpch --sf=10 prepare
更新统计信息
ANALYZE TABLE customer, lineitem, nation, orders, part, partsupp, region, supplier;
3.同步到 TiFlash
ALTER DATABASE tpch SET TIFLASH REPLICA 1;
4.查看库同步进度
SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = 'tpch';
等待完全同步完成
5.执行测试与监控
执行并发查询
go-tpc tpch --host 192.168.66.143 --port 4000 --user root -p y9MpJMcFq?Pwu -D tpch --sf=10 --threads=2 --time 5m run
Mysql 1.准备数据
go-tpc tpch --host 192.168.66.150 --port 3306 --user root -p Huang123. -D tpch --sf=10 prepare
更新统计信息
ANALYZE TABLE customer, lineitem, nation, orders, part, partsupp, region, supplier;
执行并发查询
go-tpc tpch --host 192.168.66.150 --port 3306 --user root -p Huang123. -D tpch --sf=10 --threads=2 --time 5m run
结果:

| 查询 | MySQL 8.0.28 | TiDB 7.1.8 | 性能差异 (MySQL/TiDB) | 优势方 | 性能提升倍数 |
|---|---|---|---|---|---|
| Q1 | 63.79 | 2.00 | 31.9x | TiDB | 31.9倍 |
| Q2 | 1.64 | 1.10 | 1.5x | TiDB | 1.5倍 |
| Q3 | 39.69 | 1.04 | 38.2x | TiDB | 38.2倍 |
| Q4 | 14.50 | 7.19 | 2.0x | TiDB | 2.0倍 |
| Q5 | 21.94 | 2.26 | 9.7x | TiDB | 9.7倍 |
| Q6 | 21.11 | 0.28 | 75.4x | TiDB | 75.4倍 |
| Q7 | 67.14 | 0.92 | 73.0x | TiDB | 73.0倍 |
| Q8 | 54.02 | 1.15 | 47.0x | TiDB | 47.0倍 |
| Q9 | 193.41 | 5.64 | 34.3x | TiDB | 34.3倍 |
2.7.3 敏捷模式性能体验总结
OLTP性能测试表现:平凯数据库写操作性能优秀,读操作性能欠佳。
OLAP性能测试表现:平凯数据库处理分析型查询非常优秀!
2.8 TEM 易用性
2.8.1 TEM高可用搭建
| ip |
|---|
| 192.168.66.140 |
| 192.168.66.141 |
| 192.168.66.142 |
sudo adduser tem
passwd tem
chmod u+w /etc/sudoers
cat >> /etc/sudoers << EFO
tem ALL=(ALL) NOPASSWD:ALL
EFO
su tem
mkdir /home/tem/.ssh/
chmod 700 ~/.ssh
1.三台机器建立互相
# 192.168.66.140
ssh-keygen -t rsa -b 2048 -f /home/tem/.ssh/id_rsa -N ""
ssh-copy-id -i /home/tem/.ssh/id_rsa.pub tem@192.168.66.140
ssh-copy-id -i /home/tem/.ssh/id_rsa.pub tem@192.168.66.141
ssh-copy-id -i /home/tem/.ssh/id_rsa.pub tem@192.168.66.142
# 192.168.66.141
ssh-keygen -t rsa -b 2048 -f /home/tem/.ssh/id_rsa -N ""
ssh-copy-id -i /home/tem/.ssh/id_rsa.pub tem@192.168.66.140
ssh-copy-id -i /home/tem/.ssh/id_rsa.pub tem@192.168.66.142
# 192.168.66.142
ssh-keygen -t rsa -b 2048 -f /home/tem/.ssh/id_rsa -N ""
ssh-copy-id -i /home/tem/.ssh/id_rsa.pub tem@192.168.66.140
ssh-copy-id -i /home/tem/.ssh/id_rsa.pub tem@192.168.66.141
chmod 600 /home/tem/.ssh/authorized_keys
验证互信
# 192.168.66.140
ssh tem@192.168.66.141 date
ssh tem@192.168.66.142 date
# 192.168.66.141
ssh tem@192.168.66.140 date
ssh tem@192.168.66.142 date
# 192.168.66.142
ssh tem@192.168.66.140 date
ssh tem@192.168.66.141 date
在解压后的安装包目录下,编辑 TEM 配置文件:config.yaml
global:
user: "tem" # 修改为上面互信的用户
group: "tem"
ssh_port: 22
deploy_dir: "/tem-deploy"
data_dir: "/tem-data"
arch: "amd64"
log_level: "info"
enable_tls: false
server_configs: #这里指定tem 节点的全局配置
tem_servers:
db_addresses: "192.168.66.140:4000" # 这里非常重要一点要选tem_servers.host中的一个,不要填127.0.0.1
db_u: "root"
db_pwd: ""
db_name: "test"
log_filename: "/tem-deploy/tem-server-8080/log/tem.log"
log_tem_level: "info"
log_max_size: 300
log_max_days: 30
log_max_backups: 0
tem_servers:
- host: "192.168.66.140"
port: 8080
mirror_repo: true
- host: "192.168.66.141"
port: 8080
mirror_repo: false
- host: "192.168.66.142"
port: 8080
mirror_repo: false
接着安装TEM,参照安装文档。

2.8.2 多集群管控测试
2.8.2.1 巡检体验
1.新建巡检策略

创建巡检

2.查看巡检
点开具体哪个集群


2.8.2.2 备份体验
1.创建备份


这里选择数据库备份或者表备份会出现个错误,全量备份是正常的


2.8.2.3 数据闪回体验
1.模拟误删数据
delete from sbtest1 where id = 1;
2.创建闪回

3.查看恢复情况

select * from sbtest1 where id = 1;
2.8.2.4 告警体验
1.创建告警通道

2.根据提示重载 Alertmanager 使其生效
3.添加告警规则
这个是模版默认有的告警规则tikb CPU越限超过80%则报警(如果没有则自定义添加)

4.压测[[#2.7.2.1 OLTP测试]]模拟告警

3. 平凯数据库敏捷模式优势 & 体验总结
平凯数据库敏捷模式+TEM通过提供更丰富的部署选择和简化的集群管理方式,显著降低了用户的使用门槛和运维成本。用户从一开始选择敏捷模式,不仅可以快速部署和扩展集群,还能实现平滑升级,有效避免了后续异构迁移的复杂性和风险。同时,该模式着力摆脱了传统认知中“小数据量下性能不如传统数据库”的标签,在多场景部署和轻量级应用中表现出良好的适应性。
3.1 优势
(1)快速创建集群 TEM 支持快速创建多集群,极大提升了部署效率。
(2)监控多集群 TEM 提供了直观的多集群监控视图,弥补了 Dashboard 仅支持单集群监控的不足,用户可汇总查看多集群状态并快速切换监控对象。
(3)便捷的集群管理 通过图形化界面操作集群组件,TEM 显著简化了组件添加和管理步骤。
(4)部署灵活多样 支持多种部署模式,不再仅限于分布式数据库部署,更好地适应不同业务场景需求。
(5)快速节点扩展 提供图形化节点扩展操作,流程简单、响应迅速,有效支持集群弹性扩缩容。
(6)高效处理分析型查询 列式存储引擎 TiFlash 在处理高效处理分析型查询、全表扫描和复杂聚合极其高效
3.2 不足
(1)单机读性能未达最优 单机版初始化的集群在读性能方面尚未达到最佳状态,尤其在资源有限环境下与传统数据库仍有差距。
(2)TEM 功能尚不完善 目前缺乏对 DM 集群、TiCDC 集群等组件的管理功能,功能覆盖度有待提升。
(3)部分功能存在异常 例如备份功能在实际使用中会出现一些 bug,影响用户体验和数据管理可靠性。
3.3 总结
平凯数据库敏捷模式通过TEM管理平台大幅降低了分布式数据库的使用门槛,在部署效率、集群管理和监控方面表现出明显优势。虽然单机性能和部分功能仍需完善,但其灵活的部署方式、强大的扩展能力和出色的分析查询性能,使其特别适合互联网、金融科技、物联网等行业的多种应用场景。建议在资源允许的开发测试环境、中小型生产系统及需要高效分析查询的场景中优先采用该模式,同时关注其后续版本的功能完善和性能优化。
声明:以上测试为个人测试,并非专业团队测试,用于学习讨论。可能测试方式存在错误和测试过程不够严格,希望大家能不吝赐教。