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 ===============================================================================