注册
一套引擎如何同时承载交易与分析:DM9 TP 与 AP 混合负载架构解析及实测【#达梦数据库 #达梦同行者征文】
专栏/技术分享/ 文章详情 /

一套引擎如何同时承载交易与分析:DM9 TP 与 AP 混合负载架构解析及实测【#达梦数据库 #达梦同行者征文】

开心 2026/09/18 420 1 0
摘要

摘要

我想验证的事情很具体:在同一个 DM9 实例里,让短事务和扫描聚合同时运行,仅把订单明细从普通行存换成事务型 HUGE,空间、分析吞吐和交易延迟会发生什么变化?为避免把别的因素混进来,订单头、客户、商品和事件表始终使用普通行存,TP 线程的访问路径也保持不变。AP 线程只在两张数据完全相同的订单明细表之间切换。

测试数据包含 20 万订单和 100 万条订单明细。稳定组三次中位数显示,HUGE 事实表占用页由 7,984 降到 2,439,减少 69.45%;AP-only 场景在 15 秒内完成的查询由 86 条增加到 91 条,混合场景由 78 条增加到 82 条。此时 Mixed-row 与 Mixed-HUGE 的 TP 吞吐分别是 2,589.29 TPS 和 2,571.80 TPS,P95 为 2.044 ms 和 2.050 ms,未出现可辨识的退化。

这些结果只回答本次模型中的问题。HUGE 带来的 AP 收益约为 5%,没有达到数量级差异;TP 与 AP 混跑后,AP 完成量仍下降约一成。更值得记录的是测试方法:先验证事务能力,再保证数据等价;遇到漂移就保留原始结果并重跑;最后结合执行计划和等待事件解释数字。

一、先把问题缩小到一张事实表

“一套数据库同时跑交易和分析”听起来像产品开关,真正落到系统里却涉及几条不同的路径。订单状态更新通常通过主键命中少量数据页,提交还要等待 redo 落盘;收入统计则要扫描大量明细,随后做连接、聚合和排序。两类请求进入同一实例后,会共同使用 CPU、缓存、执行线程和 I/O 调度。

如果同时改并行度、缓存参数和表结构,即使指标变好,也很难说清是哪一项起作用。所以这次我只改变订单明细的物理组织。订单头 ORDERS、事件表 ORDER_EVENTS、客户表和商品表保持普通行存,TP 的读、更新和提交逻辑全程不变。分析线程分别查询 ORDER_LINES_ROW 与 ORDER_LINES_HUGE,上层 SQL 保持一致。

dm9_architecture.png

这样的拆法也更接近常见订单系统:状态变化集中在订单头,明细通常以追加和查询为主。它不能代表所有 HTAP 架构,却能把一次对比限制在能够解释的范围内。

二、事务型 HUGE 先做能力探测

HUGE 能更新并不等于适合频繁更新

安装包中的《DM9-SQL语言使用手册》把 HUGE 表定义为列式组织,WITH DELTA 用于事务型 HUGE。当前实例的 HUGE_WITH_DELTA=1、RLOG_GEN_FOR_HUGE=1 也符合这个方向,但我没有直接拿参数当结论。

正式建表前,我先创建了一张小型探测表,依次做插入、提交、更新、回滚和查询。更新后的金额在回滚后恢复,说明这套实例上的事务链路确实生效。随后才建立百万行事实表,核心定义如下:

CREATE HUGE TABLE ORDER_LINES_HUGE ( ORDER_ID BIGINT NOT NULL, LINE_NUMBER INT NOT NULL, PRODUCT_ID BIGINT NOT NULL, QUANTITY INT NOT NULL, UNIT_PRICE DECIMAL(12,2) NOT NULL, PRIMARY KEY (ORDER_ID, LINE_NUMBER) ) STORAGE( SECTION(8192), STAT SYNCHRONOUS, WITH DELTA, ON MAIN );

这里有几个容易在建模时忽略的限制。HUGE 不能建立聚集索引,但可以建立二级索引;主键或唯一约束是否执行唯一性检查还受 HUGE_UNIQUE_CHECK 控制;增删改积累到一定程度后,还要考虑数据重整。WITH DELTA 解决的是列存参与事务的问题,并没有消除高频随机更新的维护代价。

