我有一个我们每天都成功运行了差不多过去的2年一个Perl程序,但今天崩溃,并显示错误消息:
严重错误:不能做PRAGMA CACHE_SIZE = 1000000:尝试写入只读数据库
有问题的SQLite数据库是只读的,而且一直和代码一直使用PRAGMA cache_size = 1000000
就可以打开它的只读连接后即可。
设置CACHE_SIZE不是写操作时,如果我直接访问数据库直通的DBI,这样不会失败:
$ dbh->做( “PRAGMA CACHE_SIZE = 1000000”)
然而,该代码使得SqliteH :: DB DBI ::数据库的一个子类,然后调用从子类此功能:
$自我> SUPER :: DO( “PRAGMA CACHE_SIZE = 1000000”)
现在它死了“DBD :: SQLite的:: DB做失败:尝试写在/local/ifs_projects/prok/function/src/lib/SqliteH.pm线只读数据库329.”
该代码工作在CentOS 5,Perl的5.10.1,DBD :: SQLite的1.29和1.611 DBI。 它不工作的CentOS 6,Perl的5.16,DBD :: SQLite的1.39,和DBI 1.627。 不过,我困惑,它/ DID /工作,上周在CentOS 6和Perl 5.16。 它可能已在周末升级DBD :: SQLite的或DBI。
请不要更改标题为“突然变得对已数月的工作程序错误”了。 这是一个无用的和非特异性的称号。
TL; DR - 如果交易,那么任何命令试图写入事务日志。 删除自动提交=> 0从胸径连接标志如果数据库是只读的[你不应该有任何 - > begin_work()或INSERT / UPDATE调用要么,但从来没有在一个只读数据库:-)工作] 。
事实证明,我今天有完全相同的问题更新的SQLite,DBI和DBD :: SQLite的后(所以我不知道到底是哪他们造成的问题),但对我来说,在选择(这使它更令人费解)。 原来,交易是在原来的连接字符串打开:
my $dbh=DBI->connect('dbi:SQLite:file.db','','',, {PrintError=>1,RaiseError=>1,AutoCommit=>0});
并且,跟踪代码后,我发现它实际上是崩溃试图启动一个事务。
DB<4> $dbh->trace(15)
DBI::db=HASH(0x18b9c38) trace level set to 0x0/15 (DBI @ 0x0/0) in DBI 1.627-ithread (pid 15740)
DB<5> $sth= $dbh->prepare("SELECT key,value FROM annotation where accession=?")
...
DB<6> $sth->execute('D3FET3')
-> execute for DBD::SQLite::st (DBI::st=HASH(0x18ba340)~0x18ba178 'D3FET3') thr#10cd010
sqlite trace: bind into 0x18ba268: 1 => D3FET3 (0) pos 0 at dbdimp.c line 1232
sqlite trace: executing SELECT key,value FROM annotation where accession=? at dbdimp.c line 660
sqlite trace: bind 0 type 3 as D3FET3 at dbdimp.c line 677
sqlite trace: BEGIN TRAN at dbdimp.c line 774
sqlite error 8 recorded: attempt to write a readonly database at dbdimp.c line 79
!! ERROR: '8' 'attempt to write a readonly database' (err#1)
<- execute= ( undef ) [1 items] at (eval 15)[/usr/local/packages/perl-5.16.1/lib/5.16.1/perl5db.pl:646] line 2 via at -e line 1
DBD::SQLite::st execute failed: attempt to write a readonly database at (eval 15)[/usr/local/packages/perl-5.16.1/lib/5.16.1/perl5db.pl:646] line 2.
...
卸下自动提交=> 0标志在connect()调用固定我的问题。
文章来源: Perl DBI treats setting SQLite DB cache_size as a write operation when subclassing DBI