| Index: third_party/sqlite/patches/0011-Allow-auto-vacuum-to-work-with-chunks.patch
|
| diff --git a/third_party/sqlite/patches/0011-Allow-auto-vacuum-to-work-with-chunks.patch b/third_party/sqlite/patches/0011-Allow-auto-vacuum-to-work-with-chunks.patch
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..58294ad0b9d3dba9da4536354cda4beb918bc159
|
| --- /dev/null
|
| +++ b/third_party/sqlite/patches/0011-Allow-auto-vacuum-to-work-with-chunks.patch
|
| @@ -0,0 +1,185 @@
|
| +From d62ff0d64a8738fd8bb07b82bcebd65143a17045 Mon Sep 17 00:00:00 2001
|
| +From: Scott Hess <shess@chromium.org>
|
| +Date: Thu, 2 Mar 2017 15:23:09 -0800
|
| +Subject: [PATCH 11/11] Allow auto-vacuum to work with chunks.
|
| +
|
| +SQLITE_FCNTL_CHUNK_SIZE can advise the VFS to resize files in quantum
|
| +amounts, to reduce fragmentation from tiny appends. This change allows
|
| +a new PRAGMA auto_vacuum_slack_pages to provide auto_vacuum with a hint
|
| +to only rearrange pages when an entire quantum can be released.
|
| +
|
| +BUG=698010
|
| +---
|
| + third_party/sqlite/src/src/btree.c | 56 ++++++++++++++++++++++++++++++++++-
|
| + third_party/sqlite/src/src/btree.h | 2 ++
|
| + third_party/sqlite/src/src/btreeInt.h | 1 +
|
| + third_party/sqlite/src/src/pragma.c | 21 +++++++++++++
|
| + third_party/sqlite/src/src/pragma.h | 8 +++++
|
| + 5 files changed, 87 insertions(+), 1 deletion(-)
|
| +
|
| +diff --git a/third_party/sqlite/src/src/btree.c b/third_party/sqlite/src/src/btree.c
|
| +index de553423b884..3335ced417ca 100644
|
| +--- a/third_party/sqlite/src/src/btree.c
|
| ++++ b/third_party/sqlite/src/src/btree.c
|
| +@@ -2812,6 +2812,46 @@ int sqlite3BtreeGetAutoVacuum(Btree *p){
|
| + #endif
|
| + }
|
| +
|
| ++/*
|
| ++** Change the 'auto-vacuum-slack-pages' property of the database. If auto vacuum
|
| ++** is enabled, this is the number of chunks of slack to allow before
|
| ++** automatically running an incremental vacuum.
|
| ++*/
|
| ++int sqlite3BtreeSetAutoVacuumSlackPages(Btree *p, int autoVacuumSlack){
|
| ++#ifdef SQLITE_OMIT_AUTOVACUUM
|
| ++ return SQLITE_READONLY;
|
| ++#else
|
| ++ BtShared *pBt = p->pBt;
|
| ++ int rc = SQLITE_OK;
|
| ++ u8 avs = (u8)autoVacuumSlack;
|
| ++ if( autoVacuumSlack>avs ){
|
| ++ avs = 0xFF;
|
| ++ }
|
| ++
|
| ++ sqlite3BtreeEnter(p);
|
| ++ pBt->autoVacuumSlack = avs;
|
| ++ sqlite3BtreeLeave(p);
|
| ++ return rc;
|
| ++#endif
|
| ++}
|
| ++
|
| ++/*
|
| ++** Return the value of the 'auto-vacuum-slack-pages' property.
|
| ++*/
|
| ++int sqlite3BtreeGetAutoVacuumSlackPages(Btree *p){
|
| ++#ifdef SQLITE_OMIT_AUTOVACUUM
|
| ++ return 0;
|
| ++#else
|
| ++ int rc = 0;
|
| ++ sqlite3BtreeEnter(p);
|
| ++ if( p->pBt->autoVacuum!=0 ){
|
| ++ rc = p->pBt->autoVacuumSlack;
|
| ++ }
|
| ++ sqlite3BtreeLeave(p);
|
| ++ return rc;
|
| ++#endif
|
| ++}
|
| ++
|
| +
|
| + /*
|
| + ** Get a reference to pPage1 of the database file. This will
|
| +@@ -3653,13 +3693,27 @@ int sqlite3BtreeIncrVacuum(Btree *p){
|
| + */
|
| + static int autoVacuumCommit(BtShared *pBt){
|
| + int rc = SQLITE_OK;
|
| ++ int bShouldVacuum = pBt->autoVacuum && !pBt->incrVacuum;
|
| + Pager *pPager = pBt->pPager;
|
| + VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); )
|
| +
|
| + assert( sqlite3_mutex_held(pBt->mutex) );
|
| + invalidateAllOverflowCache(pBt);
|
| + assert(pBt->autoVacuum);
|
| +- if( !pBt->incrVacuum ){
|
| ++ if( bShouldVacuum && pBt->autoVacuumSlack ){
|
| ++ Pgno nOrig; /* Database size before freeing */
|
| ++ Pgno nFree; /* Number of pages on the freelist initially */
|
| ++
|
| ++ nOrig = btreePagecount(pBt);
|
| ++ nFree = get4byte(&pBt->pPage1->aData[36]);
|
| ++ bShouldVacuum =
|
| ++ (nOrig-nFree-1)/pBt->autoVacuumSlack < (nOrig-1)/pBt->autoVacuumSlack;
|
| ++ /* TODO: When integrating this test with the following code, contrive to
|
| ++ ** trim to the integral chunk boundary, rather than trimming the entire free
|
| ++ ** list.
|
| ++ */
|
| ++ }
|
| ++ if( bShouldVacuum ){
|
| + Pgno nFin; /* Number of pages in database after autovacuuming */
|
| + Pgno nFree; /* Number of pages on the freelist initially */
|
| + Pgno iFree; /* The next page to be freed */
|
| +diff --git a/third_party/sqlite/src/src/btree.h b/third_party/sqlite/src/src/btree.h
|
| +index ae57468e3fd5..e0da44957564 100644
|
| +--- a/third_party/sqlite/src/src/btree.h
|
| ++++ b/third_party/sqlite/src/src/btree.h
|
| +@@ -78,6 +78,8 @@ int sqlite3BtreeGetOptimalReserve(Btree*);
|
| + int sqlite3BtreeGetReserveNoMutex(Btree *p);
|
| + int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
| + int sqlite3BtreeGetAutoVacuum(Btree *);
|
| ++int sqlite3BtreeSetAutoVacuumSlackPages(Btree *, int);
|
| ++int sqlite3BtreeGetAutoVacuumSlackPages(Btree *);
|
| + int sqlite3BtreeBeginTrans(Btree*,int);
|
| + int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
|
| + int sqlite3BtreeCommitPhaseTwo(Btree*, int);
|
| +diff --git a/third_party/sqlite/src/src/btreeInt.h b/third_party/sqlite/src/src/btreeInt.h
|
| +index b01163c33f49..eb9d1b5ef58d 100644
|
| +--- a/third_party/sqlite/src/src/btreeInt.h
|
| ++++ b/third_party/sqlite/src/src/btreeInt.h
|
| +@@ -412,6 +412,7 @@ struct BtShared {
|
| + u8 openFlags; /* Flags to sqlite3BtreeOpen() */
|
| + #ifndef SQLITE_OMIT_AUTOVACUUM
|
| + u8 autoVacuum; /* True if auto-vacuum is enabled */
|
| ++ u8 autoVacuumSlack; /* Optional pages of slack for auto-vacuum */
|
| + u8 incrVacuum; /* True if incr-vacuum is enabled */
|
| + u8 bDoTruncate; /* True to truncate db on commit */
|
| + #endif
|
| +diff --git a/third_party/sqlite/src/src/pragma.c b/third_party/sqlite/src/src/pragma.c
|
| +index b1775a4082a3..1d5ebfca098d 100644
|
| +--- a/third_party/sqlite/src/src/pragma.c
|
| ++++ b/third_party/sqlite/src/src/pragma.c
|
| +@@ -736,6 +736,27 @@ void sqlite3Pragma(
|
| + }
|
| + #endif
|
| +
|
| ++ /*
|
| ++ ** PRAGMA [schema.]auto_vacuum_slack_pages(N)
|
| ++ **
|
| ++ ** Control chunk size of auto-vacuum.
|
| ++ */
|
| ++#ifndef SQLITE_OMIT_AUTOVACUUM
|
| ++ case PragTyp_AUTO_VACUUM_SLACK_PAGES: {
|
| ++ Btree *pBt = pDb->pBt;
|
| ++ assert( pBt!=0 );
|
| ++ if( !zRight ){
|
| ++ returnSingleInt(v, sqlite3BtreeGetAutoVacuumSlackPages(pBt));
|
| ++ }else{
|
| ++ int nPages = 8;
|
| ++ if( sqlite3GetInt32(zRight, &nPages) ){
|
| ++ sqlite3BtreeSetAutoVacuumSlackPages(pBt, nPages);
|
| ++ }
|
| ++ }
|
| ++ break;
|
| ++ }
|
| ++#endif
|
| ++
|
| + #ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
| + /*
|
| + ** PRAGMA [schema.]cache_size
|
| +diff --git a/third_party/sqlite/src/src/pragma.h b/third_party/sqlite/src/src/pragma.h
|
| +index 5d8d0aa35b3f..e47f80fefac4 100644
|
| +--- a/third_party/sqlite/src/src/pragma.h
|
| ++++ b/third_party/sqlite/src/src/pragma.h
|
| +@@ -48,6 +48,7 @@
|
| + #define PragTyp_REKEY 40
|
| + #define PragTyp_LOCK_STATUS 41
|
| + #define PragTyp_PARSER_TRACE 42
|
| ++#define PragTyp_AUTO_VACUUM_SLACK_PAGES 43
|
| +
|
| + /* Property flags associated with various pragma. */
|
| + #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
|
| +@@ -145,6 +146,13 @@ static const PragmaName aPragmaName[] = {
|
| + /* ColNames: */ 0, 0,
|
| + /* iArg: */ 0 },
|
| + #endif
|
| ++#if !defined(SQLITE_OMIT_AUTOVACUUM)
|
| ++ { /* zName: */ "auto_vacuum_slack_pages",
|
| ++ /* ePragTyp: */ PragTyp_AUTO_VACUUM_SLACK_PAGES,
|
| ++ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
|
| ++ /* ColNames: */ 0, 0,
|
| ++ /* iArg: */ 0 },
|
| ++#endif
|
| + #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
| + #if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
|
| + {/* zName: */ "automatic_index",
|
| +--
|
| +2.11.0
|
| +
|
|
|