SQLite

Check-in [8b3b5ab8fa]
Login

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

Overview
Comment:Test another IO error case in wal.c.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8b3b5ab8fa61ca4ef22c98abaab397707ee74ea3
User & Date: dan 2010-05-07 09:43:50.000
Context
2010-05-07
12:49
Change wal.test and walhook.test so that they work with DEFAULT_AUTOVACUUM=1 builds. (check-in: 4cde92909c user: dan tags: trunk)
09:43
Test another IO error case in wal.c. (check-in: 8b3b5ab8fa user: dan tags: trunk)
06:59
Fix a problem with checkpointing large log files created by an external process. (check-in: 8f94bde568 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/test_vfs.c.
486
487
488
489
490
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
  int *pMapSize, 
  void **pp
){
  int rc = SQLITE_OK;
  Testvfs *p = (Testvfs *)(pVfs->pAppData);
  TestvfsShm *pShm = (TestvfsShm *)pShmHandle;

  tvfsGrowBuffer(pShm, reqMapSize, pMapSize);
  tvfsExecTcl(p, "xShmGet", 
      Tcl_NewStringObj(pShm->pBuffer->zFile, -1), pShm->id, 0
  );
  tvfsResultCode(p, &rc);
  if( rc==SQLITE_OK ){

    *pp = pShm->pBuffer->a;
  }
  return rc;
}

static int tvfsShmRelease(sqlite3_vfs *pVfs, sqlite3_shm *pShmHandle){
  int rc = SQLITE_OK;







<





>







486
487
488
489
490
491
492

493
494
495
496
497
498
499
500
501
502
503
504
505
  int *pMapSize, 
  void **pp
){
  int rc = SQLITE_OK;
  Testvfs *p = (Testvfs *)(pVfs->pAppData);
  TestvfsShm *pShm = (TestvfsShm *)pShmHandle;


  tvfsExecTcl(p, "xShmGet", 
      Tcl_NewStringObj(pShm->pBuffer->zFile, -1), pShm->id, 0
  );
  tvfsResultCode(p, &rc);
  if( rc==SQLITE_OK ){
    tvfsGrowBuffer(pShm, reqMapSize, pMapSize);
    *pp = pShm->pBuffer->a;
  }
  return rc;
}

static int tvfsShmRelease(sqlite3_vfs *pVfs, sqlite3_shm *pShmHandle){
  int rc = SQLITE_OK;
Changes to src/wal.c.
407
408
409
410
411
412
413
414


415
416
417
418
419
420
421
                             &pWal->szWIndex, (void**)(char*)&pWal->pWiData);
    if( rc==SQLITE_OK && pWal->pWiData==0 ){
      /* Make sure pWal->pWiData is not NULL while we are holding the
      ** lock on the mapping. */
      assert( pWal->szWIndex==0 );
      pWal->pWiData = &pWal->iCallback;
    }
    assert( rc==SQLITE_OK || pWal->pWiData==0 );


  }
  return rc;
}

/*
** Remap the wal-index so that the mapping covers the full size
** of the underlying file.







|
>
>







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
                             &pWal->szWIndex, (void**)(char*)&pWal->pWiData);
    if( rc==SQLITE_OK && pWal->pWiData==0 ){
      /* Make sure pWal->pWiData is not NULL while we are holding the
      ** lock on the mapping. */
      assert( pWal->szWIndex==0 );
      pWal->pWiData = &pWal->iCallback;
    }
    if( rc!=SQLITE_OK ){
      walIndexUnmap(pWal);
    }
  }
  return rc;
}

/*
** Remap the wal-index so that the mapping covers the full size
** of the underlying file.
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
        rc = SQLITE_BUSY;
      }
      walIndexUnmap(pWal);
      if( rc!=SQLITE_OK ){
        walSetLock(pWal, SQLITE_SHM_READ);
      }
    }
  }else if( pWal->lockState==SQLITE_SHM_WRITE ){
    rc = walSetLock(pWal, SQLITE_SHM_READ);
  }
  return rc;
}

/*
** If any data has been written (but not committed) to the log file, this







|







1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
        rc = SQLITE_BUSY;
      }
      walIndexUnmap(pWal);
      if( rc!=SQLITE_OK ){
        walSetLock(pWal, SQLITE_SHM_READ);
      }
    }
  }else if( ALWAYS( pWal->lockState==SQLITE_SHM_WRITE ) ){
    rc = walSetLock(pWal, SQLITE_SHM_READ);
  }
  return rc;
}

/*
** If any data has been written (but not committed) to the log file, this
Changes to test/walfault.test.
245
246
247
248
249
250
251












































































252
253
254
  BEGIN;
    INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 1 */
    INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 2 */
    INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 4 */
    INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 8 */
  ROLLBACK;
}













































































finish_test








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



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
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
  BEGIN;
    INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 1 */
    INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 2 */
    INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 4 */
    INSERT INTO abc SELECT randomblob(900) FROM abc;    /* 8 */
  ROLLBACK;
}

#-------------------------------------------------------------------------
# When a database is checkpointed, SQLite does the following:
#
#   1. xShmLock(CHECKPOINT) to lock the WAL.
#   2. xShmGet(-1) to get a mapping to read the wal-index header.
#   3. If the mapping obtained in (2) is not large enough to cover the
#      entire wal-index, call xShmGet(nReq) to get a larger mapping.
#   4. Do the checkpoint.
#   5. Release the lock and mapping.
#
# This test case tests the outcome of an IO error in step 2.
#
proc shmfault_vfs_cb_6 {method args} {
  switch -- $::shm_state {
    0 { return SQLITE_OK }
    1 {
      if {$method == "xShmGet"} {
        set ::wal_index [tvfs shm [lindex $args 0]]
        tvfs shm [lindex $args 0] [string range $::wal_index 0 65535]
        set ::shm_state 2
      }
    }
    2 {
      if {$method == "xShmGet"} {
        tvfs shm [lindex $args 0] $::wal_index
        return SQLITE_IOERR
      }
    }
  }
  return SQLITE_OK
}
do_test walfault-shm-6.1 {
  set ::shm_state 0
  testvfs tvfs shmfault_vfs_cb_6

  sqlite3 db  test.db -vfs tvfs
  sqlite3 db2 test.db -vfs tvfs

  execsql {
    PRAGMA journal_mode = WAL;
    PRAGMA wal_autocheckpoint = 0;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(randomblob(900));
  }
} {wal 0}
do_test walfault-shm-6.2 {
  execsql {
    PRAGMA wal_autocheckpoint = 0;
    BEGIN;
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 2 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 4 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 8 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 16 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 32 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 64 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 128 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 256 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 512 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 1024 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 2048 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 4096 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 8192 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;    /* 16384 */
    COMMIT;
  } db2
} {0}
do_test walfault-shm-6.3 {
  set ::shm_state 1
  catchsql { PRAGMA wal_checkpoint } db2
} {1 {disk I/O error}}
set ::shm_state 0
db close
db2 close
tvfs delete
unset -nocomplain ::wal_index ::shm_state

finish_test