首页 文章

在对DBI进行子类化时,Perl DBI将SQLite DB cache_size设置为写入操作

提问于
浏览
1

我有一个Perl程序,我们在过去两年中每天都成功运行,但今天崩溃的错误消息:

FATAL ERR:无法执行PRAGMA cache_size = 1000000:尝试编写只读数据库

有问题的SQLite数据库是readonly,并且一直都是,并且代码在打开readonly连接后立即使用 PRAGMA cache_size = 1000000 .

设置cache_size不是写操作,如果我通过DBI直接访问db,则不会失败,如下所示:

$ dbh-> do(“PRAGMA cache_size = 1000000”)

但是,代码使SqliteH :: db成为DBI :: db的子类,然后从子类调用此函数:

$ self-> SUPER :: do(“PRAGMA cache_size = 1000000”)

它现在死了“DBD :: SQLite :: db do failed:尝试在/local/ifs_projects/prok/function/src/lib/SqliteH.pm第329行写一个只读数据库 . ”

该代码适用于CentOS 5,Perl 5.10.1,DBD :: SQLite 1.29和DBI 1.611 . 它不适用于CentOS 6,Perl 5.16,DBD :: SQLite 1.39和DBI 1.627 . 然而,我对上周在CentOS 6和Perl 5.16上的表现感到困惑 . IT可能在周末升级了DBD :: SQLite或DBI .

请不要将 Headers 更改为“突然收到有关数月工作的程序错误” . 这是一个无益和非特定的 Headers .

1 回答

  • 3

    TL; DR - 如果启用了事务,则任何命令都会尝试写入事务日志 . 如果数据库是只读的,则从dbh连接标志中删除AutoCommit => 0 [你不应该有任何 - > begin_work()或INSERT / UPDATE调用,但是从未在只读db上运行:-)] .

    事实证明,在更新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.
        ...
    

    删除connect()调用中的AutoCommit => 0标志解决了我的问题 .

相关问题