On Tue, 30 Nov 2004, Alexander Jordanov wrote:

I am 100% sure that my all my queries go trought that class.  Unfortunatelly
it is too late to make such changes ('forces the user to specify whether the
transaction is write or read') - i have too many scripts to change.

make every single sql execution follow this logic

  die 'nested lock' if global_recursion_flag

  global_recursion_flag = true

    ret = flock 'db.lock', LOCK_EX
    die 'lock failed' unless ret

    result = execute sql

    ret = flock 'db.lock', LOCK_UN
    die 'unlock failed' unless ret

  global_recursion_flag = false


if all access is through this one class you CANNOT experience a locked database using this logic. if you are then:

  0) some other process is locking the database

  1) there is some database access NOT though this class

  2) your app is doing some weird thread things fcntl based locks are process
  based so all thread 'get the lock'


About NFS i asked the hosting and they said they dont use NFS.

good.

And can the lack of threadsafe lead to such behaviour? (i suppose it can...)

i don't know - but seriously doubt it unless you're access is multithreaded.

is it?

I must say also that the database seems to get locked during a select query
because i can read normally from the database but can't write in it.

then some other process holds the lock.

i can't get the database to lock (exept when the script times out and i only
noticed that on a linux machine and i can't confirm that it also applies to
the server - probably will test that tommorow but even if it applies i have
put one hour timeout and my scripts are not that heavy i have 2 places if i
recall correctly where i use recursion and for the first i am 100% sure it
is ok and the second has been used for -4-5 months without problems and i
haven't changed anything on it)

this smells fishy. obviously SOMETHING changed right? recursion and locking sounds like a great thing NOT to do! another thing you might try removing your database - seriously, if you coordinated ALL access through something like

    ret = flock 'db.lock', LOCK_EX

    mv '.db', 'db'

    result = execute sql

    mv 'db', '.db'

    ret = flock 'db.lock', LOCK_UN

i would expect that the offending code (the secret locker you cannot determine
with lsof or fuser) would begin to blow up.  does that make sense?  what i am
saying is that if database never exists unless the lock is held then code that
is not respecting the lockfile will fail because the database will not be there
(tiny race condition i realize but this would certainly make offending code
fail).

Can a query get the database locked? because i can't imagine a query that
can do that...

i don't think so.

And what can lock a database?

probably nothing but your own code ;-(

I tried not to commit a transaction but the database didn't lock... any
ideas?

something is very, very wrong then:

  harp:~ > rm db; sqlite db 'create table foo(bar)'

  harp:~ > strace sqlite db 'begin;end;' 2>&1 | grep -i lck
  fcntl64(3, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff7b30) = 0
  fcntl64(3, F_SETLK64, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff7b40) = 0
  fcntl64(4, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff7b30) = 0
  fcntl64(4, F_SETLK64, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff7b40) = 0
  fcntl64(3, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff76b0) = 0
  fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff7710) = 0
  fcntl64(4, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff76b0) = 0
  fcntl64(4, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff7710) = 0
  fcntl64(3, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff76f0) = 0
  fcntl64(3, F_SETLK64, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff76c0) = 0
  fcntl64(4, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff76f0) = 0
  fcntl64(4, F_SETLK64, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff76c0) = 0

  harp:~ > strace sqlite db 'begin; insert into foo values(42); end;' 2>&1 | 
grep -i lck
  fcntl64(3, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9ed0) = 0
  fcntl64(3, F_SETLK64, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9ee0) = 0
  fcntl64(4, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9ed0) = 0
  fcntl64(4, F_SETLK64, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9ee0) = 0
  fcntl64(3, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9a50) = 0
  fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9ab0) = 0
  fcntl64(4, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9a50) = 0
  fcntl64(4, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9ab0) = 0
  fcntl64(3, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9a90) = 0
  fcntl64(3, F_SETLK64, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9a60) = 0
  fcntl64(4, F_SETLK64, {type=F_RDLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9a90) = 0
  fcntl64(4, F_SETLK64, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}, 
0xbfff9a60) = 0

-a
--
===============================================================================
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| When you do something, you should burn yourself completely, like a good
| bonfire, leaving no trace of yourself.  --Shunryu Suzuki
===============================================================================

Reply via email to