Subject: | Long running: database is locked(5) at dbdimp.c line 218 |
I have an ugly and not very well isolated test case that reliably
fails with a "database is locked" on some platforms with
DBD::SQLite 1.14 and it's default sqlite version.
Failures have been encountered on Debian Etch, Windows XP.
(Ubuntu 8.10, with perl: 5.10.0 64bit succeeded)
There's a writer process, adding rows to a database, intermixing
transactions and autocommit (seemingly required?) and a read-only
process doing selects. It uses fork() to launch the reader
(pseudo-processes on windows xp).
The writer process seems to be the one failing, as the reader's
prints continue with old values.
The failure occurs at slightly different points in processing,
around 280000 count on windows, 204000 count on etch.
The numbers vary, but the windows output looks like:
276000
DBD::SQLite::db commit failed: database is locked(5) at dbdimp.c line
218 at db_
locked.pl line 36.
DBD::SQLite::db commit failed: database is locked(5) at dbdimp.c line
218 at db_
locked.pl line 36.
99
277000
99
277000
99
The .db file produced by the test grows to around 500 Mb
on windows before failing. (Runs without errors grow even larger)
WinXP perl5.8.8, both ActiveState and Strawberry.
I'll try to clarify the problem later if I can,
Brad
Subject: | db_locked.pl |
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use DBD::SQLite;
my $db_file = "test-$$.db";
#print "DBI vers: $DBI::VERSION\n";
print "DBD::SQLite vers: $DBD::SQLite::VERSION\n";
if (my $child = fork) {
print "Parent $$\n";
print "Child $child\n";
writer($db_file);
print "Killing child $child\n";
kill 9, $child;
} else {
sleep(2);
reader($db_file);
}
sub writer {
my $dbh = DBI->connect("dbi:SQLite:dbname=$db_file",'','',
{ RaiseError => 1 });
$dbh->do('create table t1 (a)');
$dbh->do('create table t2 (b)');
for (1..1000) {
$dbh->begin_work();
for (1..1000) {
# s/rand() x 100/1/ ran to completion
$dbh->do('insert into t1 (a) values (?)', {}, rand() x 100);
}
sleep(1);
$dbh->commit();
$dbh->do('insert into t2 (b) values (?)', {}, $_);
}
}
sub reader {
my $dbh = DBI->connect("dbi:SQLite:dbname=$db_file",'','',
{ RaiseError => 1 });
while (1) {
print $dbh->selectrow_array('select count(*) from t1'), "\n";
print $dbh->selectrow_array('select max(b) from t2'), "\n";
sleep(1);
}
}
END {
#unlink $db_file;
}