SQLite

Check-in [dc98ee169c]
Login

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

Overview
Comment:If recovery is run before a checkpoint, change back to a CHECKPOINT lock before performing the actual checkpoint.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: dc98ee169cfa43c89f1b36fb1150d4788710fda3
User & Date: dan 2010-05-06 18:27:20.000
Context
2010-05-06
18:48
Instead of transitioning to RECOVER state from CHECKPOINT when a recovery is required, perform the recovery while holding the CHECKPOINT lock. (check-in: bb0b6021e7 user: dan tags: trunk)
18:27
If recovery is run before a checkpoint, change back to a CHECKPOINT lock before performing the actual checkpoint. (check-in: dc98ee169c user: dan tags: trunk)
18:04
Only pass -1 as the size parameter to xShmGet when the caller does not care what size mapping is returned. Only call xShmSize when the underlying allocation (not the mapping) should be resized. (check-in: 637f51ddf9 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/wal.c.
915
916
917
918
919
920
921

922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941

942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
**
** If the wal-index header is successfully read, return SQLITE_OK. 
** Otherwise an SQLite error code.
*/
static int walIndexReadHdr(Wal *pWal, int *pChanged){
  int rc;
  int isValid = 0;


  assert( pWal->lockState>=SQLITE_SHM_READ );
  assert( pChanged );
  rc = walIndexMap(pWal, -1);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  /* First try to read the header without a lock. Verify the checksum
  ** before returning. This will almost always work.  
  */
  rc = walIndexTryHdr(pWal, &isValid, pChanged);
  if( isValid || rc!=SQLITE_OK ){
    return rc;
  }

  /* If the first attempt to read the header failed, lock the wal-index
  ** file and try again. If the header checksum verification fails this
  ** time as well, run log recovery.
  */

  if( SQLITE_OK==(rc = walSetLock(pWal, SQLITE_SHM_RECOVER)) ){
    /* This call to walIndexTryHdr() may not return an error code, as the
    ** wal-index is already mapped. It may find that the header is invalid,
    ** but there is no chance of hitting an actual error.  */
    assert( pWal->pWiData );
    rc = walIndexTryHdr(pWal, &isValid, pChanged);
    assert( rc==SQLITE_OK );
    if( isValid==0 ){
      *pChanged = 1;
      rc = walIndexRecover(pWal);
    }
    walSetLock(pWal, SQLITE_SHM_READ);
  }

  return rc;
}

/*
** Lock a snapshot.







>




















>











|







915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
**
** If the wal-index header is successfully read, return SQLITE_OK. 
** Otherwise an SQLite error code.
*/
static int walIndexReadHdr(Wal *pWal, int *pChanged){
  int rc;
  int isValid = 0;
  int lockState;

  assert( pWal->lockState>=SQLITE_SHM_READ );
  assert( pChanged );
  rc = walIndexMap(pWal, -1);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  /* First try to read the header without a lock. Verify the checksum
  ** before returning. This will almost always work.  
  */
  rc = walIndexTryHdr(pWal, &isValid, pChanged);
  if( isValid || rc!=SQLITE_OK ){
    return rc;
  }

  /* If the first attempt to read the header failed, lock the wal-index
  ** file and try again. If the header checksum verification fails this
  ** time as well, run log recovery.
  */
  lockState = pWal->lockState;
  if( SQLITE_OK==(rc = walSetLock(pWal, SQLITE_SHM_RECOVER)) ){
    /* This call to walIndexTryHdr() may not return an error code, as the
    ** wal-index is already mapped. It may find that the header is invalid,
    ** but there is no chance of hitting an actual error.  */
    assert( pWal->pWiData );
    rc = walIndexTryHdr(pWal, &isValid, pChanged);
    assert( rc==SQLITE_OK );
    if( isValid==0 ){
      *pChanged = 1;
      rc = walIndexRecover(pWal);
    }
    walSetLock(pWal, lockState);
  }

  return rc;
}

/*
** Lock a snapshot.
Changes to test/wal2.test.
331
332
333
334
335
336
337






























338
339
  proc ok {args} {return SQLITE_OK}
  testvfs tvfs ok
  sqlite3 db test.db -vfs tvfs
  catchsql { SELECT * FROM data }
} {0 {{need xShmOpen to see this}}}
db close
tvfs delete































finish_test







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


331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
  proc ok {args} {return SQLITE_OK}
  testvfs tvfs ok
  sqlite3 db test.db -vfs tvfs
  catchsql { SELECT * FROM data }
} {0 {{need xShmOpen to see this}}}
db close
tvfs delete

#-------------------------------------------------------------------------
# Test that if a database connection is forced to run recovery before it
# can perform a checkpoint, it transistions from RECOVERY->CHECKPOINT
# before doing so.
#
do_test wal2-5.1 {
  proc tvfs_cb {method args} {
    set ::shm_file [lindex $args 0]
    if {$method == "xShmLock"} { lappend ::locks [lindex $args 2] }
    return $::tvfs_cb_return
  }
  set tvfs_cb_return SQLITE_OK

  testvfs tvfs tvfs_cb

  sqlite3 db test.db -vfs tvfs
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE x(y);
    INSERT INTO x VALUES(1);
  }

  incr_tvfs_hdr $::shm_file 1 1
  set ::locks [list]
  execsql { PRAGMA wal_checkpoint }
  set ::locks
} {CHECKPOINT RECOVER CHECKPOINT UNLOCK}



finish_test