诡异的sqlite3之malformed错误(一)

在处理大规模数据时,设备报告sqlite3版本3.8.6的210MB数据库出现'malformed'错误。错误与查询条件有关,不完全匹配主键时触发全表扫描,导致问题复现。测试显示,在特定条件下能遍历更多记录,而在另一天的数据库中问题消失。可能是由于数据库自动恢复或拷贝时的事务冲突造成。
摘要由CSDN通过智能技术生成

诡异的sqlite3之malformed错误(一)

现象

  • 现场设备生成并插入大规模的数据,设备异常将数据库拉出来检查时,报告malformed错误
  • sqlite3 版本 3.8.6
  • 数据库文件大小 210 MB

定位问题

  • 数据大小

    select count(*) from DataSheet;
    /*结果*/
    950131
    
  • 主键

    primary key(ctype,id,DataTime)
    
  • 复现 (SQLite Expert)

    select * from DataSheet where id='000537719140' order by DataTime;  /*malformed*/
    select * from DataSheet where ctype=5002 and id='000537719140' order by DataTime; /*OK*/
    

    如上所述,这两条SQL语句差异只有where子句中是否含有oad条件,为什么会如此呢,先执行如下SQL比较一二:

    select * from DataSheet where id='000537719140';  /*OK*/
    select * from DataSheet order by DataTime;     /*malformed, 全表扫描*/
    
    • where子句中有ctype,id,DataTime时命中索引(主键),此时,order by DataTime对符合条件的索引排序,因此,问题不复现
    • where子句不完全匹配有ctype,id,DataTime时,未命中索引(主键),order by DataTime对符合条件的结果排序,实际上执行全表扫描,问题复现
  • 测试代码: 定位行

    char * malformed = "select rowid, ctype, id, StartTime, DataTime from DataSheet;"; /*malformed*/
    char * okayQuery = "select rowid, ctype, id, DataTime from DataSheet;"; /*OK*/
    char * sql = okayQuery;
    sqlite3_prepare_v2(db, sql, strlen(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值