SQLite4
Check-in [e64f3ba5f0]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a couple of problems related to log recovery and checkpointing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e64f3ba5f09f21b0b9ad01713100a64f8cfad6ad
User & Date: dan 2014-02-19 11:28:29
Context
2014-02-21
17:36
Performance tweaks for seek operations. check-in: 18ae7f9855 user: dan tags: trunk
2014-02-19
11:28
Fix a couple of problems related to log recovery and checkpointing. check-in: e64f3ba5f0 user: dan tags: trunk
2014-02-18
20:01
Add crash simulation and recovery test infrastructure. And one test case. check-in: cd8da865a4 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/bt_log.c.

  1023   1023       assert( rc!=SQLITE4_NOTFOUND );
  1024   1024   
  1025   1025       /* Based on the wal-header, the page-size and number of pages in the
  1026   1026       ** database are now known and stored in snapshot.dbhdr. But the other
  1027   1027       ** header field values (iCookie, iRoot etc.) are still unknown. Read
  1028   1028       ** them from page 1 of the database file now.  */
  1029   1029       if( rc==SQLITE4_OK ){
         1030  +      u32 nPg = pLog->snapshot.dbhdr.nPg;
  1030   1031         rc = btLogReadDbhdr(pLog, &pLog->snapshot.dbhdr, ctx.iPageOneFrame);
         1032  +      if( ctx.iLast>0 ){
         1033  +        pLog->snapshot.dbhdr.nPg = nPg;
         1034  +      }
  1031   1035       }
  1032   1036   
  1033   1037     }else if( rc==SQLITE4_OK ){
  1034   1038       /* There is no data in the log file. Read the database header directly
  1035   1039       ** from offset 0 of the database file.  */
  1036   1040       btLogZeroSnapshot(pLog);
  1037   1041       rc = btLogReadDbhdr(pLog, &pLog->snapshot.dbhdr, 0);
................................................................................
  1890   1894       }
  1891   1895   
  1892   1896       if( rc==SQLITE4_OK && nPgno>0 ){
  1893   1897         i64 iOff = btLogFrameOffset(pLog, pgsz, iLast);
  1894   1898   
  1895   1899         /* Ensure the log has been synced to disk */
  1896   1900         if( rc==SQLITE4_OK ){
  1897         -        rc = btLogSyncFile(pLog, pLog->pLock->pFd);
         1901  +        rc = btLogSyncFile(pLog, pLog->pFd);
  1898   1902         }
  1899   1903   
  1900   1904         rc = btLogReadData(pLog, iOff, (u8*)&fhdr, sizeof(BtFrameHdr));
  1901   1905         iFirstRead = fhdr.iNext;
  1902   1906   
  1903   1907         /* Copy data from the log file to the database file. */
  1904   1908         for(i=0; rc==SQLITE4_OK && i<nPgno; i++){

Changes to test/permutations.test.

   131    131   #   full
   132    132   #
   133    133   lappend ::testsuitelist xxx
   134    134   
   135    135   test_suite "bt" -prefix "bt-" -description {
   136    136   } -files {
   137    137   bt1.test
          138  +recover1.test recover2.test
          139  +
   138    140   aggerror.test
   139    141   alter.test
   140    142   alter3.test
   141    143   alter4.test
   142    144   analyze.test
   143    145   analyze3.test
   144    146   analyze4.test

Changes to test/recover1.test.

     5      5   #
     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
           12  +# This file contains tests that verify that the bt backend can recover
           13  +# data from the types of log files that might be left in the file-system
           14  +# following a power failure.
           15  +#
    12     16   
    13     17   set testdir [file dirname $argv0]
    14     18   source $testdir/tester.tcl
    15     19   source $testdir/malloc_common.tcl
    16     20   set ::testprefix recover1
    17     21   
    18     22   
................................................................................
    81     85   
    82     86     do_test 1.2.$i.2 { 
    83     87       sqlite4 db test.db
    84     88       checkdb 
    85     89     } 1
    86     90   
    87     91     do_execsql_test 1.2.$i.3 { SELECT count(*) FROM t1 } [expr $nRow*2]
    88         -  do_execsql_test 1.2.$i.4 { DELETE FROM t1 WHERE rowid%2 }
           92  +  do_execsql_test 1.2.$i.4 { DELETE FROM t1 WHERE rowid>8 }
    89     93   }
    90     94   
    91     95   finish_test
    92     96   
    93     97   
    94     98   
    95     99   

Added test/recover2.test.

            1  +# 2014 February 19
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file contains tests that verify that the bt backend can recover
           13  +# data from the types of log files that might be left in the file-system
           14  +# following an application crash.
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +source $testdir/malloc_common.tcl
           20  +set ::testprefix recover2
           21  +
           22  +
           23  +proc checkdb {db} {
           24  +  $db one { SELECT (SELECT x FROM sum)==(SELECT md5sum(a, b) FROM t1); }
           25  +}
           26  +
           27  +do_execsql_test 1.0 {
           28  +  CREATE TABLE t1(a, b);
           29  +  CREATE TABLE sum(x);
           30  +
           31  +  INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
           32  +  INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
           33  +  INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
           34  +  INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
           35  +  INSERT INTO sum SELECT md5sum(a, b) FROM t1;
           36  +}
           37  +do_test 1.1 { checkdb db } 1
           38  +
           39  +for {set i 1} {$i<25} {incr i} {
           40  +  set nRow [db one {SELECT count(*) FROM t1}]
           41  +
           42  +  do_execsql_test 1.2.$i.1 {
           43  +    BEGIN;
           44  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
           45  +    UPDATE sum SET x = (SELECT md5sum(a, b) FROM t1);
           46  +    COMMIT;
           47  +  } 
           48  +
           49  +  do_test 1.2.$i.2 { 
           50  +    forcecopy test.db test.db2
           51  +    forcecopy test.db-wal test.db2-wal
           52  +
           53  +    sqlite4 db2 test.db2
           54  +    breakpoint
           55  +    checkdb db2
           56  +  } 1
           57  +
           58  +  do_test 1.2.$i.3 { 
           59  +    execsql { SELECT count(*) FROM t1 } db2
           60  +  } [expr $nRow*2]
           61  +  db2 close
           62  +
           63  +  do_execsql_test 1.2.$i.4 { DELETE FROM t1 WHERE rowid>8 }
           64  +}
           65  +
           66  +finish_test
           67  +
           68  +