简介:专门适配达梦数据库的BenchmarkSQL基准测试工具包,面向数据库管理员、性能测试工程师及国产数据库选型团队。该版本已针对达梦完成兼容优化,支持配置TPC-C类混合事务负载,可对达梦、Oracle、MySQL、PostgreSQL等主流数据库横向对比,量化评估处理能力与响应表现。包内共94个文件,以Java类、SQL脚本、Shell启动脚本、JAR依赖包和Properties配置为主,可直接运行测试流程脚本,并附带了达梦专属的配置文件和测试语句,配合依赖库与日志组件,解压后即可调整并发、时长等参数运行。压缩包仅3.77MB,轻量易用。资源已有799人学习使用,包含完整目录结构、README及常见问题说明,可避开环境配置与执行中的常见坑点。对于正在做达梦数据库选型或性能调优的团队,这份工具能显著降低基准测试搭建门槛,覆盖从建库、装载数据到运行负载、生成报告的完整环节,快速产出可复现的对比数据,是评估达梦性能的实用选择。
1. 拿到BenchmarkSQL达梦版:先搞清楚它到底帮你解决什么
做数据库选型或者性能验收的人,迟早会碰到一个尴尬场景:手里有台达梦数据库,领导让出个压测报告,但翻遍网上的压测工具教程,全是针对MySQL或PostgreSQL的,达梦连驱动都没法直接加载。BenchmarkSQL支持达梦数据库版就是把这条断头路接上——它是在开源的BenchmarkSQL 5.0基础上,补齐了达梦方言、驱动加载和建表脚本,让你能用同一套TPC-C标准负载去测达梦,也能拿它跟Oracle、PostgreSQL的测试结果放在一张表里对比。这篇文章会把这份资源拆开,从配置文件到压测命令,再到我实际跑达梦时踩过的坑,逐个说清楚。适合刚接触达梦、需要出性能数据的DBA,以及要在多个数据库之间做横向对比的测试工程师。
2. 理解BenchmarkSQL达梦版:TPC-C模型、资源组成与适配原理
2.1 TPC-C基准模型:为什么它是数据库压测的事实标准
BenchmarkSQL的实现基础是TPC-C标准,这个标准模拟的是一个批发商的订单处理系统,包含仓库、区域、客户、订单、订单明细等表。压测过程中会执行五种事务:新订单、支付、订单查询、发货和库存查询,其中新订单事务占45%权重。一个完整的TPC-C测试要满足事务混合比例、响应时间、主键外键约束等多个要求,正是这些约束让测试结果能真实反映数据库在混合OLTP负载下的表现。
理解这个模型对跑达梦版很重要,因为达梦适配版做的事就是让这些事务能在达梦上原样跑通。比如sql.dameng目录下的建表和索引脚本,就是按照TPC-C的表结构用达梦的SQL方言重写的。你不需要自己去设计压测场景,BenchmarkSQL已经把这套业务模型封装好了。运行时,每个终端(terminal)模拟一个用户,按照设定的事务混合比例生成请求,工具会记录每笔事务的响应时间、每类事务的成功/失败次数,最后汇总成tpmC(每分钟新订单事务数)和TPS。
实践里我一般把TPC-C结果理解成一个“公平秤”:它不偏向任何数据库的特定优化,所有被测试的数据库都跑同样的SQL、同样的数据量、同样的并发模型。所以当你拿达梦版测出来的数字和网上公开的PostgreSQL TPC-C数据对比时,前提是warehouses数、terminals数、rampup时间这些参数一致,否则数字高低不具备参考意义。
2.2 达梦版资源组成:从props.dm到sql.dameng的关键文件
解压benchmarksql-5.0支持达梦版之后,目录结构和原版BenchmarkSQL大体相同,多了几个专门为达梦准备的文件。最重要的有两个:props.dm和sql.dameng目录。props.dm是达梦版的配置入口,所有连接信息、并发数、数据量都在这里改;sql.dameng目录里放的是达梦的建表、建索引、存储过程脚本,因为达梦的SQL方言和PostgreSQL/Oracle有细微差别,比如自增列写法、字符串拼接函数、分页语法等,所以需要单独维护一套脚本。
runBenchmark.sh是压测主入口,它读取props.dm里的参数,启动终端模拟压测;runDatabaseBuild.sh负责建库,会先执行sql.common里的公共表结构脚本和sql.dameng里的达梦专用脚本,再按warehouses数生成测试数据;runDatabaseDestroy.sh用于清理测试数据,跑完一轮压测后重置环境。
lib目录里除了达梦的JDBC驱动,我还注意到保留了log4j-1.2.17.jar和apache-log4j-extras-1.1.jar这两个日志库,说明达梦版的日志记录逻辑还是沿用原版结构。用的时候直接在props.dm里指定driver=dm.jdbc.driver.DmDriver和对应的jdbc url,比如jdbc:dm://127.0.0.1:5236。达梦默认端口是5236,不是MySQL的3306,也不是Oracle的1521,这一点第一跑的人经常会下意识填错。
2.3 达梦适配的三个关键改动:驱动、方言与事务控制
我拆过原版BenchmarkSQL的源码,对比达梦版之后,发现适配工作主要集中在三个层面。第一个是驱动接入,原版BenchmarkSQL通过Class.forName动态加载驱动,props里写什么驱动类名它就加载什么,所以达梦版做得最基础的适配就是提供一个可用的达梦JDBC驱动,并存放到lib目录。第二个是SQL方言,这一点才是真正的坑。达梦兼容Oracle语法,但又不是完全一致,比如达梦的CREATE TABLE支持IDENTITY自增列,但也兼容Oracle的SEQUENCE+TRIGGER方案,sql.dameng里选的哪种方式会直接影响TPC-C装载数据的耗时。
第三点是事务控制。TPC-C测试对事务隔离级别有要求,达梦默认的隔离级别和PostgreSQL不完全一样,props.dm里如果没设对,跑出来的tpmC会波动很大。我做压测时会把isolationLevel=TRANSACTION_READ_COMMITTED显式写出来,避免达梦实例级配置干扰测试结果。这三个适配都是“看不见但决定成败”的部分,配置不对的时候工具能启动、终端也能连上,但测试跑到一半会出现死锁或者数据不一致报错。
提示:收到压缩包后,先检查
props.dm里driver这一行是否为dm.jdbc.driver.DmDriver,如果不是,说明你拿到的版本驱动路径可能被改过,需要先确认lib目录里的驱动jar包名,再调整driver类名。
3. 把达梦压测跑起来:配置、建库与执行的三步法
3.1 第一步:改props.dm配置,决定测试规模与负载模型
配置是压测前最需要花心思的环节,props.dm里的每一项参数都直接影响测试结果的有效性。最基本的连接配置包括:
driver=dm.jdbc.driver.DmDriver conn=jdbc:dm://127.0.0.1:5236 user=benchmarksql password=benchmarksql warehouses=10 loadWorkers=4 terminals=8 runMins=5 limitTxnsPerMin=0 terminalWarehouseFixed=true isolationLevel=TRANSACTION_READ_COMMITTED这段配置里,warehouses=10代表生成10个仓库的数据量,TPC-C标准里每个仓库约占用100MB左右空间,10个仓库大约是1GB,这对测试达梦的装载速度和索引维护能力有参考价值。loadWorkers=4是并行装载数据的线程数,达梦在多核服务器上可以调到8或16,但如果是开发机测试,4比较稳妥,因为装载数据时并发太高容易触发锁等待。terminals=8是模拟用户数,也就是并发连接数,实际要按业务峰值并发量来设,而不是越大越好。
runMins=5是测试持续时间,单位是分钟。一般我建议至少跑10分钟以上,5分钟的数据波动太大,尤其达梦在第一次跑的时候有buffer预热问题,前一两分钟tpmC是爬坡状态,5分钟可能刚好爬到平台期就结束了,结果偏保守。limitTxnsPerMin=0表示不限制每分钟事务数,保留0即可,如果设置了限制,测试结果就会被人工“封顶”,失去参考意义。terminalWarehouseFixed=true的含义是每个终端固定访问一个仓库,这模拟的是真实业务中用户通常只操作自己所属仓库的场景;如果改成false,所有终端随机访问所有仓库,会放大锁竞争,tpmC数字会明显下降。
3.2 第二步:建库装载数据,runDatabaseBuild.sh的完整流程
配置改完后,第一步要执行的是建库脚本。在达梦上跑之前,有两个前置操作必须完成:在达梦中创建一个用于测试的业务用户,并给这个用户足够的表空间权限;确认该用户有创建表、索引、序列的权限。否则runDatabaseBuild.sh会在执行到中途时报权限错误,这时候已经创建的表和序列会残留,重跑时得先清理。
# 在达梦中先执行,创建压测用的用户(也可以在disql里操作) CREATE USER benchmarksql IDENTIFIED BY benchmarksql; GRANT DBA TO benchmarksql;cd benchmarksql-5.0 ./runDatabaseBuild.sh props.dm执行runDatabaseBuild.sh有一个值得注意的细节:它是一次性完成建表、建索引、装载数据三个动作的脚本。日志输出里会看到先执行sql.common里的公共脚本,再执行sql.dameng里的达梦专用脚本,最后通过loadWorkers并行插入数据。装载完成后,可以用一个简单的SQL验证数据量:
SELECT COUNT(*) FROM warehouse; SELECT COUNT(*) FROM customer;达梦版的仓库表数据量应该是warehouses参数的值乘以1,customer表是warehouses乘以30000。比如10个仓库,warehouse表应该有10行,customer表应该有300000行。这个验证步骤很多人省略,但数据量不对会导致后面压测的SQL执行计划完全不可比。
有一点需要特别提醒:如果中途建库失败,不能直接重跑runDatabaseBuild.sh,因为表已经存在,脚本里没有DROP TABLE IF EXISTS的容错处理(至少我拆的这版没有),所以必须先执行runDatabaseDestroy.sh清理一遍。这是和MySQL版的一个显著差异,MySQL版会先drop再create,达梦版更依赖用户手动控制流程。
3.3 第三步:正式压测与清理,runBenchmark.sh和runDatabaseDestroy.sh
数据装载完成后就可以跑正式压测了。命令很简单:
./runBenchmark.sh props.dm压测启动后,终端会输出两类信息:一类是每笔事务的实时日志,包括事务类型、响应时间、是否成功;另一类是每30秒打印一次的阶段性汇总。跑的过程中不要动数据库、不要手工执行查询,否则这些外部操作会占用达梦的CPU和I/O资源,拉低tpmC。跑完10分钟,脚本会在report目录下生成一个带时间戳的目录,里面是完整的测试报告。
压测完成后的清理同样重要。跑完一次测试,数据库里会有大量测试数据,下轮测试要在干净的数据集上跑,这时执行:
./runDatabaseDestroy.sh props.dm这个脚本会按表顺序删除测试数据,并清理序列。执行完后可以用SELECT COUNT(*) FROM orders;确认订单表已经清空。如果清理时报外键约束错误,那是因为删除顺序不对——达梦的外键约束检查比PostgreSQL更严格,我遇到过一次,后面在避坑章节细讲。
注意:
runMins和runTxnsPerTerminal是互斥参数,手册里写的是两者设置一个即可。如果两个都设置了,工具会以先达到的那个条件为准结束测试,这会导致测试时长和你预期不一致。
4. 测试报告怎么读:从tpmC到响应时间分布的几个关键指标
4.1 报告文件结构与核心数字:tpmC、TPS、平均响应时间
压测结束后,report目录下生成的时间戳文件夹里,包含一个result目录和多个CSV文件。result目录下的runResult.txt是最后的汇总报告,打开后先看tpmC这个数字。TPC-C标准规定tpmC只统计新订单事务的成功完成数,单位是每分钟。所以如果报告显示5032.83 tpmC,意思是每分钟处理约5032个新订单事务。这个数字是横向对比达梦与其他数据库性能的核心指标。
除了tpmC,还要关注总TPS和事务成功率。总TPS是每分钟所有类型事务的总数除以60,跑10分钟的话,这个数字等于总事务数除以600秒。事务成功率如果低于99%,说明数据库在压力下出现大量回滚或死锁,tpmC高也没有意义。注意看Measured tpmC和Measured tpmTOTAL两个字段,tpmTOTAL是包含所有事务类型的总吞吐,tpmC只是其中的新订单部分。
我平时拿到报告后,先看三个数:tpmC、平均响应时间、第90百分位响应时间。平均响应时间具有迷惑性,因为TPC-C混合负载里,支付事务和订单查询事务明显快于新订单事务,平均时长被快事务拉低。所以更值得关注的是90th percentile latency,达梦在压力增大时这个数字的上升斜率比平均值更陡,如果90分位超过200毫秒,说明延迟已经出现明显拐点,系统接近瓶颈。
4.2 用事务明细CSV定位性能瓶颈
报告的data目录下有一个transaction_data.csv,里面记录了每一笔事务的类型、开始时间、耗时、终端编号和成功状态。这个文件是定位瓶颈的原始依据,比汇总报告信息量更大。分析的时候,我习惯用awk或Excel数据透视表按事务类型汇总:
awk -F, '{print $2}' transaction_data.csv | sort | uniq -c | sort -rn# 按事务类型统计平均耗时和数量 awk -F, '{sum[$2]+=$3; cnt[$2]++} END{for(k in sum) print k, cnt[k], sum[k]/cnt[k]}' transaction_data.csv | sort -k2 -rn第一段命令统计每种事务类型的发生次数,正常情况下新订单事务数量应该占45%左右;第二段命令计算每种事务的平均耗时,NEW_ORDER如果远高于其他类型,说明达梦在订单相关查询上还有优化空间,可能是复合索引缺失,也可能是数据库参数没调。这些细节是报告里的tpmC数字无法体现的,但恰恰是后续调优的抓手。
如果发现事务失败记录(status字段不为0),需要重点排查失败原因。常见失败包括死锁、超时、违反约束三类。死锁和超时通常说明并发参数设置偏高,或者达梦的锁等待超时时间太短;违反约束则要回到sql.dameng里的建表脚本检查,可能是外键约束在数据装载阶段就有问题。
4.3 如何判断达梦版的测试结果是否可信
拿到一个高tpmC值,先别急着高兴,有几个校验点能判断测试结果是否注水或者失真。首先是看Measured tpmC和Required tpmC的关系,TPC-C标准要求被测系统在测试期间必须满足“90%的新订单事务响应时间不超过5秒”的要求,如果报告显示响应时间超过5秒的事务占比超过10%,那这个tpmC就是不合规的,不能用来横向对比。
其次看终端数量与tpmC的比值。单个终端的tpmC一般有合理区间,10个仓库8个终端跑出5000 tpmC是合理的,但如果8个终端跑出50000 tpmC,就要怀疑是不是warehouses数设置过低导致数据全部命中内存,或者达梦配置里的buffer pool大得异常,使得工作集完全驻留内存。这种测试结果只能说明内存型性能,不能代表磁盘型真实负载。
最后要交叉验证CPU利用率。达梦服务器在压测期间的CPU使用率如果低于70%,说明数据库没有被充分压满,这个测试规模不够,需要增加终端或仓库数。CPU打满但tpmC上不去,才是数据库自身的瓶颈;CPU不满tpmC也上不去,问题多半出在配置或并发模型上。
提示:同一份报告里,如果
New Order事务的90分位响应时间在测试后5分钟内是前5分钟的两倍以上,说明测试期间发生了buffer pool饱和,建议加长rampup时间再跑一次。达梦版的rampup时长在props.dm里通过reportDirectory前的时间戳间接体现,如果你想控制预热时长,需要在runBenchmark.sh里调整终止逻辑。
5. 达梦版避坑与常见问题:五个真实踩坑记录
5.1 坑一:连接报错“网络通信异常”,端口填错不自知
现象:执行runBenchmark.sh后,终端日志里出现java.sql.SQLException: 网络通信异常或Connection refused,工具立即退出。
原因:达梦数据库默认监听端口是5236,不是1521也不是3306。很多从Oracle转过来的测试人员会条件反射填1521,从MySQL转过来的填3306,导致JDBC连接被拒。另外,第一次装达梦时会同时启动一个实例和多个服务,如果只启动了服务管理器但没有启动数据库实例,即使端口写对也连不上。
解决:先用达梦自带的disql工具验证可达性,再改props.dm:
# 在达梦服务器上确认监听状态 netstat -an | grep 5236conn=jdbc:dm://127.0.0.1:5236如果端口确认是5236且实例已启动,仍然报网络通信异常,需要检查达梦的dm.ini里的PORT_NUM配置,有些环境安装时被自定义为5237或其他值,以实际监听为准。
5.2 坑二:建库时表已存在导致脚本中断
现象:runDatabaseBuild.sh执行到一半报Table [CUSTOMER] already exists或试图创建已存在的对象,脚本终止。
原因:上一轮建库失败或者已经跑过一次建库,没有执行runDatabaseDestroy.sh就直接重跑建库脚本。BenchmarkSQL达梦版的建表脚本没有做DROP TABLE IF EXISTS的幂等处理,表存在就直接报错。
解决:每次重跑建库前,先强制清理一轮,不要有侥幸心理:
./runDatabaseDestroy.sh props.dm如果destroy脚本本身也报错,原因是表间外键约束导致删除顺序冲突,可以登录disql手动按照子表到父表的顺序删除,或者直接drop掉整个业务用户再重建:
DROP USER benchmarksql CASCADE; CREATE USER benchmarksql IDENTIFIED BY benchmarksql; GRANT DBA TO benchmarksql;从那以后我每次重跑建库之前,都会强制走一遍这条清理流程,一分钟的事,省掉的可能是半小时的排错时间。
5.3 坑三:装载数据极慢,loadWorkers设置不当
现象:warehouses=10的数据,loadWorkers=1时跑了将近40分钟,loadWorkers=16时不但没变快,反而出现大量锁等待日志,甚至进程卡死。
原因:loadWorkers是并行装载的线程数,但达梦的表空间管理和行锁机制决定了并发插入同一个表时锁竞争非常明显,worker数超过一定阈值后,争抢加剧反而拖慢整体速度。
解决:达梦版在开发机上我一般设4到8,生产服务器可以尝试16并观察锁等待日志。另外warehouses数不是越高越好,10个仓库大约生成1GB数据,如果没有特殊需求,做功能验证用3~5个仓库足够,压测时长和装载时间都会大幅缩短。如果确实要跑大规格,建议分阶段:先loadWorkers=8跑通流程,再调整到16做正式压测。
5.4 坑四:压测期间出现死锁,达梦报“锁定冲突”
现象:压测进行到中间阶段,运行日志里连续出现Deadlock detected或锁定超时,随后部分终端退出,结果报告显示事务成功率掉到95%以下。
原因:达梦的锁等待超时参数默认值偏保守,在高并发混合事务下,支付事务和新订单事务更新同一行时,等待时间超过阈值就直接报锁定冲突,而不是通过排队消化并发。
解决:在达梦服务端调整锁超时参数,再重跑。达梦的dm.ini里找LOCK_TIMEOUT(单位是毫秒),我一般调到15000或30000,同时把DEADLOCK_CHECK_INTERVAL调小一点让死锁检测更敏感。改完后重启达梦服务生效:
LOCK_TIMEOUT = 30000 DEADLOCK_CHECK_INTERVAL = 500这个调整不影响BenchmarkSQL侧的配置,但需要数据库管理员权限。在应用侧,也可以把props.dm里的terminals降一半先验证是否仍然出现死锁,如果降了之后死锁消失,说明原并发数超过了达梦实例的锁处理能力。
5.5 坑五:测试结果tpmC偏高但报告被判定无效,响应时间超阈值
现象:跑出来的tpmC数字很好看,但仔细读报告发现新订单事务的平均响应时间或90分位响应时间超过5秒,按TPC-C合规标准就是无效测试。
原因:终端数设置过高导致系统过载;或者机器配置本身性能不够,在并发压力下事务排队时间过长。还有一种情况是达梦的SQL优化器没有走预期索引,新订单事务中涉及的多表关联查询执行计划是全表扫描。
解决:降低terminals数直到响应时间95分位降到5秒以内;同时用达梦的EXPLAIN命令查看NEW_ORDER事务涉及的SQL执行计划,确认用了主键和索引字段,没有全表扫描。如果执行计划有问题,需要回到sql.dameng里的建索引脚本,检查是否所有外键列都有对应索引。TPC-C标准里的CUSTOMER表按C_W_ID, C_D_ID, C_LAST查询,这个组合索引如果没建,新订单事务在客户匹配阶段就会大量扫描。
注意:不要因为追求tpmC好看而牺牲合规性。一份响应时间超标的报告,在数据库选型答辩或者采购验收场景下是没有说服力的,必须保证tpmC和延迟两个指标同时合规。
6. 压测结束后的最后一公里:验证结果可复现性的三个习惯
压测报告中tpmC数字漂亮,这只是第一步。真正让结果可信的是可复现性——同一份配置和同一套数据,连续跑三轮,tpmC波动应该在合理范围内。很多人在数据库调优时被“单次测试结果”误导,调了参数之后tpmC涨了20%,实际是测试噪声,不是参数生效。
我现在的标准流程是:第一轮跑完,记录tpmC和90分位延迟;然后执行runDatabaseDestroy.sh清空数据,再重新建库、再跑一轮。两轮结果之间tpmC偏差超过10%就说明数据装载或者预热过程有问题,需要排查。三轮测试中如果有异常高或异常低的一轮,不要取平均值掩盖它,而是去查那一轮的日志——很可能是测试期间有后台任务抢占资源造成的。
第二个习惯是保存完整的测试环境快照,包括达梦的dm.ini关键参数、props.dm的完整内容、服务器CPU和内存配置,以及测试时间段是什么时候。这个快照不是为了做给公司看的,而是三个月后回看这份测试报告时,能重建出当时的全部前置条件。达梦的参数版本之间差异很大,同一个BenchmarkSQL达梦版跑出来的结果,在DM8和DM9上可能差20%,不记录这些信息,报告等于白做。
最后一个建议是横向对比时务必锁定同一套参数。拿达梦的tpmC和PostgreSQL的tpmC对比,warehouses、terminals、缓冲池大小必须一致,否则数字的大小关系没有任何实际意义。我一般会先在同一台机器上分别跑两个基准的默认配置,观察它们各自的最优区间,再在各自最优区间内做横向比较——这样对达梦和PostgreSQL都公平。
从那以后,我每次跑完一轮压测,不管结果好坏,都强制走一遍“销毁→重建→复跑”循环,并且把props.dm文件和达梦服务端的关键参数值留档。这个过程耗尽的时间不过多十分钟,但换来的是一份能在答辩现场站得住脚的测试结论。希望读到这里的人也能少走一些我走过的弯路,毕竟这类工具本身不复杂,复杂的是参数背后的边界条件和数据库特性。希望帮到你。
本文还有配套的精品资源,点击获取