诡异的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(sql), &stmt, NULL);
    ncols = sqlite3_column_count(stmt);
    int rowno = 0;
    do {rc = sqlite3_step(stmt);switch (rc) {case SQLITE_ROW:  break;case SQLITE_DONE: rowno = -100;  break;default:          fprintf(stderr, "rowno = %d, sqlite3 error %d\n", rowno, rc);  break;}if (rowno >= 0) { rowno++; }
    }
    while (rowno >= 0);
    sqlite3_finalize(stmt);
    
    • sql = okayQuery,共查询950131(rowno:950130)条记录,然后SQLITE_DONE结束
    • sql = malformed,取第950300条记录时报告错误11 (SQLITE_CORRUPT)
      • 查询正常时,只能遍历950131(rowno:950130)条记录
      • 查询异常时,居然遍历到950300(rowno:950301)条记录时出错!
  • 测试代码: 定位时间

    char * malformed = "select rowid, ctype, id, DataTime, StartTime from DataSheet;";
    char * okayQuery = "select rowid, ctype, id, DataTime from DataSheet;";
    char * sql = malformed;
    sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL);
    ncols = sqlite3_column_count(stmt);
    int rowno = 0;
    do {rc = sqlite3_step(stmt);switch (rc) {case SQLITE_ROW:if (rowno >= 950129 && rowno <= 950301/* 950300 */) {rowid     = sqlite3_column_int(stmt, 0);ctype  = (char*)sqlite3_column_text(stmt, 1);id = (char*)sqlite3_column_text(stmt, 2);colltime = (char *)sqlite3_column_text(stmt, 3);fprintf(stderr, "rowno: %d, rowid: %i, ctype: %s, id:%s, time:%s\n", rowno, rowid, (ctype?ctype:snull),(id?id:snull), (colltime?colltime:snull));}break;case SQLITE_DONE:    rowno = -100;  break;default:          fprintf(stderr, "rowno = %d, sqlite3 error %d\n", rowno, rc);    break;}if (rowno >= 0) { rowno++; }
    }
    while (rowno >= 0);
    sqlite3_finalize(stmt);
    

    输出:

    rowno: 950129, rowid: 4478623, ctype: 5002, id:001548532328, time:20191220105300
    rowno: 950130, rowid: 4478624, ctype: 5002, id:001548532328, time:20191220105400
    ...
    rowno: 950297, rowid: 4478791, ctype: 5002, id:001548532342, time:20191220105800
    rowno: 950298, rowid: 4478792, ctype: 5002, id:001548532342, time:20191220105900
    rowno: 950299, rowid: 4478793, ctype: 5002, id:001548532342, time:20191220110100
    rowno = 950300, sqlite3 error 11
    rowno: 950301, rowid: 3526517, ctype: 5002, id:005410401490, time:20191214202200
    

日志

  • 20191220.log

    #12-20 11:21:30.098: 写入[38] 20191220-111700  ...
    #12-20 11:21:30.433: 写入[39] 20191220-111800  ...
    #12-20 11:21:30.434: 写入[40] 20191220-111900  ...
    

检查下一天的数据库

  • 2019/12/21的数据库
  • 数据库文件大小: 210 MB
    • 数据库大小相同
  • Check菜单
    • OK

分析

  • 2019/12/20的数据库有malformed问题,而2019/12/21的数据库不存在该问题,可能:

    • 可能原因一:数据库已自动恢复

      • 数据周期未抵达:非通过清理自动恢复
      • 设备中无修复功能
    • 可能原因二:数据库拷贝问题
      • 最后的日志时标: 12-20 11:24:21.057# ...
      • 如果先ftp拉取数据库,然后,保存shell日志,则拉取数据库时,有可能数据库正在执行一个事务,从而导致该问题

结论

  • ftp拉取数据库时,数据库正在执行写数据事务,从而导致malformed问题

