On Tue, 17 May 2005, Jaap Krabbendam wrote:
I have been simulating a crash during a transaction. After BEGIN, at some point I do exit(-1) instead of COMMIT or ROLLBACK in order to simulate a crash.
After that, I can see that a -journal file is present. If I restart my executable, it seems that the changes of the transaction are made undone (which is as expected). The journal file however is not removed. Furthermore, if I try to do the same operation again (BEGIN + some changes), I get an SQL_BUSY error code on the first record change (UPDATE/SET).
run fuser on the db and see who has it open. this cannot happen unless:
- some other process holds the lock (eg. you are using fastcgi or mod_ruby and some other process is locking the db)
- your db in on nfs and you setup is fubar. btw. i've never seen a __correct__ nfs setup. when incorrect locks can get hung on the server side.
- there is a kernel bug.
I have the feeling that the OS still has a lock on the database. Any ideas on how to prevent this or on how to recover from this situation?
again - unless there is a kernel bug (which i doubt as we are using sqlite on many of our linux systems running 100,000's of transactions, even on nfs, with zero issues in 3 years) the most likely explaination is that another process does, in fact, hold the lock.
I am using the following setup: -sqlite-3.2.1 -linux/i686/2.6.9-1.667smp -application using posix threads. Only one thread is accessing the database.
threads and fcntl based locks do not work as you might expect. your process will go into uninterruptable sleep on the call to fcntl if it blocks and this stops all threads. what do you mean 'only one posix thread' since ruby threads are green and not posix?? you mean you have another application using posixthreads in addition to your rails app? if so that's certainly the process holding the lock.
if your db is not on nfs this code will show you how to tell which process holds the lock:
jib:~ > cat a.rb # # http://raa.ruby-lang.org/project/posixlock/ # http://www.codeforpeople.com/lib/ruby/posixlock/ # require 'posixlock'
path = ARGV.shift || __FILE__
File::chmod 0700, path
f = open path, 'r+'
if fork ret = f.lockf File::F_LOCK, 0 pid = Process::pid
puts "parent <#{ pid }> holds lock on <#{ f.path }>" sleep 2 else sleep 1 ret = f.lockf File::F_TEST, 0 ppid = ret pid = Process::pid puts "child <#{ pid }> cannot lock <#{ f.path }> because pid <#{ ppid }> holds lock" exit end
jib:~ > ruby a.rb parent <23833> holds lock on <a.rb> child <23834> cannot lock <a.rb> because pid <23833> holds lock
so a simple script like
require 'posixlock'
path = open ARGV.shift 'r+' ret = f.lockf File::F_TEST, 0
unless ret.zero? puts "process <#{ ret }> holds lock on <#{ path }>" else puts "lock on <#{ path }> available " end
man fcntl will explain all this further.
kind regards.
-a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | renunciation is not getting rid of the things of this world, but accepting | that they pass away. --aitken roshi ===============================================================================