诡异的sqlite3之malformed错误(一)
诡异的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
对符合条件的结果排序,实际上执行全表扫描,问题复现
- 当where子句中有ctype,id,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错误(一)相关推荐
- activiti 解压zip java.lang.IllegalArgumentException: MALFORMED 错误
工作流导入 @Overridepublic int create(MultipartFile file, String name, String category) {try{if (file != ...
- java zip malformed_java 解压zip java.lang.IllegalArgumentException: MALFORMED 错误
zip压缩包在解压过程中,遇到了错误,提示如下 java.lang.IllegalArgumentException: MALFORMED at java.util.zip.ZipCoder.toSt ...
- URIError: URI malformed错误
包含了"%"字符,浏览器在对"%"执行decodeURIComponent时报错,正确的解决是将%全部替换为%25再进行传输: Str.replace(/%/g ...
- Yum database disk image is malformed 错误
解决办法: yum clean dbcache
- SQLite database disk image is malformed死亡错误及初恢复
项目中突然遇到远程的嵌入式Linux设备里面上传的数据库打开出现database disk image is malformed死亡错误,提示哪张表出问题了,如下图 一时,脑塞..##¥¥%& ...
- database disk image is malformed 问题解决
问题 提交SVN出现:svn sqlite[S11]: Database disk image is malformed 错误 解决 将sqlite3.exe文件解压缩到.svn目录的同级目录 打开c ...
- 7.1 pdo 宝塔面板php_记宝塔面板中 PHP升级到 7.3.16安全版本概要
因为有云主机上安装的宝塔面板管理的 LAMP运行环境,所以今天看见 宝塔面板 中的 软件商店 里 PHP7.3版本提示有更新,就点击查看是可以更新到 PHP7.3.16版本,于是搜索了一下 PHP7. ...
- 先学python还是先学数据库_跟着销售学python8-微信平台初次见识数据库(6)
本来是计划跟着learn python the hard way ,继续下去, 不过中途补充一下,网页的基础知识吧,也不耽搁了. [摘录]:用来记下,之前不理解的 地方? 1.web.py 引入数据 ...
- php7.2 加载pgsql驱动,PHP启动:无法加载动态库PGSQL - php
我正在尝试使用运行Symfony 3.x: Ubuntu 16.04 PHP 7.0 NGinx 我想与我创建的PGSQL数据库进行交互,但出现此错误: PHP警告:PHP启动:无法加载动态库 '/u ...
最新文章
- oracle10.2 管理工具,Oracle 10.2.0.5 EM管理器的BUG
- 科学历史也可以写的如此精彩 ——《量子物理史话:上帝掷骰子吗》读后感
- poj 3411 1724
- 累积分布函数_C7: 概率函数和分布函数Distribution Function
- 以图搜图 图像匹配_图像匹配,基于深度学习DenseNet实现以图搜图功能
- 闲暇所学“表白对话框”
- 【Python】成绩等级判断
- Hive insert into小文件问题
- 常见的html字体,网页设计中最常用的字体有哪些
- 理论知识:电感感应电压公式,纯电感正弦电路感应电压公式,纯电容正弦电路电流公式的推导
- 鲁大师Q3季度电动车报告:最聪明的电动车跑分曝光
- youtube打开显示服务器更新,youtube-dl更新出错解决办法
- dentity在Java里是什么意思_Function.identity()
- UltraLight 卡存储结构
- 拯救者15isk加装固态硬盘
- mpvue + vuex搭建小程序详细教程
- SQL39 针对salaries表emp_no字段创建索引idx_emp_no,查询emp_no为10005,使用强制索引。
- 前端播放rtmp协议的视频流文件
- 交换机access trunk hybrid模式详解
- ITU-R BT.601 Y'CbCr