SQLite

Check-in [8f94bde568]
Login

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

Overview
Comment:Fix a problem with checkpointing large log files created by an external process.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8f94bde568be52ecc5a976b7a09776ea7b4bb511
User & Date: dan 2010-05-07 06:59:09.000
Context
2010-05-07
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)
05:46
Since walIndexTryHdr() can no longer encounter any error conditions, change tehe function signature so that it does not return an error code. This removes unreachable branches from other code. (check-in: 061a282cc0 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/wal.c.
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
  }
}

/*
** Map the wal-index file into memory if it isn't already. 
**
** The reqSize parameter is the minimum required size of the mapping.
** A value of -1 means "don't care".  The reqSize parameter is ignored
** if the mapping is already held.
*/
static int walIndexMap(Wal *pWal, int reqSize){
  int rc = SQLITE_OK;
  if( pWal->pWiData==0 ){
    rc = pWal->pVfs->xShmGet(pWal->pVfs, pWal->pWIndex, reqSize,
                             &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;







|
<



|







394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
  }
}

/*
** Map the wal-index file into memory if it isn't already. 
**
** The reqSize parameter is the minimum required size of the mapping.
** A value of -1 means "don't care".

*/
static int walIndexMap(Wal *pWal, int reqSize){
  int rc = SQLITE_OK;
  if( pWal->pWiData==0 || reqSize>pWal->szWIndex ){
    rc = pWal->pVfs->xShmGet(pWal->pVfs, pWal->pWIndex, reqSize,
                             &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;
Changes to test/wal.test.
54
55
56
57
58
59
60

61
62
63
64
65
66
67
# wal-1.*: Read and write the database.
# wal-2.*: Test MVCC with one reader, one writer.
# wal-3.*: Test transaction rollback.
# wal-4.*: Test savepoint/statement rollback.
# wal-5.*: Test the temp database.
# wal-6.*: Test creating databases with different page sizes.
#


do_test wal-0.1 {
  execsql { PRAGMA synchronous = normal }
  execsql { PRAGMA journal_mode = wal }
} {wal}
do_test wal-0.2 {
  file size test.db







>







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# wal-1.*: Read and write the database.
# wal-2.*: Test MVCC with one reader, one writer.
# wal-3.*: Test transaction rollback.
# wal-4.*: Test savepoint/statement rollback.
# wal-5.*: Test the temp database.
# wal-6.*: Test creating databases with different page sizes.
#
#

do_test wal-0.1 {
  execsql { PRAGMA synchronous = normal }
  execsql { PRAGMA journal_mode = wal }
} {wal}
do_test wal-0.2 {
  file size test.db
1393
1394
1395
1396
1397
1398
1399
1400































































1401
1402
1403
1404
1405
  # When the bug was present, the following was returning {1 2 3 4} only,
  # as [db2] had an out-of-date copy of the wal-index header when it was
  # closed.
  #
  sqlite3 db test.db
  execsql { SELECT * FROM t1 }
} {1 2 3 4 5 6}
































































catch { db2 close }
catch { db close }

finish_test









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





1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
  # When the bug was present, the following was returning {1 2 3 4} only,
  # as [db2] had an out-of-date copy of the wal-index header when it was
  # closed.
  #
  sqlite3 db test.db
  execsql { SELECT * FROM t1 }
} {1 2 3 4 5 6}

#-------------------------------------------------------------------------
# This test - wal-20.* - uses two connections. One in this process and
# the other in an external process. The procedure is:
#
#   1. Using connection 1, create the database schema.
#
#   2. Using connection 2 (in an external process), add so much
#      data to the database without checkpointing that a wal-index 
#      larger than 64KB is required.
#
#   3. Using connection 1, checkpoint the database. Make sure all
#      the data is present and the database is not corrupt.
#
# At one point, SQLite was failing to grow the mapping of the wal-index
# file in step 3 and the checkpoint was corrupting the database file.
#
do_test wal-20.1 {
  file delete -force test.db test.db-wal test.db-journal
  sqlite3 db test.db
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(randomblob(900));
    SELECT count(*) FROM t1;
  }
} {wal 1}
do_test wal-20.2 {
  set ::buddy [launch_testfixture]
  testfixture $::buddy {
    sqlite3 db test.db
    db transaction { db eval {
      PRAGMA wal_autocheckpoint = 0;
      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 */
    } }
  }
} {0}
do_test wal-20.3 {
  close $::buddy
  execsql {
    PRAGMA wal_checkpoint;
    SELECT count(*) FROM t1;
  }
} {16384}
do_test wal-20.4 {
  db close
  sqlite3 db test.db
  execsql { SELECT count(*) FROM t1 }
} {16384}
integrity_check wal-20.5

catch { db2 close }
catch { db close }

finish_test