From: drh Date: Thu, 24 Jun 2010 14:52:25 +0000 (+0000) Subject: Disable memory-pressure induced cache spill during savepoint rollback. X-Git-Tag: version-3.7.2~237 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7cf4c7adf0d333c08df9a6e083120ebd8b3db346;p=thirdparty%2Fsqlite.git Disable memory-pressure induced cache spill during savepoint rollback. FossilOrigin-Name: a55eb4c3e9fa4ea43b8f8182eb9e39138df03f52 --- diff --git a/manifest b/manifest index f8510203a8..aa63d4ed8b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Add\sa\scoverage\stest\sto\spagerfault.test. -D 2010-06-24T13:24:26 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Disable\smemory-pressure\sinduced\scache\sspill\sduring\ssavepoint\srollback. +D 2010-06-24T14:52:25 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -156,7 +159,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19 F src/os_unix.c 4b03e5a8a353b51af64ba11ffec85160818b4d89 F src/os_win.c 00385a839d54f951a73ceb98ddea29112adea05c -F src/pager.c c1c7f498795240b81a3d3d91460d5aa5ea023c65 +F src/pager.c 24a9be67a52fb5837be4d0319904a273164dee3a F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 @@ -825,7 +828,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 7aac9ad6dd14b1c56eb8e4750ac769c6197c30bd -R 6bfdd9c466b6b731b932420ffb1520cb -U dan -Z 5231888a9214ebb7e83363a5d8c6dab6 +P b58db67e972b5660e62a9b7daa2c1e87c3cf0a68 +R f5ac1f53c505e3a53beab11a85ef2815 +U drh +Z 7b0751e36f8e1c64e1b55cf1de6451ba +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFMI3EsoxKgR168RlERAiOBAJ0UQ8P8rnEFYZzKEMXfxfBo527pxQCdGlbn +2vYLLg+Pl79lXpGTBqE2+fY= +=77f1 +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 0788c1e582..cbc167f9d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b58db67e972b5660e62a9b7daa2c1e87c3cf0a68 \ No newline at end of file +a55eb4c3e9fa4ea43b8f8182eb9e39138df03f52 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 225cb264df..45dc8d17f2 100644 --- a/src/pager.c +++ b/src/pager.c @@ -305,12 +305,13 @@ struct PagerSavepoint { ** master journal name is only written to the journal file the first ** time CommitPhaseOne() is called. ** -** doNotSync +** doNotSpill ** ** When enabled, cache spills are prohibited and the journal file cannot ** be synced. This variable is set and cleared by sqlite3PagerWrite() ** in order to prevent a journal sync from happening in between the -** journalling of two pages on the same sector. +** journalling of two pages on the same sector. It is also set to prevent +** pagerStress() from trying to use the journal during a rollback. ** ** needSync ** @@ -354,7 +355,7 @@ struct Pager { u8 journalStarted; /* True if header of journal is synced */ u8 changeCountDone; /* Set after incrementing the change-counter */ u8 setMaster; /* True if a m-j name has been written to jrnl */ - u8 doNotSync; /* Boolean. While true, do not spill the cache */ + u8 doNotSpill; /* Do not spill the cache when non-zero */ u8 dbSizeValid; /* Set when dbSize is correct */ u8 subjInMemory; /* True to use in-memory sub-journals */ Pgno dbSize; /* Number of pages in the database */ @@ -1690,9 +1691,12 @@ static int pager_playback_one_page( ** requiring a journal-sync before it is written. */ assert( isSavepnt ); - if( (rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1))!=SQLITE_OK ){ - return rc; - } + assert( pPager->doNotSpill==0 ); + pPager->doNotSpill++; + rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); + assert( pPager->doNotSpill==1 ); + pPager->doNotSpill--; + if( rc!=SQLITE_OK ) return rc; pPg->flags &= ~PGHDR_NEED_READ; sqlite3PcacheMakeDirty(pPg); } @@ -3514,6 +3518,18 @@ static int pagerStress(void *p, PgHdr *pPg){ assert( pPg->pPager==pPager ); assert( pPg->flags&PGHDR_DIRTY ); + /* The doNotSpill flag is set during times when writing to the journal + ** is disallowed: (1) during calls to sqlite3PagerWrite() while it + ** is journalling a set of two or more database pages that are stored + ** on the same disk sector, and (2) while performing a rollback. + ** + ** Similarly, if the pager has already entered the error state, do not + ** try to write the contents of pPg to disk. + */ + if( pPager->errCode || pPager->doNotSpill ){ + return SQLITE_OK; + } + pPg->pDirty = 0; if( pagerUseWal(pPager) ){ /* Write a single frame for this page to the log. */ @@ -3524,22 +3540,6 @@ static int pagerStress(void *p, PgHdr *pPg){ rc = pagerWalFrames(pPager, pPg, 0, 0, 0); } }else{ - /* The doNotSync flag is set by the sqlite3PagerWrite() function while it - ** is journalling a set of two or more database pages that are stored - ** on the same disk sector. Syncing the journal is not allowed while - ** this is happening as it is important that all members of such a - ** set of pages are synced to disk together. So, if the page this function - ** is trying to make clean will require a journal sync and the doNotSync - ** flag is set, return without doing anything. The pcache layer will - ** just have to go ahead and allocate a new page buffer instead of - ** reusing pPg. - ** - ** Similarly, if the pager has already entered the error state, do not - ** try to write the contents of pPg to disk. - */ - if( pPager->errCode || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC) ){ - return SQLITE_OK; - } /* Sync the journal file if required. */ if( pPg->flags&PGHDR_NEED_SYNC ){ @@ -4834,12 +4834,12 @@ int sqlite3PagerWrite(DbPage *pDbPage){ int ii; /* Loop counter */ int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ - /* Set the doNotSync flag to 1. This is because we cannot allow a journal + /* Set the doNotSpill flag to 1. This is because we cannot allow a journal ** header to be written between the pages journaled by this function. */ assert( !MEMDB ); - assert( pPager->doNotSync==0 ); - pPager->doNotSync = 1; + assert( pPager->doNotSpill==0 ); + pPager->doNotSpill++; /* This trick assumes that both the page-size and sector-size are ** an integer power of 2. It sets variable pg1 to the identifier @@ -4901,8 +4901,8 @@ int sqlite3PagerWrite(DbPage *pDbPage){ assert(pPager->needSync); } - assert( pPager->doNotSync==1 ); - pPager->doNotSync = 0; + assert( pPager->doNotSpill==1 ); + pPager->doNotSpill--; }else{ rc = pager_write(pDbPage); }