Use an external file to lock the DB File, as described in RE: File Locking (using the Search box wouldl have given you an answer right away BTW).
| [reply] |
mod_perl guide has a chapter dedicated to concurrent access to file based databases like Berkley DB. There are discussed a number of strategies and hopefully it should answer all your questions on this topic.
--
Ilya Martynov, ilya@iponweb.net
CTO IPonWEB (UK) Ltd
Quality Perl Programming and Unix Support
UK managed @ offshore prices - http://www.iponweb.net
Personal website - http://martynov.org
| [reply] |
For what it's worth, in my experience/experiments, using DB_File with the lastest version of the Berkeley DB(4x), there really isn't any need to do any sort of locking when all you want is to read.
The Berkeley DB mechanisms take care of any potential data corruption.
In the example below, run #1 and then #2 while #1 is still running (preferably in 2 separate shells -- simultaneous)
# 1
perl -MFcntl -MDB_File -e"tie%a,'DB_File','rat.test',O_CREAT|O_RDWR or
+ die $!;for(1..1_000){select undef,undef,undef,.01;$a{a}++;}"
# 2
perl -MFcntl -MDB_File -e"tie%a,'DB_File','rat.test',O_RDONLY or die $
+!;warn $a{a}"
When you first run #1, and then #2 ( while #1 is still running),
#2 will yield Warning: something's wrong at -e line 1.
every time you invoke it, whilst #1 is still running.
After #1 is finished running, then run #2 again, and it will yield 1000 at -e line 1.
In my programs, I freely tie a DB_File for O_RDONLY, but for O_RDWR, I use a flocking mechanism like DB_File::Lock.
MJD says you
can't just make shit up and expect the computer to know what you mean, retardo!
** The Third rule of perl club is a statement of fact: pod is sexy.
|
| [reply] [d/l] |
Hi,
you can use flock in this way
#!/usr/bin/perl -w
use strict;
use Fcntl ':flock'; # import LOCK_* constants
sub lock {
flock(FH,LOCK_EX);
# and, in case someone appended
# while we were waiting...
seek(FH, 0, 2);
}
sub unlock {
flock(FH,LOCK_UN);
}
my $filename = "plain-db.pdb";
open(FH, ">>$filename")
or die "Can't open file ($filename): $!";
lock();
# do what ever you want with it
unlock();
Maybe this can help you.
| [reply] [d/l] |
lock();
# do what ever you want with it
unlock();
If "whatever you want" involves tieing a DB_File, you're in for trouble. Some versions of BerkeleyDB close the file and reopen it, which loses the lock for you. This took me a lot of pain and agony to discover, but fortunately not too much data was corrupted before I figured it out.
Using a separate lock file is good. The mod_perl guide is good. Heed the other monks.
Update: If you close the same file you lose the lock, even if you open it through a different filehandle and close that one. Locks exist at the inode level, not the filehandle level. | [reply] [d/l] |
Sorry,
flock works on filehandles, if you close the filehandle
you're in trouble (the lock will be released). That's right.
| [reply] |
But only if you want to risk data corruption
That is the classic perl flock boo-boo.
You should never "unlock", just close the file, and the lock will go away.
Also, do you really need a lock subroutine?
I didn't respond to this the other day in hopes that somebody else would, and much to my suprise, nobody paid attention.
MJD says you
can't just make shit up and expect the computer to know what you mean, retardo!
** The Third rule of perl club is a statement of fact: pod is sexy.
|
| [reply] |
It might be worth mentioning here (although it may not apply to this case) that in many Unix implementations the flock() call is advisory. That is to say, only programs looking for a lock, will treat it as locked. However (at least under Solaris) you can use the SGID bit on the file to (err . . could be the SUID bit . . can't remember) to trigger a mandatory lock that will effect any/everything. Most heartily suggest a read of your local flock(3) man page to be sure how your OS of choice handles it.
Hope this helps someone.
-anelson | [reply] |
Versions of BerkeleyDB >= 3.0 have table and record level locks builtin. I have just started looking into them my self but you may want to check out Apache::Session::BerkeleyDB and specifically Apache::Session::Lock::BerkeleyDB and of course BerkeleyDB.
The perl documentation for BerkeleyDB is lacking so you will probably have to have a look at the C API at http://www.sleepycat.com.
perrin has a great article on perl.com that mentions some of the issues of using BerkeleyDB locking here
-Lee
"To be civilized is to deny one's nature." | [reply] |
my $db = tie %hash, 'DB_File', ...;
my $fd = $db->fd();
open my $handle, "+<&=$fd" or die ...
flock $handle, LOCK_WHATEVER;
--
http://fruiture.de | [reply] [d/l] |