kdb+键表重放功能触发'type'错误求助
问题:KDB+ Tick RDB重启重放时触发'type错误
环境与代码
Tickerplant Schema(sym.q)
trade:([]time:`timespan$();sym:`symbol$();price:`float$();size:`long$())
RDB代码(rdb.q)
/q tick/r.q [host]:port[:usr:pwd] [host]:port[:usr:pwd] /2008.09.09 .k ->.q if[not "w"=first string .z.o;system "sleep 1"]; upd:upsert; / 获取ticker plant和历史端口,默认5010、5012 .u.x:.z.x,(count .z.x)_(":5010";":5012"); / 日终处理:保存、清空、重载hdb .u.end:{t:tables`.;t@:where `g=attr each t@\:`sym;.Q.hdpf[`$":",.u.x 1;`:.;x;`sym];@[;`sym;`g#] each t;}; / 初始化schema并从日志文件同步;切换到hdb目录(以便客户端保存执行) / 将部分表初始化为键表 .u.rep:{(.[;();:;].)each x; `sym xkey `trade; if[null first y;:()]; -11!y; system "cd ",1_-10_string first reverse y}; / 若日志目录/数据库非默认,需硬编码\cd / 连接到ticker plant获取(schema;(logcount;log)) .u.rep .(hopen `$":",.u.x 0)".u.sub[`;`];`.u `i`L)";
现象
- 发布端运行时,数据upsert正常:
q)trade sym| time price size ---| ------------------------------- ABC| 0D13:50:59.254254870 50 654
- 退出RDB进程重启,测试日志重放时触发错误:
KDB+ 4.0 2023.11.03 Copyright (C) 1993-2023 Kx Systems l64/ 6(24)core 23967MB naseef naseef-b365m-gaming-hd 127.0.1.1 EXPIRE 2024.08.14 naseef@bitwyre.com KOD #5015621 'type [3] /home/naseef/q/l64/tick/r.q:20: .u.rep: if[null first y;:()]; -11!y; ^ system "cd ",1_-10_string first reverse y}
问题分析与修复
核心原因
错误出在.u.rep函数的-11!y行,'type错误说明y的结构不符合日志重放-11!的要求:
- 原代码对
y的合法性检查不足,若tickerplant返回的(logcount;log)为空、长度异常,或log不是合法路径,执行-11!y会触发类型错误。 first reverse y是错误写法:tickerplant返回的y是(日志计数;日志文件路径),last y就是路径,无需反转;且1_-10_string截取路径的逻辑依赖固定长度,容易出错。
修复方案
1. 修正.u.rep函数,增加合法性检查并优化路径处理
.u.rep:{(.[;();:;].)each x; `sym xkey `trade; / 检查y是否为合法的(日志计数;日志路径)结构 if[null y or 2<>count y or not `string=type last y;:()]; -11!y; / 用.Q.dpth获取日志文件所在目录,替代硬编码截取 system "cd ",string .Q.dpth last y};
2. 多键表场景适配(通用化处理)
如果存在多个键表,避免硬编码初始化,可将键表配置作为参数传入:
/ 修改.u.rep支持多键表配置 .u.rep:{(.[;();:;].)each x; / z为键表配置列表,每个元素是(表名;键列) {[tbl;keycol] keycol xkey tbl} each z; if[null y or 2<>count y or not `string=type last y;:()]; -11!y; system "cd ",string .Q.dpth last y}; / 调用时传入键表配置 .u.rep .(hopen `$":",.u.x 0)".u.sub[`;`];`.u `i`L);(`trade;`sym)"
3. 前置检查tickerplant状态
重启RDB前,在tickerplant中确认日志状态:
q).u.i / 查看日志计数,需为非负整数 q).u.L / 查看日志文件路径,需为合法字符串路径
验证
修复后重启RDB,日志重放正常,键表初始化正确,多键表场景可正常适配。
内容的提问来源于stack exchange,提问作者works
相关产品推荐
相关产品推荐

