/ Check-in [2eaf5ee0]
Login

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

Overview
Comment:When synchronous=NORMAL, use the same journal file format as with synchronous=FULL (i.e. multiple journal headers within the one journal). Fix for [d11f09d36e].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2eaf5ee0d9338de8a77fb3e06ad2f2b0daa6fcbe
User & Date: dan 2010-06-26 15:42:34
Context
2010-06-26
17:15
Fix a case where the doNotSyncSpill flag may remain permanently set following an IO error. check-in: 56c7d111 user: dan tags: trunk
15:42
When synchronous=NORMAL, use the same journal file format as with synchronous=FULL (i.e. multiple journal headers within the one journal). Fix for [d11f09d36e]. check-in: 2eaf5ee0 user: dan tags: trunk
2010-06-25
19:09
Further test cases for pager1.test and pagerfault.test. check-in: bfd563c4 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

3546
3547
3548
3549
3550
3551
3552

3553
3554
3555
3556
3557
3558
3559
3560
3561
    if( rc==SQLITE_OK ){
      rc = pagerWalFrames(pPager, pPg, 0, 0, 0);
    }
  }else{
  
    /* Sync the journal file if required. */
    if( pPg->flags&PGHDR_NEED_SYNC ){

      rc = syncJournal(pPager);
      if( rc==SQLITE_OK && pPager->fullSync && 
        !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) &&
        !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
      ){
        pPager->nRec = 0;
        rc = writeJournalHdr(pPager);
      }
    }







>

|







3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
    if( rc==SQLITE_OK ){
      rc = pagerWalFrames(pPager, pPg, 0, 0, 0);
    }
  }else{
  
    /* Sync the journal file if required. */
    if( pPg->flags&PGHDR_NEED_SYNC ){
      assert( !pPager->noSync );
      rc = syncJournal(pPager);
      if( rc==SQLITE_OK && 
        !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) &&
        !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
      ){
        pPager->nRec = 0;
        rc = writeJournalHdr(pPager);
      }
    }

Changes to test/pager1.test.

190
191
192
193
194
195
196



197
198
199
200
201
202
203
...
224
225
226
227
228
229
230











231

232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
























263
264
265
266
267
268
269
}

#-------------------------------------------------------------------------
# Savepoint related test cases.
#
# pager1-3.1.2.*: Force a savepoint rollback to cause the database file
#                 to grow.



# 
do_test pager1-3.1.1 {
  faultsim_delete_and_reopen
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TABLE counter(
      i CHECK (i<5), 
................................................................................
do_catchsql_test pager1-3.1.3 {
    INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1
} {1 {constraint failed}}
do_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0}
do_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3}
do_execsql_test pager1-3.6 { COMMIT } {}












do_test pager1-3.2.1 {

  faultsim_delete_and_reopen
  db func a_string a_string

  execsql {
    PRAGMA auto_vacuum = 2;
    PRAGMA cache_size = 10;
    CREATE TABLE z(x INTEGER PRIMARY KEY, y);
    BEGIN;
      INSERT INTO z VALUES(NULL, a_string(800));
      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   2
      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   4
      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   8
      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  16
      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  32
      INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  64
      INSERT INTO z SELECT NULL, a_string(800) FROM z;     -- 128
      INSERT INTO z SELECT NULL, a_string(800) FROM z;     -- 256
    COMMIT;
  }
  execsql { PRAGMA auto_vacuum }
} {2}
do_execsql_test pager1-3.2.2 {
  BEGIN;
    INSERT INTO z VALUES(NULL, a_string(800));
    INSERT INTO z VALUES(NULL, a_string(800));
    SAVEPOINT one;
      DELETE FROM z WHERE x>256;
      PRAGMA incremental_vacuum;
      SELECT count(*) FROM z WHERE x < 100;
    ROLLBACK TO one;
  COMMIT;
} {99}

























#-------------------------------------------------------------------------
# Hot journal rollback related test cases.
#
# pager1.4.1.*: Test that the pager module deletes very small invalid
#               journal files.
#







>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
}

