diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-14 06:37:46 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-14 06:37:46 +0000 |
commit | e48e05150a1180ea87a52fbb32e8f042ecf89610 (patch) | |
tree | ac03e954a1114cda97cd91548c6c466798bec5cb /third_party | |
parent | 6a016d854a8acc092c0789958c60649fe56d7946 (diff) | |
download | chromium_src-e48e05150a1180ea87a52fbb32e8f042ecf89610.zip chromium_src-e48e05150a1180ea87a52fbb32e8f042ecf89610.tar.gz chromium_src-e48e05150a1180ea87a52fbb32e8f042ecf89610.tar.bz2 |
[SQLite] Hack to touch page cache to debug slow connection close.
The shutdown-monitor has noted cases where sqlite3_close() is taking a
very long time to finish. In reviewing the code, writes are committed
before the close is called, so there should be almost no I/O involved
(excepting perhaps unlocking the file?). One hypothesis is that the
SQLite page cache, which is LRU, may have very old pages which have
been paged out. This change touches them all, so if they are paged
out the crash should move to this code.
BUG=95527
TEST=Monitor crash in bug, see if it changes.
Review URL: http://codereview.chromium.org/7891025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101034 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/sqlite/amalgamation/sqlite3.c | 91 | ||||
-rw-r--r-- | third_party/sqlite/amalgamation/sqlite3.h | 15 |
2 files changed, 106 insertions, 0 deletions
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c index 9c66c16..f82ed1c 100644 --- a/third_party/sqlite/amalgamation/sqlite3.c +++ b/third_party/sqlite/amalgamation/sqlite3.c @@ -126259,3 +126259,94 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ /************** End of fts3_icu.c ********************************************/ + +/* Touch the bigs of pCache which will be processed by +** pcache1TruncateUnsafe(), pcache1FreePage(), and pcache1Free() +** during sqlite3_close(). *pnTouched will have the number of bytes +** represented by the pages touched added to it. */ +SQLITE_PRIVATE void pcache1VisitUnsafe(PCache1 *pCache, + unsigned int *pnTouched){ + unsigned int iHash; + + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + + for(iHash=0; iHash<pCache->nHash; iHash++){ + PgHdr1 *pp = pCache->apHash[iHash]; + PgHdr1 *lp = pp; + unsigned int s = 0; + while (pp) { + /* Crash if a loop is detected. */ + /* NOTE(shess): Touches the PgHdr1 structure as a side effect. + ** If this check is removed, revise the code to match ordering + ** in pcache1TruncateUnsafe(). Yes, I realize this is + ** probably reordered to heck and back. + */ + if (lp == pp->pNext) { + int *zero = NULL; + *zero = 42; + } + + /* Touch the data area, in case it's on a prior VM page. */ + *pnTouched += sqlite3MallocSize(PGHDR1_TO_PAGE(pp)); + + pp = pp->pNext; + + /* Bump the loop-detection pointer forward every time s is an + ** even power of 2. */ + s++; + if (!(s & (s-1))) { + lp = pp; + } + } + } +} + +/* TODO(shess): Debugging code for http://crbug.com/95527 . +** Touch the entire page cache for the given db. The idea is that if +** paging activity is causing the slowdown, the shutdown monitor will +** see things happening here, rather than in sqlite3_close(). +*/ +int sqlite3_95527(sqlite3 *db, unsigned int *pnTouched){ + unsigned int iDb; + + /* This code assumes that pcache1 is the pager cache implementation. */ + if (sqlite3GlobalConfig.pcache.xTruncate != pcache1Truncate) { + return SQLITE_OK; + } + + /* This setup is like sqlite3_close(). */ + if( !db ){ + return SQLITE_OK; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + + /* A sqlite3* connection may refer to multiple underlying database + files. Usually these will be 'main' and 'temp', with 'temp' having + no btree or pager. */ + for(iDb=0; iDb<db->nDb; iDb++){ + Btree *b; + Pager *p; + PCache1 *pCache; + struct Db *pDb = &db->aDb[iDb]; + if (!pDb) continue; + + b = pDb->pBt; + if (!b) continue; + + p = sqlite3BtreePager(b); + if (!p) continue; + + pCache = (PCache1*)p->pPCache->pCache; + if (!pCache) continue; + + pcache1EnterMutex(pCache->pGroup); + pcache1VisitUnsafe(pCache, pnTouched); + pcache1LeaveMutex(pCache->pGroup); + } + + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} diff --git a/third_party/sqlite/amalgamation/sqlite3.h b/third_party/sqlite/amalgamation/sqlite3.h index 0d42790..4ee2ee4 100644 --- a/third_party/sqlite/amalgamation/sqlite3.h +++ b/third_party/sqlite/amalgamation/sqlite3.h @@ -6477,3 +6477,18 @@ struct sqlite3_rtree_geometry { #endif /* ifndef _SQLITE3RTREE_H_ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Fault in page cache for db. See http://crbug.com/95527 . +** *pnTouched will accumulate the number of bytes represented by the +** touched pages. */ +int sqlite3_95527(sqlite3 *db, unsigned int *pnTouched); + +/* Let our code know that it's safe to call the function. */ +#define HAS_SQLITE3_95527 + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif |