SQLite4
Check-in [e64f3ba5f0]
Not logged in

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

Overview
SHA1 Hash:e64f3ba5f09f21b0b9ad01713100a64f8cfad6ad
Date: 2014-02-19 11:28:29
User: dan
Comment:Fix a couple of problems related to log recovery and checkpointing.
Tags And Properties
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/bt_log.c

1023
1024
1025
1026
1027
1028
1029

1030



1031
1032
1033
1034
1035
1036
1037
....
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
    assert( rc!=SQLITE4_NOTFOUND );

    /* Based on the wal-header, the page-size and number of pages in the
    ** database are now known and stored in snapshot.dbhdr. But the other
    ** header field values (iCookie, iRoot etc.) are still unknown. Read
    ** them from page 1 of the database file now.  */
    if( rc==SQLITE4_OK ){

      rc = btLogReadDbhdr(pLog, &pLog->snapshot.dbhdr, ctx.iPageOneFrame);



    }

  }else if( rc==SQLITE4_OK ){
    /* There is no data in the log file. Read the database header directly
    ** from offset 0 of the database file.  */
    btLogZeroSnapshot(pLog);
    rc = btLogReadDbhdr(pLog, &pLog->snapshot.dbhdr, 0);
................................................................................
    }

    if( rc==SQLITE4_OK && nPgno>0 ){
      i64 iOff = btLogFrameOffset(pLog, pgsz, iLast);

      /* Ensure the log has been synced to disk */
      if( rc==SQLITE4_OK ){
        rc = btLogSyncFile(pLog, pLog->pLock->pFd);
      }

      rc = btLogReadData(pLog, iOff, (u8*)&fhdr, sizeof(BtFrameHdr));
      iFirstRead = fhdr.iNext;

      /* Copy data from the log file to the database file. */
      for(i=0; rc==SQLITE4_OK && i<nPgno; i++){







>

>
>
>







 







|







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
....
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
    assert( rc!=SQLITE4_NOTFOUND );

    /* Based on the wal-header, the page-size and number of pages in the
    ** database are now known and stored in snapshot.dbhdr. But the other
    ** header field values (iCookie, iRoot etc.) are still unknown. Read
    ** them from page 1 of the database file now.  */
    if( rc==SQLITE4_OK ){
      u32 nPg = pLog->snapshot.dbhdr.nPg;
      rc = btLogReadDbhdr(pLog, &pLog->snapshot.dbhdr, ctx.iPageOneFrame);
      if( ctx.iLast>0 ){
        pLog->snapshot.dbhdr.nPg = nPg;
      }
    }

  }else if( rc==SQLITE4_OK ){
    /* There is no data in the log file. Read the database header directly
    ** from offset 0 of the database file.  */
    btLogZeroSnapshot(pLog);
    rc = btLogReadDbhdr(pLog, &pLog->snapshot.dbhdr, 0);
................................................................................
    }

    if( rc==SQLITE4_OK && nPgno>0 ){
      i64 iOff = btLogFrameOffset(pLog, pgsz, iLast);

      /* Ensure the log has been synced to disk */
      if( rc==SQLITE4_OK ){
        rc = btLogSyncFile(pLog, pLog->pFd);
      }

      rc = btLogReadData(pLog, iOff, (u8*)&fhdr, sizeof(BtFrameHdr));
      iFirstRead = fhdr.iNext;

      /* Copy data from the log file to the database file. */
      for(i=0; rc==SQLITE4_OK && i<nPgno; i++){

Changes to test/permutations.test

131
132
133
134
135
136
137


138
139
140
141
142
143
144
#   full
#
lappend ::testsuitelist xxx

test_suite "bt" -prefix "bt-" -description {
} -files {
bt1.test


aggerror.test
alter.test
alter3.test
alter4.test
analyze.test
analyze3.test
analyze4.test







>
>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#   full
#
lappend ::testsuitelist xxx

test_suite "bt" -prefix "bt-" -description {
} -files {
bt1.test
recover1.test recover2.test

aggerror.test
alter.test
alter3.test
alter4.test
analyze.test
analyze3.test
analyze4.test

Changes to test/recover1.test

5
6
7
8
9
10
11




12
13
14
15
16
17
18
..
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#





set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set ::testprefix recover1


................................................................................

  do_test 1.2.$i.2 { 
    sqlite4 db test.db
    checkdb 
  } 1

  do_execsql_test 1.2.$i.3 { SELECT count(*) FROM t1 } [expr $nRow*2]
  do_execsql_test 1.2.$i.4 { DELETE FROM t1 WHERE rowid%2 }
}

finish_test











>
>
>
>







 







|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests that verify that the bt backend can recover
# data from the types of log files that might be left in the file-system
# following a power failure.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set ::testprefix recover1


................................................................................

  do_test 1.2.$i.2 { 
    sqlite4 db test.db
    checkdb 
  } 1

  do_execsql_test 1.2.$i.3 { SELECT count(*) FROM t1 } [expr $nRow*2]
  do_execsql_test 1.2.$i.4 { DELETE FROM t1 WHERE rowid>8 }
}

finish_test




Added test/recover2.test









































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 2014 February 19
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests that verify that the bt backend can recover
# data from the types of log files that might be left in the file-system
# following an application crash.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set ::testprefix recover2


proc checkdb {db} {
  $db one { SELECT (SELECT x FROM sum)==(SELECT md5sum(a, b) FROM t1); }
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE sum(x);

  INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
  INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
  INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
  INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
  INSERT INTO sum SELECT md5sum(a, b) FROM t1;
}
do_test 1.1 { checkdb db } 1

for {set i 1} {$i<25} {incr i} {
  set nRow [db one {SELECT count(*) FROM t1}]

  do_execsql_test 1.2.$i.1 {
    BEGIN;
    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
    UPDATE sum SET x = (SELECT md5sum(a, b) FROM t1);
    COMMIT;
  } 

  do_test 1.2.$i.2 { 
    forcecopy test.db test.db2
    forcecopy test.db-wal test.db2-wal

    sqlite4 db2 test.db2
    breakpoint
    checkdb db2
  } 1

  do_test 1.2.$i.3 { 
    execsql { SELECT count(*) FROM t1 } db2
  } [expr $nRow*2]
  db2 close

  do_execsql_test 1.2.$i.4 { DELETE FROM t1 WHERE rowid>8 }
}

finish_test