/ Check-in [ea8507a7]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ea8507a796c65041f7e720edea89f919fca1a028
User & Date: drh 2007-03-15 12:51:16
Context
2007-03-15
15:33
Check for multiple calls to sqlite3FailedMalloc(). Ignore the second and subsequent calls. (CVS 3691) check-in: 71808745 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: ea8507a7 user: drh tags: trunk
12:17
Infrastructure to make simulated I/O errors persistent instead of transient. (CVS 3689) check-in: 1a53f531 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_common.h.

    90     90   #ifdef SQLITE_TEST
    91     91   int sqlite3_io_error_hit = 0;
    92     92   int sqlite3_io_error_pending = 0;
    93     93   int sqlite3_io_error_persist = 0;
    94     94   int sqlite3_diskfull_pending = 0;
    95     95   int sqlite3_diskfull = 0;
    96     96   #define SimulateIOError(CODE)  \
    97         -   if( sqlite3_io_error_pending ) \
           97  +  if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \
    98     98        if( sqlite3_io_error_pending-- == 1 \
    99     99            || (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \
   100    100                   { local_ioerr(); CODE; }
   101    101   static void local_ioerr(){
   102    102     sqlite3_io_error_hit = 1;
   103    103   }
   104    104   #define SimulateDiskfullError(CODE) \
   105    105      if( sqlite3_diskfull_pending ){ \
   106    106        if( sqlite3_diskfull_pending == 1 ){ \
   107    107          local_ioerr(); \
   108    108          sqlite3_diskfull = 1; \
          109  +       sqlite3_io_error_hit = 1; \
   109    110          CODE; \
   110    111        }else{ \
   111    112          sqlite3_diskfull_pending--; \
   112    113        } \
   113    114      }
   114    115   #else
   115    116   #define SimulateIOError(A)

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.287 2007/03/15 01:16:48 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.288 2007/03/15 12:51:16 drh Exp $
    22     22   */
    23     23   #ifndef SQLITE_OMIT_DISKIO
    24     24   #include "sqliteInt.h"
    25     25   #include "os.h"
    26     26   #include "pager.h"
    27     27   #include <assert.h>
    28     28   #include <string.h>
................................................................................
  1856   1856   ** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
  1857   1857   ** file is 4096 bytes, 5 is returned instead of 4.
  1858   1858   */
  1859   1859   int sqlite3pager_pagecount(Pager *pPager){
  1860   1860     i64 n;
  1861   1861     int rc;
  1862   1862     assert( pPager!=0 );
         1863  +  if( pPager->errCode ){
         1864  +    return 0;
         1865  +  }
  1863   1866     if( pPager->dbSize>=0 ){
  1864   1867       n = pPager->dbSize;
  1865   1868     } else {
  1866   1869       if( (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
  1867   1870         pager_error(pPager, rc);
  1868   1871         return 0;
  1869   1872       }

Changes to test/diskfull.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing for correct handling of disk full
    13     13   # errors.
    14     14   # 
    15         -# $Id: diskfull.test,v 1.3 2005/09/09 10:46:19 drh Exp $
           15  +# $Id: diskfull.test,v 1.4 2007/03/15 12:51:17 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
           20  +set sqlite_io_error_persist 0
           21  +set sqlite_io_error_hit 0
           22  +set sqlite_io_error_pending 0
    20     23   do_test diskfull-1.1 {
    21     24     execsql {
    22     25       CREATE TABLE t1(x);
    23     26       INSERT INTO t1 VALUES(randstr(1000,1000));
    24     27       INSERT INTO t1 SELECT * FROM t1;
    25     28       INSERT INTO t1 SELECT * FROM t1;
    26     29       INSERT INTO t1 SELECT * FROM t1;
................................................................................
    43     46   do_test diskfull-1.5 {
    44     47     set sqlite_diskfull_pending 1
    45     48     catchsql {
    46     49       DELETE FROM t1;
    47     50     }
    48     51   } {1 {database or disk is full}}
    49     52   set sqlite_diskfull_pending 0
           53  +set sqlite_io_error_hit 0
    50     54   integrity_check diskfull-1.6
    51     55   
    52     56   set go 1
    53     57   set i 0
    54     58   while {$go} {
    55     59     incr i
    56     60     do_test diskfull-2.$i.1 {