From b5774cfa8f19b274fd4454003aa82834ca3f72e7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 15 Sep 2008 15:36:57 +0000 Subject: [PATCH] Adjust the page recycling algorithm so that the number of pages allocated to each connection does not exceed its cache_size limit. (CVS 5701) FossilOrigin-Name: 3bc221b940565133ae8d95f59b3b120e57df0124 --- manifest | 15 +++++----- manifest.uuid | 2 +- src/pcache.c | 19 +++++++------ test/pcache2.test | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 test/pcache2.test diff --git a/manifest b/manifest index cea9f2af6a..9dc8ade5b3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sasync.test\stest\sscript\sso\sthat\sit\sinvokes\s(finish_test)\seven\sif\sthe\sasynchronous\sbackend\sis\snot\sincluded\sin\sthe\sbuild\s(and\sno\stests\sare\srun).\s(CVS\s5700) -D 2008-09-15T14:47:21 +C Adjust\sthe\spage\srecycling\salgorithm\sso\sthat\sthe\snumber\sof\spages\sallocated\nto\seach\sconnection\sdoes\snot\sexceed\sits\scache_size\slimit.\s(CVS\s5701) +D 2008-09-15T15:36:58 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in d15a7ebfe5e057a72a49805ffb302dbb601c8329 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -140,7 +140,7 @@ F src/os_win.c 3209dc0ed734291764393ea8d534ba0d8696a540 F src/pager.c b1ea487022bf91ffba58fc4c02518398290ac2c2 F src/pager.h c45380ca9d0933ea5bc4ecb3a43958b6d2ec5a9c F src/parse.y d0f76d2cb8d6883d5600dc20beb961a6022b94b8 -F src/pcache.c ff79cb5eb797d0f1a244b4332c2d39cb5cfd066b +F src/pcache.c d3c0f4ad708929fba15886914b18b82d64e286bf F src/pcache.h 53730c33310cdf7a5c94e8333c853d59a3b30226 F src/pragma.c 9d00ed41b261968757c02707e1508a707f2d46a7 F src/prepare.c c7e00ed1b0bdcf699b1aad651247d4dc3d281b0b @@ -452,6 +452,7 @@ F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4 F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a F test/pagesize.test 0d9ff3fedfce6e5ffe8fa7aca9b6d3433a2e843b F test/pcache.test 515b4c26e9f57660357dfff5b6b697acac1abc5f +F test/pcache2.test 2b4fa1bee5cfc338d8c04eb6ed7eaf41f478bf7c F test/permutations.test 41832b86c152c140bcdf75a35a7c82badd8912b9 F test/pragma.test 4461cb1004084b907dd28f9d517af7bcf8f5b35f F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 @@ -635,7 +636,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 38e5ea070a38fe1656e0f5c3024f28ce67eae725 -R 4f6ae6e9e52ddaefcd8ded4941fd5732 -U danielk1977 -Z b072615d26c8fe7520e777696085a2bf +P 5c954b40ecb71203b1013c23cdac54ff83484b0a +R dc88c00a1c805cb4941b70045df2df2e +U drh +Z c3d0d50b48385323dd5a9627ae00e19c diff --git a/manifest.uuid b/manifest.uuid index 9527e22727..4807c86650 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c954b40ecb71203b1013c23cdac54ff83484b0a \ No newline at end of file +3bc221b940565133ae8d95f59b3b120e57df0124 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index ece7571651..2b90bd7e35 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file implements that page cache. ** -** @(#) $Id: pcache.c,v 1.26 2008/09/02 09:38:07 danielk1977 Exp $ +** @(#) $Id: pcache.c,v 1.27 2008/09/15 15:36:58 drh Exp $ */ #include "sqliteInt.h" @@ -555,15 +555,16 @@ static int pcacheRecycleOrAlloc(PCache *pCache, PgHdr **ppPage){ *ppPage = 0; - /* If we have reached the limit for pinned/dirty pages, and there is at - ** least one dirty page, invoke the xStress callback to cause a page to - ** become clean. + /* If we have reached either the global or the local limit for + ** pinned+dirty pages, and there is at least one dirty page, + ** invoke the xStress callback to cause a page to become clean. */ expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); expensive_assert( pcacheCheckSynced(pCache) ); if( pCache->xStress && pCache->pDirty - && pCache->nPinned>=(pcache_g.nMaxPage+pCache->nMin-pcache_g.nMinPage) + && (pCache->nPinned>=(pcache_g.nMaxPage+pCache->nMin-pcache_g.nMinPage) + || pCache->nPinned>=pCache->nMax) ){ PgHdr *pPg; assert(pCache->pDirtyTail); @@ -586,8 +587,11 @@ static int pcacheRecycleOrAlloc(PCache *pCache, PgHdr **ppPage){ } } - /* If the global page limit has been reached, try to recycle a page. */ - if( pCache->bPurgeable && pcache_g.nCurrentPage>=pcache_g.nMaxPage ){ + /* If either the local or the global page limit has been reached, + ** try to recycle a page. + */ + if( pCache->bPurgeable && (pCache->nPage>=pCache->nMax-1 || + pcache_g.nCurrentPage>=pcache_g.nMaxPage) ){ p = pcacheRecyclePage(); } @@ -1267,4 +1271,3 @@ void sqlite3PcacheStats( *pnRecyclable = nRecyclable; } #endif - diff --git a/test/pcache2.test b/test/pcache2.test new file mode 100644 index 0000000000..be4bb5477f --- /dev/null +++ b/test/pcache2.test @@ -0,0 +1,70 @@ +# 2008 September 15 +# +# 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 file is focused on testing the pcache module. +# +# $Id: pcache2.test,v 1.1 2008/09/15 15:36:58 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + + +# Set up a pcache memory pool so that we can easily track how many +# pages are being used for cache. +# +do_test pcache2-1.1 { + db close + sqlite3_shutdown + sqlite3_config_pagecache 6000 100 + sqlite3_initialize + sqlite3_status SQLITE_STATUS_PAGECACHE_USED 1 + sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0 +} {0 0 0} + +# Open up two database connections to separate files. +# +do_test pcache2-1.2 { + file delete -force test.db test.db-journal + sqlite3 db test.db + db eval {PRAGMA cache_size=10} + lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 1 +} {2} +do_test pcache2-1.3 { + file delete -force test2.db test2.db-journal + sqlite3 db2 test2.db + db2 eval {PRAGMA cache_size=50} + lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 1 +} {4} + +# Make lots of changes on the first connection. Verify that the +# page cache usage does not grow to consume the page space set aside +# for the second connection. +# +do_test pcache2-1.4 { + db eval { + CREATE TABLE t1(a,b); + CREATE TABLE t2(x,y); + INSERT INTO t1 VALUES(1, zeroblob(800)); + INSERT INTO t1 VALUES(2, zeroblob(800)); + INSERT INTO t2 SELECT * FROM t1; + INSERT INTO t1 SELECT x+2, y FROM t2; + INSERT INTO t2 SELECT a+10, b FROM t1; + INSERT INTO t1 SELECT x+10, y FROM t2; + INSERT INTO t2 SELECT a+100, b FROM t1; + INSERT INTO t1 SELECT x+100, y FROM t2; + INSERT INTO t2 SELECT a+1000, b FROM t1; + INSERT INTO t1 SELECT x+1000, y FROM t2; + } + sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0 +} {0 13 13} + +catch {db2 close} +finish_test