诡异的sqlite3之malformed错误(一)相关推荐

  1. activiti 解压zip java.lang.IllegalArgumentException: MALFORMED 错误

    工作流导入 @Overridepublic int create(MultipartFile file, String name, String category) {try{if (file != ...

  2. java zip malformed_java 解压zip java.lang.IllegalArgumentException: MALFORMED 错误

    zip压缩包在解压过程中,遇到了错误,提示如下 java.lang.IllegalArgumentException: MALFORMED at java.util.zip.ZipCoder.toSt ...

  3. URIError: URI malformed错误

    包含了"%"字符,浏览器在对"%"执行decodeURIComponent时报错,正确的解决是将%全部替换为%25再进行传输: Str.replace(/%/g ...

  4. Yum database disk image is malformed 错误

    解决办法: yum clean dbcache

  5. SQLite database disk image is malformed死亡错误及初恢复

    项目中突然遇到远程的嵌入式Linux设备里面上传的数据库打开出现database disk image is malformed死亡错误,提示哪张表出问题了,如下图 一时,脑塞..##¥¥%& ...

  6. database disk image is malformed 问题解决

    问题 提交SVN出现:svn sqlite[S11]: Database disk image is malformed 错误 解决 将sqlite3.exe文件解压缩到.svn目录的同级目录 打开c ...

  7. 7.1 pdo 宝塔面板php_记宝塔面板中 PHP升级到 7.3.16安全版本概要

    因为有云主机上安装的宝塔面板管理的 LAMP运行环境,所以今天看见 宝塔面板 中的 软件商店 里 PHP7.3版本提示有更新,就点击查看是可以更新到 PHP7.3.16版本,于是搜索了一下 PHP7. ...

  8. 先学python还是先学数据库_跟着销售学python8-微信平台初次见识数据库(6)

    本来是计划跟着learn python the hard way ,继续下去, 不过中途补充一下,网页的基础知识吧,也不耽搁了. [摘录]:用来记下,之前不理解的 地方? 1.web.py  引入数据 ...

  9. php7.2 加载pgsql驱动,PHP启动:无法加载动态库PGSQL - php

    我正在尝试使用运行Symfony 3.x: Ubuntu 16.04 PHP 7.0 NGinx 我想与我创建的PGSQL数据库进行交互,但出现此错误: PHP警告:PHP启动:无法加载动态库 '/u ...

最新文章

  1. oracle10.2 管理工具,Oracle 10.2.0.5 EM管理器的BUG
  2. 科学历史也可以写的如此精彩 ——《量子物理史话:上帝掷骰子吗》读后感
  3. poj 3411 1724
  4. 累积分布函数_C7: 概率函数和分布函数Distribution Function
  5. 以图搜图 图像匹配_图像匹配,基于深度学习DenseNet实现以图搜图功能
  6. 闲暇所学“表白对话框”
  7. 【Python】成绩等级判断
  8. Hive insert into小文件问题
  9. 常见的html字体,网页设计中最常用的字体有哪些
  10. 理论知识:电感感应电压公式,纯电感正弦电路感应电压公式,纯电容正弦电路电流公式的推导
  11. 鲁大师Q3季度电动车报告:最聪明的电动车跑分曝光
  12. youtube打开显示服务器更新,youtube-dl更新出错解决办法
  13. dentity在Java里是什么意思_Function.identity()
  14. UltraLight 卡存储结构
  15. 拯救者15isk加装固态硬盘
  16. mpvue + vuex搭建小程序详细教程
  17. SQL39 针对salaries表emp_no字段创建索引idx_emp_no,查询emp_no为10005,使用强制索引。
  18. 前端播放rtmp协议的视频流文件
  19. 交换机access trunk hybrid模式详解
  20. ITU-R BT.601 Y'CbCr

热门文章

  1. 《孩子:挑战》儿童心理学奠基之作摘录分享(四)
  2. 虚拟软件VMware
  3. 论文投稿指南——中文核心期刊推荐(建筑科学 2)
  4. 微信小程序之动态添加、删除指定view和获取input值
  5. PDF解决方案(3)--PDF转SWF
  6. ubuntu16 黑主题_Ubuntu16.04主题美化
  7. Clickhouse官方测试数据
  8. 教师评计算机课缺点及建议,教师听课评课优缺点(教师听课记录评价与建议)
  9. 分享一个小知识点:沟通技巧
  10. 湖北计算机考试打印准考证