SQLite

Check-in [b54c15f117]
Login

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

Overview
Comment:Avoid using the "direct overflow read" optimization to read large blobs if the pager layer has a wal file open - even if the database header indicates that the db is not a wal database.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b54c15f11796a75683eec4b502a22ccb87d621c6
User & Date: dan 2016-10-21 10:49:39.630
Context
2016-11-03
18:30
Avoid using the "direct overflow read" optimization to read large blobs if the pager layer has a wal file open - even if the database header indicates that the db is not a wal database. (check-in: 63cfe19724 user: drh tags: branch-3.15)
2016-10-21
17:39
Add ".mode quote" to the command-line shell. (check-in: c4f5fa78cd user: drh tags: trunk)
10:49
Avoid using the "direct overflow read" optimization to read large blobs if the pager layer has a wal file open - even if the database header indicates that the db is not a wal database. (check-in: b54c15f117 user: dan tags: trunk)
10:09
If SQLITE_DIRECT_OVERFLOW_READ is defined at compile time, add "DIRECT_OVERFLOW_READ" to the list of symbols returned by "PRAGMA compile_options". (check-in: b7d9727bff user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Added ext/rbu/rbudor.test.






















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 2016 October 21
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This test file focuses on interactions between RBU and the feature
# enabled by SQLITE_DIRECT_OVERFLOW_READ - Direct Overflow Read.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
set ::testprefix rbudor

set bigA [string repeat a 5000]
set bigB [string repeat b 5000]
do_execsql_test 1.0 {
  PRAGMA page_size = 1024;
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);
  INSERT INTO t1 VALUES(1, $bigA);
} {}

do_test 1.1 {
  forcedelete rbu.db
  sqlite3 rbu rbu.db 
  rbu eval {
    CREATE TABLE data_t1(a, b, rbu_control);
    INSERT INTO data_t1 VALUES(2, $bigB, 0);
  }
  rbu close
} {}

do_test 1.2 {
  sqlite3rbu rbu test.db rbu.db
  while {[rbu state]!="checkpoint"} {
    rbu step
  }
  rbu step
  db eval { SELECT * FROM t1 }
} [list 1 $bigA 2 $bigB]

do_test 1.3 {
  while {[rbu step]=="SQLITE_OK"} {}
  rbu close
} {SQLITE_DONE}

do_execsql_test 1.4 {
  SELECT * FROM t1 
} [list 1 $bigA 2 $bigB]

finish_test

Changes to src/btree.c.
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
        ** up loading large records that span many overflow pages.
        */
        if( (eOp&0x01)==0                                      /* (1) */
         && offset==0                                          /* (2) */
         && (bEnd || a==ovflSize)                              /* (6) */
         && pBt->inTransaction==TRANS_READ                     /* (4) */
         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
         && pBt->pPage1->aData[19]==0x01                       /* (5) */
         && &pBuf[-4]>=pBufStart                               /* (7) */
        ){
          u8 aSave[4];
          u8 *aWrite = &pBuf[-4];
          assert( aWrite>=pBufStart );                         /* hence (7) */
          memcpy(aSave, aWrite, 4);
          rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));







|







4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
        ** up loading large records that span many overflow pages.
        */
        if( (eOp&0x01)==0                                      /* (1) */
         && offset==0                                          /* (2) */
         && (bEnd || a==ovflSize)                              /* (6) */
         && pBt->inTransaction==TRANS_READ                     /* (4) */
         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
         && 0==sqlite3PagerUseWal(pBt->pPager)                 /* (5) */
         && &pBuf[-4]>=pBufStart                               /* (7) */
        ){
          u8 aSave[4];
          u8 *aWrite = &pBuf[-4];
          assert( aWrite>=pBufStart );                         /* hence (7) */
          memcpy(aSave, aWrite, 4);
          rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
Changes to src/pager.c.
813
814
815
816
817
818
819
820
821
822

823
824
825
826
827
828
829
#define isOpen(pFd) ((pFd)->pMethods!=0)

/*
** Return true if this pager uses a write-ahead log instead of the usual
** rollback journal. Otherwise false.
*/
#ifndef SQLITE_OMIT_WAL
static int pagerUseWal(Pager *pPager){
  return (pPager->pWal!=0);
}

#else
# define pagerUseWal(x) 0
# define pagerRollbackWal(x) 0
# define pagerWalFrames(v,w,x,y) 0
# define pagerOpenWalIfPresent(z) SQLITE_OK
# define pagerBeginReadTransaction(z) SQLITE_OK
#endif







|


>







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
#define isOpen(pFd) ((pFd)->pMethods!=0)

/*
** Return true if this pager uses a write-ahead log instead of the usual
** rollback journal. Otherwise false.
*/
#ifndef SQLITE_OMIT_WAL
int sqlite3PagerUseWal(Pager *pPager){
  return (pPager->pWal!=0);
}
# define pagerUseWal(x) sqlite3PagerUseWal(x)
#else
# define pagerUseWal(x) 0
# define pagerRollbackWal(x) 0
# define pagerWalFrames(v,w,x,y) 0
# define pagerOpenWalIfPresent(z) SQLITE_OK
# define pagerBeginReadTransaction(z) SQLITE_OK
#endif
Changes to src/pager.h.
174
175
176
177
178
179
180

181
182
183
184


185
186
187
188
189
190
191

#ifndef SQLITE_OMIT_WAL
  int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
  int sqlite3PagerWalSupported(Pager *pPager);
  int sqlite3PagerWalCallback(Pager *pPager);
  int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
  int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);

# ifdef SQLITE_ENABLE_SNAPSHOT
  int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
  int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
# endif


#endif

#ifdef SQLITE_ENABLE_ZIPVFS
  int sqlite3PagerWalFramesize(Pager *pPager);
#endif

/* Functions used to query pager state and configuration. */







>




>
>







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

#ifndef SQLITE_OMIT_WAL
  int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
  int sqlite3PagerWalSupported(Pager *pPager);
  int sqlite3PagerWalCallback(Pager *pPager);
  int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
  int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
  int sqlite3PagerUseWal(Pager *pPager);
# ifdef SQLITE_ENABLE_SNAPSHOT
  int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
  int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
# endif
#else
# define sqlite3PagerUseWal(x) 0
#endif

#ifdef SQLITE_ENABLE_ZIPVFS
  int sqlite3PagerWalFramesize(Pager *pPager);
#endif

/* Functions used to query pager state and configuration. */