【引子】

平时用sqlite数据库比较少。被问到sqlite数据库损坏怎么办这个问题时就把我难住了,于是就整合了几篇比较好的文章,记录一下。


SQLite算是非常稳定的数据库,不容易出现损坏,就算应用程序崩溃,或者操作系统崩溃,甚至是执行事务时出现断电,都能在下一次使用数据库时自动修复。但是,还是不能避免不出现损坏的情况。

导致SQLite数据库损坏的情况

导致SQLite数据库损坏的情况大致可归结为4类:文件覆盖问题、文件锁问题、数据同步问题、内存问题

文件覆盖问题

SQLite数据库文件被覆盖是可能的,毕竟是一个普通的磁盘文件,意味着所有的进程都可以打开和覆盖,所以不可能完全避免文件覆盖的情况。

1. 多线程写数据库问题。

SQLite数据库是支持多进程并发读写,但是如果这时候关闭和重新打开数据库,就很可能出现一些线程还在写数据到数据库,出现部分数据被覆盖的情况。

2. 执行事务时备份或恢复数据

事务都是一个过程性的操作,需要一定时间,而数据备份是原子操作,如果在事务执行过程时备份,可能导致复制的内容包含了部分新的内容和部分旧的内容,就出现数据库损坏。恢复也是一样。

3. 删除日志文件

SQLite数据库通常都是存储所有内容到一个文件,但执行事务时,为了实现程序崩溃,断电时可以回滚日志,就伴随着一些附加的日志文件。如果日志被删除了,就会导致恢复出现异常。

文件锁问题

为了实现SQLite数据库并发读写,SQLite会使用文件锁来保证数据安全。

1. 系统文件锁问题

SQLite依赖于底层的文件系统对文件锁的实现,但是,一些文件系统存在锁逻辑错误,使得锁并不可靠,这在网络文件系统和NFS情况比较常见。

2. POSIX协同锁(advisory lock)

在linux 或者unix下,SQLite 默认锁是协同锁。当进程使用 协同锁,如果其中有一个线程执行 close() 就可能导致锁被取消。如果已经有两个线程同时连接到同一个数据库,再来一个线程不以SQLite API的形式,就是以系统文件形式读取数据库( open(), read() , 然后close()),就会导致这个进程的数据库锁被取消,而两个线程同时操作数据库就会导致数据覆盖引起错乱。

3. 不同的连接协议

不同的 连接协议锁也可能会不同,也就导致锁没有发挥错误引起错误。

4.当数据库正在使用时删除或重命名数据库文件

出现这种情况往往是在linux等类POSIX系统,windows下不会出现这个情况,而且同时有事务执行就会放大这个问题。

数据同步问题

为了保证数据一致性, SQLite有时候会请求操作系统将所有等待持久化的数据刷入磁盘,然后等待这个操作完成。

1.磁盘驱动器的同步请求可能是不可靠的

现有普通消费级别的磁盘驱动器 多数 都会谎报数据同步结果,以期望得到更高的写入速度。当数据刚到达磁盘缓冲区,还没真正写入氧化物介质,磁盘驱动器就报告内容已经安全写入。但是这时候断电、硬件复位就会导致数据同步失败。这种情况主要出现在闪存介质。

2.使用PRAGMAs会影响同步

通过设置PRAGMA synchronous=OFF, SQLite所有的同步操作都会被忽略。这使得SQLite运行得更快,但如果出现电源故障或硬件复位就会前面保存的所有数据。 如果单纯为了获得最大的数据可靠性和健壮性,SQLite可设置synchronous = FULL

内存问题

SQLite作为一个 C运行库, 和使用它的应用程序运行在同一个内存地址空间。这意味着,任何野指针,缓冲区溢出,堆损坏等都有可能损坏了 SQLite的数据结构,并最终导致数据库文件损坏。
另外,使用内存映射I/O模型(如mmap)的时候,内存问题会变得更加严重。当数据库文件的一部分或全部被映射到应用程序的地址空间,虽然减少了文件IO操作,但是野指针可能访问并修改到任何部分的 映射空间 数据。

更多SQLite数据库损坏的原因可以看官网
How To Corrupt An SQLite Database File。

  1. File overwrite by a rogue thread or process
    1.1. Continuing to use a file descriptor after it has been closed
    1.2. Backup or restore while a transaction is active
    1.3. Deleting a hot journal
    1.4. Mispairing database files and hot journals
  2. File locking problems
    2.1. Filesystems with broken or missing lock implementations
    2.2. Posix advisory locks canceled by a separate thread doing close()
    2.2.1. Multiple copies of SQLite linked into the same application
    2.3. Two processes using different locking protocols
    2.4. Unlinking or renaming a database file while in use
    2.5. Multiple links to the same file
    2.6. Carrying an open database connection across a fork()
  3. Failure to sync
    3.1. Disk drives that do not honor sync requests
    3.2. Disabling sync using PRAGMAs
  4. Disk Drive and Flash Memory Failures
    4.1. Non-powersafe flash memory controllers
    4.2. Fake capacity USB sticks
  5. Memory corruption
  6. Other operating system problems
    6.1. Linux Threads
    6.2. Failures of mmap() on QNX
    6.3. Filesystem Corruption
  7. SQLite Configuration Errors
  8. Bugs in SQLite
    8.1. False corruption reports due to database shrinkage
    8.2. Corruption following switches between rollback and WAL modes
    8.3. I/O error while obtaining a lock leads to corruption
    8.4. Database pages leak from the free page list
    8.5. Corruption following alternating writes from 3.6 and 3.7.
    8.6. Race condition in recovery on windows system.

