From: drh Date: Fri, 13 May 2016 15:22:06 +0000 (+0000) Subject: Remove the unused PGHDR_NEED_READ flag. Add invariant checking (during X-Git-Tag: version-3.13.0~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a0f6b124ad1bec65832726b4d18f3a1dec397926;p=thirdparty%2Fsqlite.git Remove the unused PGHDR_NEED_READ flag. Add invariant checking (during SQLITE_DEBUG builds only) for the PgHdr object. FossilOrigin-Name: 771c5411e9ebcad00fb4b97556b519488284b87b --- diff --git a/manifest b/manifest index 12e791556f..5b2f5a2c42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarification\sof\sthe\spagerFlushOnCommit()\slogic. -D 2016-05-13T12:12:38.291 +C Remove\sthe\sunused\sPGHDR_NEED_READ\sflag.\s\sAdd\sinvariant\schecking\s(during\nSQLITE_DEBUG\sbuilds\sonly)\sfor\sthe\sPgHdr\sobject. +D 2016-05-13T15:22:06.587 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,11 +364,11 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 665c5a4da55952ac144c29d83e7f24393ce80dce +F src/pager.c 3910579bfbe323dfabed2b95d201159b61b8ef42 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c ad5ce697dc5a734caddb2b1eac83b195da95ddbe -F src/pcache.h 33b40350df1b6c278e019dee37f87e1bac276223 +F src/pcache.c e93f1e1b4c6134d59b4bd4f3f684f406987ef299 +F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9495d33879221c1821331dc72c61a6a3d182f526 -R 6b2058239dcedcc73d7ba7314be4d002 +P 3401d9dcdbec390564574e8d2972c944c204e025 +R 440a1b1b52d8bc83687d285c09ed1eae U drh -Z 481738e778b68e5e24387a60a8825df4 +Z 63614a0e4a8fa1151ab9567f8bbeafca diff --git a/manifest.uuid b/manifest.uuid index b9dc436b75..67d06a22f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3401d9dcdbec390564574e8d2972c944c204e025 \ No newline at end of file +771c5411e9ebcad00fb4b97556b519488284b87b \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 0cf2278562..b24267e58a 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2377,7 +2377,6 @@ static int pager_playback_one_page( assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; if( rc!=SQLITE_OK ) return rc; - pPg->flags &= ~PGHDR_NEED_READ; sqlite3PcacheMakeDirty(pPg); } if( pPg ){ @@ -6005,6 +6004,7 @@ void sqlite3PagerDontWrite(PgHdr *pPg){ IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) pPg->flags |= PGHDR_DONT_WRITE; pPg->flags &= ~PGHDR_WRITEABLE; + testcase( pPg->flags & PGHDR_NEED_SYNC ); pager_set_pagehash(pPg); } } diff --git a/src/pcache.c b/src/pcache.c index 6c07b20f57..d778f9aedc 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -53,11 +53,18 @@ struct PCache { sqlite3_pcache *pCache; /* Pluggable cache module */ }; +/********************************** Test and Debug Logic **********************/ /* -** Debug tracing macros +** Debug tracing macros. Enable by by changing the "0" to "1" and +** recompiling. +** +** When sqlite3PcacheTrace is 1, single line trace messages are issued. +** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries +** is displayed for many operations, resulting in a lot of output. */ #if defined(SQLITE_DEBUG) && 0 - int sqlite3PcacheTrace = 2; + int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ + int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ # define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} void pcacheDump(PCache *pCache){ int N; @@ -69,7 +76,7 @@ struct PCache { if( sqlite3PcacheTrace<2 ) return; if( pCache->pCache==0 ) return; N = sqlite3PcachePagecount(pCache); - if( N>5 ) N = 5; + if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; for(i=1; i<=N; i++){ pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); if( pLower==0 ) continue; @@ -88,6 +95,46 @@ struct PCache { # define pcacheDump(X) #endif +/* +** Check invariants on a PgHdr entry. Return true if everything is OK. +** Return false if any invariant is violated. +** +** This routine is for use inside of assert() statements only. For +** example: +** +** assert( sqlite3PcachePageSanity(pPg) ); +*/ +#if SQLITE_DEBUG +int sqlite3PcachePageSanity(PgHdr *pPg){ + PCache *pCache; + assert( pPg!=0 ); + assert( pPg->pgno>0 ); /* Page number is 1 or more */ + pCache = pPg->pCache; + assert( pCache!=0 ); /* Every page has an associated PCache */ + if( pPg->flags & PGHDR_CLEAN ){ + assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ + assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */ + assert( pCache->pDirtyTail!=pPg ); + } + /* WRITEABLE pages must also be DIRTY */ + if( pPg->flags & PGHDR_WRITEABLE ){ + assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ + } + /* NEED_SYNC can be set independently of WRITEABLE. This can happen, + ** for example, when using the sqlite3PagerDontWrite() optimization: + ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK. + ** (2) Page X moved to freelist, WRITEABLE is cleared + ** (3) Page X reused, WRITEABLE is set again + ** If NEED_SYNC had been cleared in step 2, then it would not be reset + ** in step 3, and page might be written into the database without first + ** syncing the rollback journal, which might cause corruption on a power + ** loss. + */ + return 1; +} +#endif /* SQLITE_DEBUG */ + + /********************************** Linked List Management ********************/ /* Allowed values for second argument to pcacheManageDirtyList() */ @@ -439,6 +486,7 @@ PgHdr *sqlite3PcacheFetchFinish( } pCache->nRefSum++; pPgHdr->nRef++; + assert( sqlite3PcachePageSanity(pPgHdr) ); return pPgHdr; } @@ -467,6 +515,7 @@ void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ */ void sqlite3PcacheRef(PgHdr *p){ assert(p->nRef>0); + assert( sqlite3PcachePageSanity(p) ); p->nRef++; p->pCache->nRefSum++; } @@ -478,6 +527,7 @@ void sqlite3PcacheRef(PgHdr *p){ */ void sqlite3PcacheDrop(PgHdr *p){ assert( p->nRef==1 ); + assert( sqlite3PcachePageSanity(p) ); if( p->flags&PGHDR_DIRTY ){ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); } @@ -491,6 +541,7 @@ void sqlite3PcacheDrop(PgHdr *p){ */ void sqlite3PcacheMakeDirty(PgHdr *p){ assert( p->nRef>0 ); + assert( sqlite3PcachePageSanity(p) ); if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; if( p->flags & PGHDR_CLEAN ){ @@ -499,6 +550,7 @@ void sqlite3PcacheMakeDirty(PgHdr *p){ assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); } + assert( sqlite3PcachePageSanity(p) ); } } @@ -507,12 +559,14 @@ void sqlite3PcacheMakeDirty(PgHdr *p){ ** make it so. */ void sqlite3PcacheMakeClean(PgHdr *p){ + assert( sqlite3PcachePageSanity(p) ); if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){ assert( (p->flags & PGHDR_CLEAN)==0 ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); p->flags |= PGHDR_CLEAN; pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); + assert( sqlite3PcachePageSanity(p) ); if( p->nRef==0 ){ pcacheUnpin(p); } @@ -560,6 +614,7 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; assert( p->nRef>0 ); assert( newPgno>0 ); + assert( sqlite3PcachePageSanity(p) ); pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; diff --git a/src/pcache.h b/src/pcache.h index 8e0f12e094..9012edf22e 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -51,11 +51,10 @@ struct PgHdr { #define PGHDR_WRITEABLE 0x004 /* Journaled and ready to modify */ #define PGHDR_NEED_SYNC 0x008 /* Fsync the rollback journal before ** writing this page to the database */ -#define PGHDR_NEED_READ 0x010 /* Content is unread */ -#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */ -#define PGHDR_MMAP 0x040 /* This is an mmap page object */ +#define PGHDR_DONT_WRITE 0x010 /* Do not write content to disk */ +#define PGHDR_MMAP 0x020 /* This is an mmap page object */ -#define PGHDR_WAL_APPEND 0x080 /* Appended to wal file */ +#define PGHDR_WAL_APPEND 0x040 /* Appended to wal file */ /* Initialize and shutdown the page cache subsystem */ int sqlite3PcacheInitialize(void); @@ -138,6 +137,11 @@ int sqlite3PcachePagecount(PCache*); void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); #endif +#if defined(SQLITE_DEBUG) +/* Check invariants on a PgHdr object */ +int sqlite3PcachePageSanity(PgHdr*); +#endif + /* Set and get the suggested cache-size for the specified pager-cache. ** ** If no global maximum is configured, then the system attempts to limit