Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to protect SQLite database from corruption

I'm trying to figure out which is the safest strategy for protecting my (file-based) SQLite database from corruption (in this case, I'm working with Adobe Air, but this could apply to any webkit browser that uses SQLite, including Mobile Safari).

I'm thinking about creating a database connection, keeping it around for only maybe 5 or 10 seconds and then closing it if it hasn't been used during that period. My thinking is that should the machine crash or the application exit abnormally, chances are good that the file will already be closed and thus less likely to get corrupted. But I know that the more often you open and close a filebased DB, the more likely it is you'll have a critical error.

I'm sure I'm over-thinking this, but for my application it's critical that in the event of a system crash, the application can recover cleanly and quickly and that means I have to try to protect the DB as much as I can.

Does anyone know which strategy is likely to be safer?

like image 630
Andrew Avatar asked Jun 27 '10 08:06

Andrew


People also ask

Can SQLite get corrupted?

An SQLite database is highly resistant to corruption. If an application crash, or an operating-system crash, or even a power failure occurs in the middle of a transaction, the partially written transaction should be automatically rolled back the next time the database file is accessed.

How can we prevent database corruption?

Backup, Backup, and Backup Regularly carrying out back-up procedures ensures business continuity. Backups can be of great help when databases develop problems. In such cases, backup files can be used to restore the corrupt databases, thereby preventing downtime.

How do I make SQLite secure?

In the end, it seems like the best solution for storing sensitive data in SQLite is to encrypt it before storage. If you prefer not to encrypt the data yourself, SQLite has an extension called SQLCipher that will perform encryption. The commercial version does have a fee, but the community edition is open source.

How can I tell if SQLite database is corrupted?

To verify that you're truly suffering from database corruption, enter the following command into the shell: sqlite> PRAGMA integrity_check; If the response is anything other than ok, the database is integrity checks have failed and needs to be repaired.


2 Answers

At the end of this document

File Locking And Concurrency In SQLite Version 3

There are a section named "6.0 How To Corrupt Your Database Files" that discuss corruption hipotetical curroptions problems in sqlite. "Things that can can go wrong".

like image 52
Jonathan Avatar answered Sep 28 '22 23:09

Jonathan


First do NOT use journal_mode=MEMORY or =OFF.

We can use these commands to reduce the probability of a corruption:

  1. PRAGMA synchronous=FULL or PRAGMA synchronous=EXTRA
  2. PRAGMA fullfsync=ON (only works on Mac OS X)

But they come with a cost of making the transactions slower. And even with them the db can become corrupted due to other causes like failure in the storage device or in the memory so we must be prepared to the problem.

We can make regular backups, but it has 2 disadvantages:

  1. It copies the entire db file on each backup
  2. We loose all the transactions that were made after the last backup

I have a customer that was used to make his backup on a pen-drive and the pen-drive was always kept plugged to the computer until a lightning came and destroyed the computer, including the pen-drive. All the data was lost. So the backup must be kept separated from the main computer.

A better alternative is to use replication. With it each transaction executed on the main db is replicated to the replicas.

For SQLite we can use litereplica. It supports Point-in-Time Recovery and I suggest to use it with replication because if some data is accidentally deleted from the main db it will be replicated. With PITR we can restore the db to a previous point in time.

Another important suggestion is to keep the replica in a separate device, and apart from each other. At least not in the same building.

Running PRAGMA integrity_check command once in a while is a good practice due to the fact that SQLite does not do it automatically and it continues writing to the db in some kinds of corruptions.

And if your db uses foreign keys you can do the same with PRAGMA foreign_key_check.

like image 22
Bernardo Ramos Avatar answered Sep 28 '22 21:09

Bernardo Ramos