本文将要为您介绍的是数据库损坏的可能原因,具体操作过程:
  1.数据库文件被其他线程覆盖或删除 在文件描述符关掉以后,继续使用这个文件描述符访问 打开文件,获取文件描述符fd(其实是一个整形) 关闭文件 打开sqlite文件,获取文件描述符(碰巧也是)fd 另一个线程继续使用fd,写文件 sqlite文件被损坏 在事务进行过程中,进行数据库备份或恢复 在数据库事务过程中,数据库文件既包括老的内容,也包括新的内容。如果此时拷贝这个文件,数据库可能会被损坏。 备份数据库好使用sqlite的api。 删除日志文件 日志文件中包括rollback需要的信息。删除以后,无法正确回滚,有可能会导致数据库损坏。
  2. 文件锁相关
  sqlite使用文件锁来在保证多线程访问。如果文件锁机制不正常,会导致同时读写文件等信息,导致数据库损坏文件系统没有正确的实现文件锁的机制 在网络操作系统中,比较常见 不正确使用close()函数 在Unix中,close()函数会解除所有线程的文件锁。 例如A、B线程打开了数据库文件,使用sqlite的api。此时,线程C依次调用了open(),read()以及close()。此时,这个文件的所有锁已经没了。因此A、B有可能会同时写数据到文件中。 两个进程使用不同的锁协议(locking protocols) 默认使用POSIX advisory locking,可以用sqlite3_open_v2()函数修改。如果不一致,可能发生同时读写,数据库损坏。 在数据库文件使用时rename或unlink 两个进程A、B,同时对一个数据库文件建立数据库连接。A关闭连接,unlink文件,用同样的名字创建一个新的数据库文件,在打开这个数据库。这样子A、B两个进程在使用不同的数据库,名字却是一样的。 然而,日志文件是根据数据库名字来区分数据库文件的。因此这两个进程的数据库文件会是同一个。导致数据库文件损坏。 一个文件有多个连接 也是说一个数据库文件有多个名字。假如A、B使用不同的名字打开同一个数据库链接,会有两个日志文件。 如果线程A crash了,B检测到需要进行rollback。找不到日志文件,无法回滚。
  3. sync失败
  为了保证数据库文件的一致性(consistent),会调用fsync()系统调用,把内存中的数据刷到磁盘中。如果这个sync操作失败,会导致数据库文件损坏
  sync系统调用和文档描述不一致 USB闪存经常这样子。例如写大数据时,在函数返回已写入成功时,USB的指示灯还在亮着。 使用PRAGMAs禁用sync synchronous=OFF可以提高速度,却会导致文件不一致。
  4.硬盘、闪存损坏
  5. 内存损坏
  当野指针、内存溢出等原因,可能导致内存中的数据库结构损坏,从而有可能导致数据库文件损坏。 当进行memory-mapped I/O时,由于内存直接映射到磁盘,如果发生数组越界等,内存中的数据损坏,磁盘文件也会损坏
  6. 其他操作系统问题 文件系统崩溃