Can SQLite be used with GlusterFS?

I want to build a distributed storage based on GlusterFS with Automatic File Replication (AFR) to store users files in a fault-tolerant way.

But I also want to access an SQLite3 database stored on the GlusterFS volume (and so replicated on several servers) from multiples clients. Is it possible? Does the concurency between the several clients will be well handled and will not lead to corruption?

Or is there a better alternative to GlusterFS to distribute the SQLite3 database?


GlusterFS supports full POSIX file / record level locking even in replication mode. It should work fine.


I wrote a sqlite_shared_fs_check.sh script to simulate many reads and writes to the sqlite3 database. It is supposed to run in the same GlusterFS directory on several client machines.

I tested following configurations:

  • GlusterFS 3.2 and sqlite3 3.5.9 (ubuntu 8.10). The DB did not become corrupted.
  • GlusterFS 3.2 and sqlite3 3.6.22-1 (ubuntu 10.04). TBD.
  • Ext3 and sqlite3 3.5.9 (ubuntu 8.10): The test was run from two terminal windows at once. The test finished without any problems whatsoever.

Results of the last test (ext3+sqlite3) put the blame on POSIX locking non-conformance onto GlusterFS 3.2.

Here is the script I used to do the testing:

#!/bin/bash

function ErrorExit()
{
  echo Error: $@
  exit 1
}

# Microseconds
timeout=5000

if [ ! -f test.sqlite3 ];
then
  touch test.sqlite3
  echo 'create table test1 (id integer primary key autoincrement,datetime text,hostname text);' | sqlite3 test.sqlite3 || ErrorExit "Create"
fi

if [ ! -f /tmp/insert.sql ];
then
  echo .timeout $timeout > /tmp/insert.sql
  echo "insert into test1 values (NULL,datetime('now','localtime'),'$HOSTNAME');" >> /tmp/insert.sql
fi

if [ ! -f select.sql ];
then
  echo .timeout $timeout > select.sql
  echo "select * from test1 order by id desc limit 1;" >> select.sql
fi

if [ ! -f count.sql ];
then
  echo .timeout $timeout > count.sql
  echo "select count(*) from test1;" >> count.sql
fi

i=1
while [ $i -le 1000 ];
do
  lockfile-create --retry 20 test.sqlite3 || echo -n "?"
  sqlite3 test.sqlite3 < /tmp/insert.sql
  lockfile-remove test.sqlite3

  # Sleep a bit to allow other users
  sleep 0.5
  lockfile-create --retry 20 test.sqlite3 || echo -n "?"
  sqlite3 test.sqlite3 < select.sql >/dev/null || ErrorExit select [$i]
  sqlite3 test.sqlite3 < count.sql >/dev/null || ErrorExit count [$i]
  lockfile-remove test.sqlite3
  let i++
  echo -n "."
done

Note that I had to use the lockfile-create utility to acquire locking on the db, as sqlite's internal locking is not reliable enough.


I think the locking might be the hard part of it. Imagine the write process has to lock the sqlite3 database(file) when it is writing into it. The question is what level of concurrency do you need? I think you are going to face possible performance issues with a write bound application.


You'll have locking issues where (in effect) one client at a time can be writing to the file.