修复损坏的SQLite数据库

前阵子由于分区空间满出现了sqlite3数据库文件损坏的现象,操作的时候报错:

Error: database disk image is malformed

这里记录一下修复的操作过程:

1.将数据库中的数据导出为sql语句文件

sqlite3 test_file.db #打开损坏的数据库文件
.output recovery.sql  #设置输出文件
.dump   # 导出文件
.q

2.将导出的recovery.sql文件最后一行ROLLBACK改为COMMIT;

vim recovery.sql

3.导入到一个新库中

sqlite3 fix.db  #打开用于导入修复后的数据库数据
.read recovery.sql  #读取数据文件
.q

SQLite使用建议

这里有4点建议:

  1. 减少多进程或多线程操作,尽可能单线程写。
  2. 减少事务操作,减小事务复杂度,减少检查点
  3. 减少数据库的大小
  4. 避免使用PRAGMA synchronous=OFF

引经据典

https://blog.csdn.net/jieshibendan/article/details/90678036
https://blog.csdn.net/qq_35241071/article/details/111247142
https://blog.csdn.net/mycwq/article/details/45541409

SQLite数据库损坏与修复相关推荐

  1. 讨论SQLite数据库损坏与修复

    昨晚,朋友和我反馈SQLite数据库发生损坏有没有办法恢复.大致的情况是这样的,当数据库在使用时不小心用了新的文件覆盖数据库,导致了SQLite数据库出现了损坏,打开的时候出现要输入密码,而且不能把S ...

  2. SQLite数据库损坏及其修复探究

  3. SQL Server FILESTREAM数据库损坏和修复

    This article will cover corruption and recovery scenarios in the context of SQL Server FILESTREAM in ...

  4. dbnetlib sqlserver不存在或拒绝访问_SQL Server数据库损坏和修复

    常见错误解读 823错误 错误信息是:"在文件'%ls'中.偏移量为%#016I64x的位置执行%S_MSG期间,操作系统已经向SQL Server返回了错误%ls." " ...

  5. SQLITE数据库损坏分析及解决

    1 前言 本文主要阐述SQLTE数据库文件在异常场景下发生损坏的原因及提供相应的解决方案.本文涉及代码部分的SQLITE库使用SQLITE_VERSION 3.20.1. 2 数据库异常操作 SQLT ...

  6. SQLite数据库损坏修复

    The database disk image is malformed https://www.sqlite.org/2018/sqlite-tools-win32-x86-3240000.zip ...

  7. Sqlite 数据库损坏的恢复

    SQlite database disk image is malformed 数据表的损坏,一般原因: 数据表在读写的时候,设备突然断电.关机.软件闪退等情况下会造成数据库或表的损坏. Sqlite ...

  8. Andriod SQLite3 数据库损坏,优化,修复,备份方案研究

    Andriod Sqlite3 数据库损坏,修复,备份方案研究 1.数据库损坏原因 我们首先来看 SQLite 损坏的原因,SQLite官网<How To Corrupt An SQLite D ...

  9. 修复损坏的SQLite数据库文件(database disk image is malformed)

    文章目录 问题与原因 修复数据库 命令行修复 一.准备 二.命令行打开被损坏的数据库文件 三.导出sql语句到临时文件 四. 修改tmp.sql文件与写入到空数据库中 SQLite Expert Pr ...

最新文章

  1. 1.3 选择适合的Arduino
  2. c语言判断文件是否建立成功,C语言编程之怎样判断某一文件是否存在
  3. python turtle画彩虹-Python基础实例——绘制彩虹(turtle库的应用)
  4. iphone导出通讯录到安卓_如何把旧手机的便签数据转移到新的iPhone手机上?
  5. js和css被屏蔽了,拦截器 Filter ,js、css、image等静态资源不被拦截解决方案
  6. 如何提升测试环境的稳定性?来看看阿里内部的实践总结
  7. mine layer(2008 World Final C)
  8. 【数据结构】八种常见数据结构介绍
  9. 店店融合共振出的价值 才是苏宁的零售杀手锏
  10. 基于阿里云 OSS 下载图片跨域问题
  11. K8S报error: You must be logged in to the server错误
  12. 感染 <SCRIPT Language=VBScript> DropFileName = “svchost.exe” Ramnit 蠕虫病毒 HTML清除工具
  13. 十分钟看懂数据库——数据库入门级语言总结
  14. 利用CIBERSORT免疫细胞类群分析详细教程
  15. 浅谈区块链技术对未来行业的影响
  16. android最强论坛,Android开发论坛
  17. matlab曲线加颜色,matlab学习之绘制参数曲线,添加辅助线以及颜色设置
  18. 关于串口波特率的的记录
  19. 软体艺术系列--抽象工厂 (原文最终修订于2006年10月18日 凌晨04:25:06)
  20. Go实现 Bit 数组(集合)

热门文章

  1. NYOJ练习题 how many hairstyles can they see?
  2. (十)更快的排序算法(归并、快排、基数)
  3. python 面向对象(类)--学习笔记
  4. 微信自动关闭内置浏览器页面,返回公众号窗口 WeixinJSBridge.call('closeWindow')
  5. 什么是 Spring?
  6. 在window 2008 server r2 64位 IIS上配置 apache tomcat 8.0
  7. Android 线程 thread 两种实现方法!
  8. 发个上海英雄会聚会沙龙的公告 希望和大家一起见面交流探讨
  9. Python学习笔记:‘’AttributeError: NoneType object has no attribute‘’
  10. Win10:tensorflow 学习笔记(1)