并行能力暂时不纳入比较

本机参数为 PARALLEL_POLICY=0、MAX_PARALLEL_DEGREE=1。DM9 支持会话级并行策略,但本轮没有为了提高 AP 数字临时调大并行度。原因很简单:并行会同时影响 CPU 调度、工作内存和 TP 尾延迟,一旦加入,表组织就不再是唯一变量。并行能力应放到另一组容量实验中单独测试。

监控 SQL 先以实机字段为准

ENABLE_MONITOR=1 后,可以查询 V$ACTIVE_SESSION_HISTORY、V$SYSTEM_EVENT 和 V$SESSION_EVENT。我第一次写采集 SQL 时就遇到了字段错误:当前版本的 V$SYSTEM_EVENT 使用 EVENT、TIME_WAITED_MICRO、AVERAGE_WAIT_MICRO,会话视图使用 SESSION#,和我按既有印象写出的 NAME、SESS_ID 不同。

这个报错没有技术难度,却很有代表性。后来我把 DESC 视图放到采集脚本之前,确认字段后再冻结 SQL。监控视图能够访问,不代表不同版本的列名可以直接照搬。

三、数据相同,性能对比才有意义

测试环境

项目 配置
宿主形态 Windows 上的 WSL2,Ubuntu 22.04.5 LTS
内核 6.6.87.2-microsoft-standard-WSL2
资源 12 vCPU、15 GiB 内存、4 GiB Swap
DM9 DM Database Server 64 V9,安装器元数据 9.1.0.26
数据库 HTAP,端口 5237,16 KiB 页,UTF-8,大小写敏感
缓冲区 BUFFER=4096 MiB
工作线程 WORKER_THREADS=16,TASK_THREADS=16
分析参数 OLAP_FLAG=2,PARALLEL_POLICY=0,MAX_PARALLEL_DEGREE=1
监控 ENABLE_MONITOR=1

安装运行在 WSL2 中。测试时还有一个环境细节:从 Windows 侧访问 127.0.0.1:5237 会超时,改用 WSL 发行版地址后连接正常。为了不让连接路径影响对比,后续客户端全部使用同一个 WSL 地址。这个现象只记录为 WSL 网络限制,不归因到 DM9。

装载后做四项校验

数据生成器固定使用种子 20260915,生成 20,000 个客户、5,000 个商品和 200,000 笔订单,每笔订单 5 条明细。普通表和 HUGE 表各装载 1,000,000 条明细,整个装载过程耗时 102.935 秒。

我没有只比较 COUNT(*)。装载结束后还核对了数量合计、金额合计和订单 ID 边界。两张事实表均为 1,000,000 行,数量合计 4,500,737,金额合计 1,127,887,646.99,订单 ID 从 1 到 200,000。四项全部一致后,才进入压测。

五个场景共用同一套负载

TP 由 4 个线程执行短事务:按随机主键读取订单状态、更新状态、写入一条订单事件,然后提交;发生异常时回滚并计入失败。采集指标包括 TPS、失败率和 P50/P95/P99 延迟。

AP 线程循环执行三类查询,并完整读取结果集:按月聚合收入、按商品类别聚合收入、客户收入 Top 20。三条 SQL 都要访问事实表,其中月收入和客户 Top 20 还会连接订单或客户维表。

测试分为 TP-only、AP-row、AP-HUGE、Mixed-row、Mixed-HUGE 五组。每组正式测量 15 秒,之前执行 5 秒同场景暖机。正式测试轮换场景顺序并重复三次,最终报告三次中位数,所有 JSON 原始结果均保留。

四、最初三轮为什么没有进入统计

第一次跑完时,数字看上去越来越好。以 TP-only 为例,同一场景从约 419 TPS 一路升到 1,079 TPS,混合场景也随时间抬升。若只采用最后一次,图表会更漂亮,但那很可能把批量装载后的后台刷盘和缓存稳定过程算成了数据库能力。

