SQLite

Check-in [ea8507a796]
Login

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

Overview
Comment:Fix the pager so that it handles persistent I/O errors correctly. Update the testing infrastructure so that it tests for persistent I/O errors instead of just transient errors. (CVS 3690)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ea8507a796c65041f7e720edea89f919fca1a028
User & Date: drh 2007-03-15 12:51:16.000
Context
2007-03-15
15:33
Check for multiple calls to sqlite3FailedMalloc(). Ignore the second and subsequent calls. (CVS 3691) (check-in: 7180874592 user: danielk1977 tags: trunk)
12:51
Fix the pager so that it handles persistent I/O errors correctly. Update the testing infrastructure so that it tests for persistent I/O errors instead of just transient errors. (CVS 3690) (check-in: ea8507a796 user: drh tags: trunk)
12:17
Infrastructure to make simulated I/O errors persistent instead of transient. (CVS 3689) (check-in: 1a53f531ec user: drh tags: trunk)
Changes
Side-by-Side Diff Show Whitespace Changes Patch
Changes to src/os_common.h.
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116







-
+











+







#ifdef SQLITE_TEST
int sqlite3_io_error_hit = 0;
int sqlite3_io_error_pending = 0;
int sqlite3_io_error_persist = 0;
int sqlite3_diskfull_pending = 0;
int sqlite3_diskfull = 0;
#define SimulateIOError(CODE)  \
   if( sqlite3_io_error_pending ) \
  if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \
     if( sqlite3_io_error_pending-- == 1 \
         || (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \
                { local_ioerr(); CODE; }
static void local_ioerr(){
  sqlite3_io_error_hit = 1;
}
#define SimulateDiskfullError(CODE) \
   if( sqlite3_diskfull_pending ){ \
     if( sqlite3_diskfull_pending == 1 ){ \
       local_ioerr(); \
       sqlite3_diskfull = 1; \
       sqlite3_io_error_hit = 1; \
       CODE; \
     }else{ \
       sqlite3_diskfull_pending--; \
     } \
   }
#else
#define SimulateIOError(A)
Changes to src/pager.c.
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28







-
+







** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.287 2007/03/15 01:16:48 drh Exp $
** @(#) $Id: pager.c,v 1.288 2007/03/15 12:51:16 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
1856
1857
1858
1859
1860
1861
1862



1863
1864
1865
1866
1867
1868
1869
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872







+
+
+







** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
** file is 4096 bytes, 5 is returned instead of 4.
*/
int sqlite3pager_pagecount(Pager *pPager){
  i64 n;
  int rc;
  assert( pPager!=0 );
  if( pPager->errCode ){
    return 0;
  }
  if( pPager->dbSize>=0 ){
    n = pPager->dbSize;
  } else {
    if( (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
      pager_error(pPager, rc);
      return 0;
    }
Changes to test/diskfull.test.
8
9
10
11
12
13
14
15

16
17
18
19



20
21
22
23
24
25
26
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29







-
+




+
+
+







#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing for correct handling of disk full
# errors.
# 
# $Id: diskfull.test,v 1.3 2005/09/09 10:46:19 drh Exp $
# $Id: diskfull.test,v 1.4 2007/03/15 12:51:17 drh Exp $

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

set sqlite_io_error_persist 0
set sqlite_io_error_hit 0
set sqlite_io_error_pending 0
do_test diskfull-1.1 {
  execsql {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(randstr(1000,1000));
    INSERT INTO t1 SELECT * FROM t1;
    INSERT INTO t1 SELECT * FROM t1;
    INSERT INTO t1 SELECT * FROM t1;
43
44
45
46
47
48
49

50
51
52
53
54
55
56
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60







+







do_test diskfull-1.5 {
  set sqlite_diskfull_pending 1
  catchsql {
    DELETE FROM t1;
  }
} {1 {database or disk is full}}
set sqlite_diskfull_pending 0
set sqlite_io_error_hit 0
integrity_check diskfull-1.6

set go 1
set i 0
while {$go} {
  incr i
  do_test diskfull-2.$i.1 {