#-------------------------------------------------------------------------
# Savepoint related test cases.
#
# pager1-3.1.2.*: Force a savepoint rollback to cause the database file
#                 to grow.
#
# pager1-3.1.3.*: Use a journal created in synchronous=off mode as part
#                 of a savepoint rollback.
# 
do_test pager1-3.1.1 {
  faultsim_delete_and_reopen
  execsql {
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE TABLE counter(
      i CHECK (i<5), 
................................................................................
do_catchsql_test pager1-3.1.3 {
    INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1
} {1 {constraint failed}}
do_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0}
do_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3}
do_execsql_test pager1-3.6 { COMMIT } {}

foreach {tn sql tcl} {
  9  { PRAGMA synchronous = NORMAL } { }

  7  { PRAGMA synchronous = NORMAL } {
    testvfs tv -default 1
    tv devchar safe_append
  }
  8  { PRAGMA synchronous = FULL } { }
  10 { PRAGMA synchronous = OFF } { }
  11 { PRAGMA synchronous = FULL ; PRAGMA fullfsync = 1 } { }
} {
  do_test pager1-3.$tn.1 {
    eval $tcl
    faultsim_delete_and_reopen
    db func a_string a_string
    execsql $sql
    execsql {
      PRAGMA auto_vacuum = 2;
      PRAGMA cache_size = 10;
      CREATE TABLE z(x INTEGER PRIMARY KEY, y);
      BEGIN;
        INSERT INTO z VALUES(NULL, a_string(800));
        INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   2
        INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   4
        INSERT INTO z SELECT NULL, a_string(800) FROM z;     --   8
        INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  16
        INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  32
        INSERT INTO z SELECT NULL, a_string(800) FROM z;     --  64
        INSERT INTO z SELECT NULL, a_string(800) FROM z;     -- 128
        INSERT INTO z SELECT NULL, a_string(800) FROM z;     -- 256
      COMMIT;
    }
    execsql { PRAGMA auto_vacuum }
  } {2}
  do_execsql_test pager1-3.$tn.2 {
    BEGIN;
      INSERT INTO z VALUES(NULL, a_string(800));
      INSERT INTO z VALUES(NULL, a_string(800));
      SAVEPOINT one;
        UPDATE z SET y = NULL WHERE x>256;
        PRAGMA incremental_vacuum;
        SELECT count(*) FROM z WHERE x < 100;
      ROLLBACK TO one;
    COMMIT;
  } {99}

  do_execsql_test pager1-3.$tn.3 {
    BEGIN;
      SAVEPOINT one;
        UPDATE z SET y = y||x;
      ROLLBACK TO one;
    COMMIT;
    SELECT count(*) FROM z;
  } {258}

  do_execsql_test pager1-3.$tn.4 {
    SAVEPOINT one;
      UPDATE z SET y = y||x;
    ROLLBACK TO one;
  } {}
  do_execsql_test pager1-3.$tn.5 {
    SELECT count(*) FROM z;
    RELEASE one;
    PRAGMA integrity_check;
  } {258 ok}

  db close
  catch { tv delete }
}

#-------------------------------------------------------------------------
# Hot journal rollback related test cases.
#
# pager1.4.1.*: Test that the pager module deletes very small invalid
#               journal files.
#

Changes to test/pagerfault.test.

18
19
20
21
22
23
24


25
26
27
28
29
30
31
...
417
418
419
420
421
422
423






424
425
426
427
428
429
430
...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
...
458
459
460
461
462
463
464
465











































































466
set a_string_counter 1
proc a_string {n} {
  global a_string_counter
  incr a_string_counter
  string range [string repeat "${a_string_counter}." $n] 1 $n
}
db func a_string a_string



#-------------------------------------------------------------------------
# Test fault-injection while rolling back a hot-journal file.
#
do_test pagerfault-1-pre1 {
  execsql {
    PRAGMA journal_mode = DELETE;
................................................................................
} -body {
  execsql COMMIT
} -test {
  faultsim_test_result {0 {}}
  faultsim_integrity_check
}







do_test pagerfault-9-pre1 {
  faultsim_delete_and_reopen
  execsql {
    PRAGMA auto_vacuum = incremental;
    CREATE TABLE t1(x);
    CREATE TABLE t2(y);
    CREATE TABLE t3(z);
................................................................................

    INSERT INTO t1 VALUES(randomblob(900));
    INSERT INTO t1 VALUES(randomblob(900));
    DELETE FROM t1;
  }
  faultsim_save_and_close
} {}

do_faultsim_test pagerfault-9 -prep {
  faultsim_restore_and_reopen
  execsql { 
    BEGIN;
      INSERT INTO t1 VALUES(randomblob(900));
      INSERT INTO t1 VALUES(randomblob(900));
      DROP TABLE t3;
      DROP TABLE t2;
................................................................................
  faultsim_integrity_check

  set sl [db one { SELECT COALESCE(sum(length(x)), 'null') FROM t1 }]
  if {$sl!="null" && $sl!=1800} { 
    error "Content looks no good... ($sl)" 
  }
}












































































finish_test







>
>







 







>
>
>
>
>
>







 







<
|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
...
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453
...
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
set a_string_counter 1
proc a_string {n} {
  global a_string_counter
  incr a_string_counter
  string range [string repeat "${a_string_counter}." $n] 1 $n
}
db func a_string a_string

if 1 {

#-------------------------------------------------------------------------
# Test fault-injection while rolling back a hot-journal file.
#
do_test pagerfault-1-pre1 {
  execsql {
    PRAGMA journal_mode = DELETE;
................................................................................
} -body {
  execsql COMMIT
} -test {
  faultsim_test_result {0 {}}
  faultsim_integrity_check
}

#-------------------------------------------------------------------------
# This test case is specially designed so that during a savepoint 
# rollback, a new cache entry must be allocated (see comments surrounding
# the call to sqlite3PagerAcquire() from within pager_playback_one_page()
# for details). Test the effects of injecting an OOM at this point.
#
do_test pagerfault-9-pre1 {
  faultsim_delete_and_reopen
  execsql {
    PRAGMA auto_vacuum = incremental;
    CREATE TABLE t1(x);
    CREATE TABLE t2(y);
    CREATE TABLE t3(z);
................................................................................

    INSERT INTO t1 VALUES(randomblob(900));
    INSERT INTO t1 VALUES(randomblob(900));
    DELETE FROM t1;
  }
  faultsim_save_and_close
} {}

do_faultsim_test pagerfault-9.1 -prep {
  faultsim_restore_and_reopen
  execsql { 
    BEGIN;
      INSERT INTO t1 VALUES(randomblob(900));
      INSERT INTO t1 VALUES(randomblob(900));
      DROP TABLE t3;
      DROP TABLE t2;
................................................................................
  faultsim_integrity_check

  set sl [db one { SELECT COALESCE(sum(length(x)), 'null') FROM t1 }]
  if {$sl!="null" && $sl!=1800} { 
    error "Content looks no good... ($sl)" 
  }
}

#-------------------------------------------------------------------------
# Test fault injection with a temporary database file.
#
do_faultsim_test pagerfault-10 -prep {
  sqlite3 db ""
  db func a_string a_string;
  execsql {
    PRAGMA cache_size = 10;
    BEGIN;
      CREATE TABLE xx(a, b, UNIQUE(a, b));
      INSERT INTO xx VALUES(a_string(200), a_string(200));
      INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
      INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
      INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
      INSERT INTO xx SELECT a_string(200), a_string(200) FROM xx;
    COMMIT;
  }
} -body {
  execsql { UPDATE xx SET a = a_string(300) }
} -test {
  faultsim_test_result {0 {}}
  faultsim_integrity_check
  faultsim_integrity_check
}

}

#-------------------------------------------------------------------------
# Test fault injection with transaction savepoints (savepoints created
# when a SAVEPOINT command is executed outside of any other savepoint
# or transaction context).
#
do_test pagerfault-9-pre1 {
  faultsim_delete_and_reopen
  db func a_string a_string;
  execsql {
    PRAGMA auto_vacuum = on;
    CREATE TABLE t1(x UNIQUE);
    CREATE TABLE t2(y UNIQUE);
    CREATE TABLE t3(z UNIQUE);
    BEGIN;
      INSERT INTO t1 VALUES(a_string(202));
      INSERT INTO t2 VALUES(a_string(203));
      INSERT INTO t3 VALUES(a_string(204));
      INSERT INTO t1 SELECT a_string(202) FROM t1;
      INSERT INTO t1 SELECT a_string(203) FROM t1;
      INSERT INTO t1 SELECT a_string(204) FROM t1;
      INSERT INTO t1 SELECT a_string(205) FROM t1;
      INSERT INTO t2 SELECT a_string(length(x)) FROM t1;
      INSERT INTO t3 SELECT a_string(length(x)) FROM t1;
    COMMIT;
  }
  faultsim_save_and_close
} {}
do_faultsim_test pagerfault-11 -prep {
  faultsim_restore_and_reopen
  execsql { PRAGMA cache_size = 10 }
} -body {
  execsql {
    SAVEPOINT trans;
      UPDATE t2 SET y = y||'2';
      INSERT INTO t3 SELECT * FROM t2;
      DELETE FROM t1;
    ROLLBACK TO trans;
    UPDATE t1 SET x = x||'3';
    INSERT INTO t2 SELECT * FROM t1;
    DELETE FROM t3;
    RELEASE trans;
  }
} -test {
  faultsim_test_result {0 {}}
  faultsim_integrity_check
}


finish_test

Added test/pagerfault2.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
# 2010 June 15
#
# 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.
#
#***********************************************************************
#
# The tests in this file test the pager modules response to various
# fault conditions (OOM, IO error, disk full etc.). They are similar
# to those in file pagerfault1.test. 
#
# More specifically, the tests in this file are those deemed too slow to 
# run as part of pagerfault1.test.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl

set a_string_counter 1
proc a_string {n} {
  global a_string_counter
  incr a_string_counter
  string range [string repeat "${a_string_counter}." $n] 1 $n
}
db func a_string a_string


# The following tests, pagerfault2-1.*, attempt to provoke OOM errors when
# manipulating the internal "bitvec" structures. Since bitvec structures
# only allocate memory very rarely, this requires fairly large databases.
#
do_test pagerfault2-1-pre1 {
  faultsim_delete_and_reopen
  db func a_string a_string
  execsql {
    PRAGMA journal_mode = DELETE;
    CREATE TABLE t1(a, b);
    INSERT INTO t1 VALUES(a_string(401), a_string(402));
  }
  for {set ii 0} {$ii < 14} {incr ii} {
    execsql { INSERT INTO t1 SELECT a_string(401), a_string(402) FROM t1 }
  }
  faultsim_save_and_close
} {}
do_faultsim_test pagerfault2-1.1 -faults oom* -prep {
  faultsim_restore_and_reopen
  execsql { 
    BEGIN;
      INSERT INTO t1 VALUES(5, 6);
      SAVEPOINT abc;
        UPDATE t1 SET a = a||'x';
  }
} -body {
  execsql { ROLLBACK TO abc }
} -test {
  faultsim_test_result {0 {}}
  faultsim_integrity_check
}

finish_test

Changes to test/permutations.test.

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173


174
175
176
177
178
179
180
}]

set allquicktests [test_set $alltests -exclude {
  async2.test async3.test backup_ioerr.test corrupt.test
  corruptC.test crash.test crash2.test crash3.test crash4.test crash5.test
  crash6.test crash7.test delete3.test e_fts3.test fts3rnd.test
  fkey_malloc.test fuzz.test fuzz3.test fuzz_malloc.test in2.test loadext.test
  misc7.test mutex2.test notify2.test onefile.test 
  savepoint4.test savepoint6.test select9.test 
  speed1.test speed1p.test speed2.test speed3.test speed4.test 
  speed4p.test sqllimits1.test tkt2686.test thread001.test thread002.test
  thread003.test thread004.test thread005.test trans2.test vacuum3.test 
  incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
  vtab_err.test walslow.test walcrash.test 
  walthread.test
}]

#############################################################################
# Start of tests
#

#-------------------------------------------------------------------------
................................................................................
#
#   coverage-wal
#
test_suite "coverage-wal" -description {
  Coverage tests for file wal.c.
} -files {
  wal.test       wal2.test      wal3.test      walmode.test    
  walbak.test    walhook.test  walcrash2.test  walcksum.test
  walfault.test
} 

test_suite "coverage-pager" -description {
  Coverage tests for file pager.c.
} -files {
  pager1.test
  pager2.test
  pagerfault.test


  journal2.test
} 


lappend ::testsuitelist xxx
#-------------------------------------------------------------------------
# Define the permutation test suites:







|






|







 







|









>
>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
}]

set allquicktests [test_set $alltests -exclude {
  async2.test async3.test backup_ioerr.test corrupt.test
  corruptC.test crash.test crash2.test crash3.test crash4.test crash5.test
  crash6.test crash7.test delete3.test e_fts3.test fts3rnd.test
  fkey_malloc.test fuzz.test fuzz3.test fuzz_malloc.test in2.test loadext.test
  misc7.test mutex2.test notify2.test onefile.test pagerfault2.test 
  savepoint4.test savepoint6.test select9.test 
  speed1.test speed1p.test speed2.test speed3.test speed4.test 
  speed4p.test sqllimits1.test tkt2686.test thread001.test thread002.test
  thread003.test thread004.test thread005.test trans2.test vacuum3.test 
  incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
  vtab_err.test walslow.test walcrash.test 
  walthread.test 
}]

#############################################################################
# Start of tests
#

#-------------------------------------------------------------------------
................................................................................
#
#   coverage-wal
#
test_suite "coverage-wal" -description {
  Coverage tests for file wal.c.
} -files {
  wal.test       wal2.test      wal3.test      walmode.test    
  walbak.test    walhook.test   walcrash2.test walcksum.test
  walfault.test
} 

test_suite "coverage-pager" -description {
  Coverage tests for file pager.c.
} -files {
  pager1.test
  pager2.test
  pagerfault.test
  walfault.test
  walbak.test
  journal2.test
} 


lappend ::testsuitelist xxx
#-------------------------------------------------------------------------
# Define the permutation test suites: