SQLite

Check-in [311d0b61]
Login

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

Overview
Comment:When committing a WAL transaction, do not write any pages to the WAL file with page numbers greater than the size of the database image in pages.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 311d0b613d9cfa2dbcbb9ef2450041b1fd48770a
User & Date: dan 2011-04-05 16:09:08
Context
2011-04-05
17:31
Remove the mutex counter and the logic that attempts to verify that btree mutexes are held continuously. We are not making that assumption at this time. (check-in: 242ce7cf user: drh tags: trunk)
16:09
When committing a WAL transaction, do not write any pages to the WAL file with page numbers greater than the size of the database image in pages. (check-in: 311d0b61 user: dan tags: trunk)
14:22
Fix a documentation typo. (check-in: d25c17ef user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

2967
2968
2969
2970
2971
2972
2973













2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986

2987
2988
2989
2990
2991
2992
2993
  assert( pPager->pWal );
#ifdef SQLITE_DEBUG
  /* Verify that the page list is in accending order */
  for(p=pList; p && p->pDirty; p=p->pDirty){
    assert( p->pgno < p->pDirty->pgno );
  }
#endif














  if( pList->pgno==1 ) pager_write_changecounter(pList);
  rc = sqlite3WalFrames(pPager->pWal, 
      pPager->pageSize, pList, nTruncate, isCommit, syncFlags
  );
  if( rc==SQLITE_OK && pPager->pBackup ){
    PgHdr *p;
    for(p=pList; p; p=p->pDirty){
      sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
    }
  }

#ifdef SQLITE_CHECK_PAGES

  for(p=pList; p; p=p->pDirty){
    pager_set_pagehash(p);
  }
#endif

  return rc;
}







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













>







2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
  assert( pPager->pWal );
#ifdef SQLITE_DEBUG
  /* Verify that the page list is in accending order */
  for(p=pList; p && p->pDirty; p=p->pDirty){
    assert( p->pgno < p->pDirty->pgno );
  }
#endif

  if( isCommit ){
    /* If a WAL transaction is being committed, there is no point in writing
    ** any pages with page numbers greater than nTruncate into the WAL file.
    ** They will never be read by any client. So remove them from the pDirty
    ** list here. */
    PgHdr *p;
    PgHdr **ppNext = &pList;
    for(p=pList; (*ppNext = p); p=p->pDirty){
      if( p->pgno<=nTruncate ) ppNext = &p->pDirty;
    }
    assert( pList );
  }

  if( pList->pgno==1 ) pager_write_changecounter(pList);
  rc = sqlite3WalFrames(pPager->pWal, 
      pPager->pageSize, pList, nTruncate, isCommit, syncFlags
  );
  if( rc==SQLITE_OK && pPager->pBackup ){
    PgHdr *p;
    for(p=pList; p; p=p->pDirty){
      sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
    }
  }

#ifdef SQLITE_CHECK_PAGES
  pList = sqlite3PcacheDirtyList(pPager->pPCache);
  for(p=pList; p; p=p->pDirty){
    pager_set_pagehash(p);
  }
#endif

  return rc;
}

Changes to test/wal.test.

14
15
16
17
18
19
20


21
22
23
24
25
26
27
#

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



ifcapable !wal {finish_test ; return }

proc reopen_db {} {
  catch { db close }
  file delete -force test.db test.db-wal test.db-wal-summary
  sqlite3_wal db test.db







>
>







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

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

set testprefix wal

ifcapable !wal {finish_test ; return }

proc reopen_db {} {
  catch { db close }
  file delete -force test.db test.db-wal test.db-wal-summary
  sqlite3_wal db test.db
1500
1501
1502
1503
1504
1505
1506





























1507



















1508
1509
1510
1511
1512
  execsql { SELECT * FROM t1 }
} {1 2 3 4}
set nPage [expr 2+$AUTOVACUUM]
do_test wal-23.4 { 
  set ::log 
} [list SQLITE_OK "Recovered $nPage frames from WAL file $walfile"]






























db close



















sqlite3_shutdown
test_sqlite3_log
sqlite3_initialize

finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
  execsql { SELECT * FROM t1 }
} {1 2 3 4}
set nPage [expr 2+$AUTOVACUUM]
do_test wal-23.4 { 
  set ::log 
} [list SQLITE_OK "Recovered $nPage frames from WAL file $walfile"]


ifcapable autovacuum {
  # This block tests that if the size of a database is reduced by a 
  # transaction (because of an incremental or auto-vacuum), that no
  # data is written to the WAL file for the truncated pages as part
  # of the commit. e.g. if a transaction reduces the size of a database
  # to N pages, data for page N+1 should not be written to the WAL file 
  # when committing the transaction. At one point such data was being 
  # written.
  #
  catch {db close}
  forcedelete test.db
  sqlite3 db test.db
  do_execsql_test 24.1 {
    PRAGMA auto_vacuum = 2;
    PRAGMA journal_mode = WAL;
    PRAGMA page_size = 1024;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(randomblob(5000));
    INSERT INTO t1 SELECT * FROM t1;
    INSERT INTO t1 SELECT * FROM t1;
    INSERT INTO t1 SELECT * FROM t1;
    INSERT INTO t1 SELECT * FROM t1;
  } {wal}
  do_execsql_test 24.2 { 
    DELETE FROM t1;
    PRAGMA wal_checkpoint;
  } {0 109 109}
  do_test 24.3 {
    db close
    sqlite3 db test.db
    file exists test.db-wal
  } 0
  do_test 24.4 {
    file size test.db
  } [expr 84 * 1024]
  do_test 24.5 {
    execsql { 
      PRAGMA incremental_vacuum;
      PRAGMA wal_checkpoint;
    }
    file size test.db
  } [expr 3 * 1024]
  do_test 24.6 {
    file size test.db-wal
  } 2128
}

db close
sqlite3_shutdown
test_sqlite3_log
sqlite3_initialize

finish_test