/ Check-in [c80c5c62]
Login

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

Overview
Comment:Fix a problem with mixing temp-files and mmap-mode.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tempfiles-25
Files: files | file ages | folders
SHA1: c80c5c62b2e2c5e47e0839f8e2d5b6341ca4a249
User & Date: dan 2016-04-23 17:24:16
Context
2016-04-23
19:55
Merge the latest trunk changes. check-in: 84da122d user: drh tags: tempfiles-25
17:24
Fix a problem with mixing temp-files and mmap-mode. check-in: c80c5c62 user: dan tags: tempfiles-25
14:55
Fix some problems to do with temp-file databases and recovering from IO and SQLITE_FULL errors. check-in: 3d61da4a user: dan tags: tempfiles-25
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/pager.c.

2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
....
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
....
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
    }
  }
#endif

  sqlite3BitvecDestroy(pPager->pInJournal);
  pPager->pInJournal = 0;
  pPager->nRec = 0;
  if( pagerFlushOnCommit(pPager) ){
    sqlite3PcacheCleanAll(pPager->pPCache);
  }else{
    sqlite3PcacheClearWritable(pPager->pPCache);
  }
  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);

  if( pagerUseWal(pPager) ){
................................................................................
      void *pData = 0;

      rc = sqlite3OsFetch(pPager->fd, 
          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
      );

      if( rc==SQLITE_OK && pData ){
        if( pPager->eState>PAGER_READER ){
          pPg = sqlite3PagerLookup(pPager, pgno);
        }
        if( pPg==0 ){
          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
        }else{
          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
        }
................................................................................
      pPager->zFilename, zMaster, pPager->dbSize));

  /* If no database changes have been made, return early. */
  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;

  assert( MEMDB==0 || pPager->tempFile );
  assert( isOpen(pPager->fd) || pPager->tempFile );
  if( !isOpen(pPager->fd) ){
    /* If this is an in-memory db, or no pages have been written to, or this
    ** function has already been called, it is mostly a no-op.  However, any
    ** backup in progress needs to be restarted.  */
    sqlite3BackupRestart(pPager->pBackup);
  }else{
    if( pagerUseWal(pPager) ){
      PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);







|







 







|







 







|







2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
....
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
....
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
    }
  }
#endif

  sqlite3BitvecDestroy(pPager->pInJournal);
  pPager->pInJournal = 0;
  pPager->nRec = 0;
  if( MEMDB || pagerFlushOnCommit(pPager) ){
    sqlite3PcacheCleanAll(pPager->pPCache);
  }else{
    sqlite3PcacheClearWritable(pPager->pPCache);
  }
  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);

  if( pagerUseWal(pPager) ){
................................................................................
      void *pData = 0;

      rc = sqlite3OsFetch(pPager->fd, 
          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
      );

      if( rc==SQLITE_OK && pData ){
        if( pPager->eState>PAGER_READER || pPager->tempFile ){
          pPg = sqlite3PagerLookup(pPager, pgno);
        }
        if( pPg==0 ){
          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
        }else{
          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
        }
................................................................................
      pPager->zFilename, zMaster, pPager->dbSize));

  /* If no database changes have been made, return early. */
  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;

  assert( MEMDB==0 || pPager->tempFile );
  assert( isOpen(pPager->fd) || pPager->tempFile );
  if( 0==pagerFlushOnCommit(pPager) ){
    /* If this is an in-memory db, or no pages have been written to, or this
    ** function has already been called, it is mostly a no-op.  However, any
    ** backup in progress needs to be restarted.  */
    sqlite3BackupRestart(pPager->pBackup);
  }else{
    if( pagerUseWal(pPager) ){
      PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);

Changes to test/temptable2.test.

311
312
313
314
315
316
317
318





























319
320
        INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x;
      COMMIT;
    }

    do_execsql_test 9.$tn.$i.6 { PRAGMA integrity_check } ok
  }
}






























finish_test









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


311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
        INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x;
      COMMIT;
    }

    do_execsql_test 9.$tn.$i.6 { PRAGMA integrity_check } ok
  }
}

#-------------------------------------------------------------------------
# When using mmap mode with a temp file, SQLite must search the cache 
# before using a mapped page even when there is no write transaction
# open. For a temp file, the on-disk version may not be up to date.
#
sqlite3 db ""
do_execsql_test 10.0 {
  PRAGMA cache_size = 50;
  PRAGMA page_size = 1024;
  CREATE TABLE t1(a, b, PRIMARY KEY(a)) WITHOUT ROWID;
  CREATE INDEX i1 ON t1(a);
  CREATE TABLE t2(x, y);
  INSERT INTO t2 VALUES(1, 2);
}

do_execsql_test 10.1 {
  BEGIN;
    WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
      INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
  COMMIT;
  INSERT INTO t2 VALUES(3, 4);
}

do_execsql_test 10.2 {
  PRAGMA mmap_size = 512000;
  SELECT * FROM t2;
  PRAGMA integrity_check;
} {512000 1 2 3 4 ok}

finish_test