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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e64f3ba5f09f21b0b9ad01713100a64f8cfad6ad
User & Date: dan 2014-02-19 11:28:29.504
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
Unified Diff Show Whitespace Changes Patch
Changes to src/bt_log.c.
1023
1024
1025
1026
1027
1028
1029

1030



1031
1032
1033
1034
1035
1036
1037
    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);







>

>
>
>







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
    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);
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
    }

    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++){







|







1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
    }

    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.
1
2
3
4
5
6
7
8
9
10
11




12
13
14
15
16
17
18
# 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.
#
#***********************************************************************
#





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













>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 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 a power failure.
#

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


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

  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











|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

  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