aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2016-05-04 11:28:03 +0000
committerdan <dan@noemail.net>2016-05-04 11:28:03 +0000
commitc88ae52d868d8da91931ef3863e96ca661b4356d (patch)
tree430e14234af4fd6e4ae8f4816c56803c740b4f6a /src
parent12b35ea980c777c5c76f7e528567d799f8eade9c (diff)
downloadsqlite-c88ae52d868d8da91931ef3863e96ca661b4356d.tar.gz
sqlite-c88ae52d868d8da91931ef3863e96ca661b4356d.zip
Disable the PagerDontWrite() optimization for temp tables. It can cause database corruption if a page passed to PagerDontWrite() is dirty at the start of a transaction that is subsequently rolled back.
FossilOrigin-Name: 6341ab2ffef298ca16b323358afbea4a4c1fb0e1
Diffstat (limited to 'src')
-rw-r--r--src/pager.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/pager.c b/src/pager.c
index d24337cd5..8ef0492e5 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -6008,10 +6008,16 @@ int sqlite3PagerIswriteable(DbPage *pPg){
**
** Tests show that this optimization can quadruple the speed of large
** DELETE operations.
+**
+** This optimization cannot be used with a temp-file, as the page may
+** have been dirty at the start of the transaction. In that case, if
+** memory pressure forces page pPg out of the cache, the data does need
+** to be written out to disk so that it may be read back in if the
+** current transaction is rolled back.
*/
void sqlite3PagerDontWrite(PgHdr *pPg){
Pager *pPager = pPg->pPager;
- if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
+ if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
pPg->flags |= PGHDR_DONT_WRITE;