因此我没有从三轮里挑一个顺眼的结果。初始 JSON 被单独保留,随后执行 SELECT CHECKPOINT(100) 主动刷出脏页,再按相同顺序重新跑三轮。稳定组的 Mixed-row 分别为 2,613.7、2,589.3、2,562.2 TPS;Mixed-HUGE 分别为 2,532.5、2,667.8、2,571.8 TPS。它们仍有波动,但已经能够进行中位数比较。

这段过程改变了我对基准测试的看法。一次查询跑通只是功能验证;要拿数字解释架构,必须先确认测量窗口里的系统状态是否可比。异常轮次不应被删除,它们本身就是判断正式结果是否可信的依据。

五、结果并不夸张,但可以解释

dm9_results.png

HUGE 表页减少 69.45%

TABLE_USED_SPACE 返回表对象占用页数。普通明细表占 7,984 页,HUGE 表占 2,439 页;按 16 KiB 页计算,约从 124.8 MiB 降到 38.1 MiB。

69.45% 与达梦发布信息中的“节省 70% 存储”接近,但本次数据只有 5 列数值型明细,基数和压缩策略也固定。字符串长度、重复度、增量区规模和更新频率变化后,比例都会变化,因此不能把这个数字套到任意业务表上。

AP-only 完成量增加约 5.8%

指标(三次中位数) 普通行存 HUGE 变化
15 秒完成查询数 86 91 +5.8%
月收入聚合中位耗时 192.94 ms 184.76 ms -4.2%
品类收入聚合中位耗时 139.72 ms 125.08 ms -10.5%
客户 Top 20 中位耗时 175.98 ms 168.99 ms -4.0%

执行计划提供了较清楚的解释线索。普通事实表使用 CSCN2 扫描,HUGE 使用 HFSCN2;两边上层都保留 HASH2 连接、HAGR2 聚合和排序。连接算法没有随存储类型改变,主要差异落在事实表扫描路径和数据占用上。

三类查询里,品类聚合改善最大。它只连接 5,000 行商品维表,扫描百万行事实表在总成本中的占比更高。客户 Top 20 还要连接 20 万订单和 2 万客户,维表访问与连接成本稀释了扫描收益。这组差异提醒我,迁移判断需要看执行计划中的主导算子,不能仅凭“这是分析 SQL”就决定改用 HUGE。

混合运行时 AP 仍会受到干扰

Mixed-row 在 15 秒内完成 78 条 AP 查询,Mixed-HUGE 完成 82 条,提升 5.13%。然而和各自 AP-only 基线相比,完成量分别下降 9.30% 和 9.89%。换了物理组织以后,CPU、执行线程、缓存和日志相关调度仍然共享,资源竞争并没有消失。

混合场景中的 TP 指标如下:

指标(三次中位数) Mixed-row Mixed-HUGE 变化
吞吐 2,589.29 TPS 2,571.80 TPS -0.68%
P50 1.417 ms 1.429 ms +0.012 ms
P95 2.044 ms 2.050 ms +0.006 ms
P99 2.915 ms 2.811 ms -0.104 ms
失败率 0 0 持平

TP 全程只更新行存订单头和事件表,HUGE 只承担分析扫描。在这个前提下,-0.68% 可以理解为当前精度下没有观察到实质差异。它不能证明高频更新 HUGE 事实表同样没有成本。

TP-only 反而更慢,暂时只能记为现象

TP-only 的中位数只有 1,120.32 TPS,P95 为 6.379 ms,明显弱于两个混合场景。等待增量里,rlog flush wait 都是事务场景的首要等待;其单次等待中位平均值在 TP-only 约为 1,397 微秒,在 Mixed-row 和 Mixed-HUGE 中约为 751、749 微秒。

更有效的组提交、调度节奏或缓存交互都可能产生类似现象,但现有数据没有证明其中任何一个原因。我目前只接受两条结论:这个反常结果在稳定三轮中重复出现;redo 刷盘单次平均等待同步下降。至于“运行 AP 能提高 TP 性能”,本次实验完全不足以支持。

若继续验证,我会固定提交批次,扩大 TP 并发,采集日志刷盘时间线,并换到裸机或独立 Linux 主机复测。动态视图在这里的作用也体现出来了:它没有直接给出答案,却把一个奇怪数字变成了可以继续实验的假设。

六、把测试方法带回生产设计

这次实验最直接的启发,是不要急着按“交易系统”和“分析系统”给整套业务贴标签。表的访问方式更值得关注。订单头、账户状态、状态机等高频点查和更新适合留在普通行存;追加较多、扫描聚合占主导、列投影相对稳定的明细表,才是 HUGE 的候选对象。

迁移前后必须做数据等价校验,并为同一条 SQL 保存 EXPLAIN。如果连接顺序、估算基数和扫描方式同时变化,就很难把收益归到某一种存储组织。本次两类计划的上层结构基本相同,只在事实表扫描上出现 CSCN2 与 HFSCN2 的区别,所以解释相对简单。

统计信息也要进入发布流程。本实验对普通表调用 DBMS_STATS.GATHER_TABLE_STATS,HUGE 使用 STAT SYNCHRONOUS。生产环境需要根据写入强度选择统计策略,并在变更前后检查执行计划,不能等查询变慢后才临时补收集。

并行度则要和业务并发一起测。一个 8 路并行查询与 8 个分析会话各跑 8 路并行,对调度器和工作内存的压力完全不同。比较稳妥的办法是固定 TP 并发,逐步增加 AP 会话数和并行度,同时观察 TP P95/P99、AP 完成量、工作内存和等待类别。一旦尾延迟越过业务 SLO,就要回退并行度或考虑隔离。

事务型 HUGE 还需要维护窗口。增量机制支持更新,也会随着长期增删改积累重整成本。上线前应把增量数据比例、查询计划、重整时的锁与日志开销纳入观察。对于持续高频随机更新的事实表,普通行存或冷热分层通常更容易控制风险。

排障时,我会优先沿着业务指标、活动会话、等待事件和执行计划往下查,而不只看 CPU 利用率。本次 TP 的主要等待是 rlog flush wait;AP-only 的系统等待增量很低,差异更多体现在扫描和执行耗时。CPU 不高并不能排除提交或 I/O 路径上的等待。

七、适用范围和本次测试的限制

这套混合物理设计适合订单头或账户状态频繁更新、明细以追加和聚合为主的模型。分析可以与交易共享实例,但必须有明确的尾延迟和查询完成量目标,团队也要愿意维护统计信息、计划基线和 HUGE 重整流程。

如果事实明细本身持续随机更新,AP 需要很高并行度却没有资源隔离,TP 的 P99 极为敏感,或者分析必须在故障域、权限域上与交易彻底隔离,就不宜照搬这次做法。读写分离、独立分析实例或数据同步架构可能更合适。

本次测试运行在 WSL2 而非裸机,宿主文件缓存使磁盘字节计数无法等价为设备 IOPS。单实例、12 vCPU、15 GiB 内存也不代表生产规模;每个场景只有一个 AP 会话,测量窗口只有 15 秒;并行没有启用,故障切换、备机读取和事务型 HUGE 的长期增量膨胀也未覆盖。因此本文给出的是验证方法和当前环境中的趋势,不是容量承诺。

结语

跑完这组实验后,我没有得到“HUGE 一定更快”这样简单的答案。它在这张百万行数值型事实表上明显节省了空间,AP 完成量提高约 5%;只要 TP 仍走独立的行存订单路径,混合场景下的交易吞吐和 P95 也基本持平。与此同时,混跑使 AP 完成量损失约一成,说明同一实例中的资源竞争依然存在。

对我而言,最有价值的是中间那些不够顺利的部分:监控字段先报错,初始三轮持续漂移,TP-only 又出现了反直觉结果。把这些现象保留下来,再通过 DESC、CHECKPOINT、执行计划和等待事件逐步缩小解释范围,最终得到的结论虽然克制,却比一组孤立的漂亮数字更可复用。

#达梦数据库 #达梦同行者征文

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服