]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental branch to provide SQLITE_LIMIT_HEAP_K to limit the amount of limit_heap_k
authordrh <drh@noemail.net>
Thu, 7 Nov 2019 19:59:14 +0000 (19:59 +0000)
committerdrh <drh@noemail.net>
Thu, 7 Nov 2019 19:59:14 +0000 (19:59 +0000)
allocated memory used by each database connection, individually.

FossilOrigin-Name: 4ab9dbb9394ceaa014a55394a98d74008036ef0cdbc28e626024ada3d2079e39

manifest
manifest.uuid
src/main.c
src/malloc.c
src/shell.c.in
src/sqlite.h.in
src/sqliteInt.h
src/sqliteLimit.h
src/test1.c

index 465b28edbb5e359ad7e425ccb2b790f4b385b877..a60a9c838966c5ef9d6bb6a4f351baa72998caa4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\sxferCompatibleIndex()\sfunction\sso\sthat\sit\srecognizes\sthat\sa\sPRIMARY\sKEY\nindex\sfor\sa\sWITHOUT\sROWID\stable\sis\sdifferent\sfrom\sa\sUNIQUE\sconstraint\sindex\non\sthe\sprimary\skey.\s\sTicket\s[302027baf1374498]
-D 2019-11-07T14:51:24.956
+C Experimental\sbranch\sto\sprovide\sSQLITE_LIMIT_HEAP_K\sto\slimit\sthe\samount\sof\nallocated\smemory\sused\sby\seach\sdatabase\sconnection,\sindividually.
+D 2019-11-07T19:59:14.570
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -490,8 +490,8 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
 F src/insert.c 8701d80b3cecd47f0375483c1ef35dfcdc777f3c67e2d3581dd7841b980910a3
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 4ddc65ae13c0d93db0ceedc8b14a28c8c260513448b0eb8c5a2ac375e3b6a85d
-F src/main.c 20c6325c581123b8771ecb938f60d7e31c8152be01b4bf8e5eefbb74671ea86f
-F src/malloc.c b7640bcf8992cf2e98447da0d27e372abdc4621a6760418bad6d1470f041ada9
+F src/main.c 003804487422633b99b9db051f686852470c796b42384883179ccb8593018e5f
+F src/malloc.c 70aae7cc8accb049dcc03112ed8badd78d0fff93ed14574f62997cc899edc153
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
 F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
@@ -527,16 +527,16 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c cf2391c93d425455388389e7a47674b9da107d2ed69ebf49979044d70dbeb045
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
 F src/select.c 3395765ea3749341deb4c25e8339c3d626a8ac641a52c216e9632e48e620ba68
-F src/shell.c.in c06961f202f3cc50b819744b7331d3caea3d79d958402f4900b0668248557468
-F src/sqlite.h.in 5ba20664cede7f4e6861541fad1f17bac50f7bf576b40a8784c54f9126a9edd4
+F src/shell.c.in 5e402d7f77113bea90f9cf001d7d640d3cc4d4d08eafb16e171ced938ee05626
+F src/sqlite.h.in f0218cb514b4c446b3330b68073b1df80ee8515b228272a2c4f187c3dc09fb4c
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
-F src/sqliteInt.h a9afee1875df1784bf2fb5d02aece62a6a93dfd082b43bb4d5d2b5295a0042ae
-F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
+F src/sqliteInt.h 6b73ae93011f792d9186a73939aa01d2e257b6791a5c0c18d763d053907d0a23
+F src/sqliteLimit.h b1f05b390de2ae884cf17f1fe8381237b40d020091d50763fccba07cecb8d193
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
 F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290
-F src/test1.c 95c7af53c4761c57b5dbfeb5da154de31a7dae0246da8976b0bdaee1062f0826
+F src/test1.c d007f593298b98089155604d0c620f84a8cd803c19267a01d97ce48f6b88345a
 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
@@ -1849,7 +1849,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 104a2beb57037f9353ffa77096aae0eb64e4682e667f31623bfd3d064dd8d881
-R c8b53b705fa0400a6763ef7952da070a
+P 34f64f11ca481996b1ff1686bdc5e278946635b6856cd1fe2355fce8e298e0f8
+R d66fe9db5595aad5bbfd0a97b477cd6e
+T *branch * limit_heap_k
+T *sym-limit_heap_k *
+T -sym-trunk *
 U drh
-Z 1a2695a1ff301ea728b819cbcc928cab
+Z dfa7ee02c85a708dc5c324d8cd8d8443
index 59ba87321130978d089e106bd71c60c4b1811401..b87e08f6d52b95b512944e53b4e4abc52bb04d5a 100644 (file)
@@ -1 +1 @@
-34f64f11ca481996b1ff1686bdc5e278946635b6856cd1fe2355fce8e298e0f8
\ No newline at end of file
+4ab9dbb9394ceaa014a55394a98d74008036ef0cdbc28e626024ada3d2079e39
\ No newline at end of file
index 1172188821432d5dd46c52d3d261c85c7bb3679f..b2a54b2de359bc360f2566686b9c431edde4210d 100644 (file)
@@ -2595,6 +2595,7 @@ static const int aHardLimit[] = {
   SQLITE_MAX_VARIABLE_NUMBER,      /* IMP: R-38091-32352 */
   SQLITE_MAX_TRIGGER_DEPTH,
   SQLITE_MAX_WORKER_THREADS,
+  SQLITE_MAX_HEAP_K,
 };
 
 /*
@@ -2673,7 +2674,8 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
   assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
   assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
   assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
-  assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) );
+  assert( aHardLimit[SQLITE_LIMIT_HEAP_K]==SQLITE_MAX_HEAP_K );
+  assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-2) );
 
 
   if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
@@ -3068,6 +3070,7 @@ static int openDatabase(
   db->aDb = db->aDbStatic;
   db->lookaside.bDisable = 1;
   db->lookaside.sz = 0;
+  db->nMemUsed = 0;
 
   assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
   memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
index 8a2b234853eaa238c11a1061d4f14d7423c894bb..17e1fcf8b2b64ed1c96eb33698ad5146caa0c973 100644 (file)
@@ -333,6 +333,15 @@ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
   *db->pnBytesFreed += sqlite3DbMallocSize(db,p);
 }
 
+static SQLITE_NOINLINE void sqlite3DbFreeTail(sqlite3 *db, void *p){
+  db->nMemUsed -= sqlite3MallocSize(p);
+  assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+  assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+  assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
+  sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
+  sqlite3_free(p);
+}
+
 /*
 ** Free memory that might be associated with a particular database
 ** connection.  Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op.
@@ -356,6 +365,8 @@ void sqlite3DbFreeNN(sqlite3 *db, void *p){
       db->lookaside.pFree = pBuf;
       return;
     }
+    sqlite3DbFreeTail(db, p);
+    return;
   }
   assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
   assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
@@ -469,9 +480,18 @@ static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){
   void *p;
   assert( db!=0 );
   p = sqlite3Malloc(n);
-  if( !p ) sqlite3OomFault(db);
-  sqlite3MemdebugSetType(p, 
+  if( p==0 ){
+    sqlite3OomFault(db);
+  }else{
+    sqlite3MemdebugSetType(p, 
          (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
+    db->nMemUsed += sqlite3MallocSize(p);
+    if( db->nMemUsed > 1024*(i64)db->aLimit[SQLITE_LIMIT_HEAP_K] ){
+      sqlite3DbFreeNN(db, p);
+      p = 0;
+      sqlite3OomFault(db);
+    }
+  }
   return p;
 }
 
index 105cab6e5e4feb274ff202b3336e1a2bbd6178a1..99b90bbcfda7a4a1132d9824f5d474802b52da6b 100644 (file)
@@ -7895,6 +7895,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       { "variable_number",       SQLITE_LIMIT_VARIABLE_NUMBER           },
       { "trigger_depth",         SQLITE_LIMIT_TRIGGER_DEPTH             },
       { "worker_threads",        SQLITE_LIMIT_WORKER_THREADS            },
+      { "heap_k",                SQLITE_LIMIT_HEAP_K                    },
     };
     int i, n2;
     open_db(p, 0);
index 5c3827e2d444633612f286aa98f1bb4242eefebe..1c91bde5507961781e6084254328bf32bedc0a55 100644 (file)
@@ -3705,6 +3705,10 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
 ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
 ** <dd>The maximum number of auxiliary worker threads that a single
 ** [prepared statement] may start.</dd>)^
+**
+** [[SQLITE_LIMIT_HEAP_K]] ^(<dt>SQLITE_LIMIT_HEAP_K</dt>
+** <dd>The maximum number of kibibytes (one kibibyte is 1024 bytes) that
+** an individual [database connection] is allowed to allocate.)^
 ** </dl>
 */
 #define SQLITE_LIMIT_LENGTH                    0
@@ -3719,6 +3723,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
 #define SQLITE_LIMIT_VARIABLE_NUMBER           9
 #define SQLITE_LIMIT_TRIGGER_DEPTH            10
 #define SQLITE_LIMIT_WORKER_THREADS           11
+#define SQLITE_LIMIT_HEAP_K                   12
 
 /*
 ** CAPI3REF: Prepare Flags
index b12391a3ed8d984d799aef260877448bb570545b..5e58a1db2c63564e9a67f210a835318ff4421281 100644 (file)
@@ -1250,7 +1250,7 @@ struct Schema {
 ** The number of different kinds of things that can be limited
 ** using the sqlite3_limit() interface.
 */
-#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
+#define SQLITE_N_LIMIT (SQLITE_LIMIT_HEAP_K+1)
 
 /*
 ** Lookaside malloc is a set of fixed-size buffers that can be used
@@ -1417,6 +1417,7 @@ struct sqlite3 {
   int nVdbeExec;                /* Number of nested calls to VdbeExec() */
   int nVDestroy;                /* Number of active OP_VDestroy operations */
   int nExtension;               /* Number of loaded extensions */
+  i64 nMemUsed;                 /* Memory used by this database connection */
   void **aExtension;            /* Array of shared library handles */
   int (*xTrace)(u32,void*,void*,void*);     /* Trace function */
   void *pTraceArg;                          /* Argument to the trace function */
index 28e7a41cc3e1f5e888566b4dfb43775dded36ccc..9d6c54fdc9e93d3e11420f75d44f889899445c29 100644 (file)
 #ifndef SQLITE_MAX_TRIGGER_DEPTH
 # define SQLITE_MAX_TRIGGER_DEPTH 1000
 #endif
+
+/*
+** Maximum number of kibibytes (1 kibibyte == 1024 bytes) that a single
+** database connection is allowed to allocate.  Memory allocations that
+** are percipitated by a database conection but are not directly attached
+** to a database connection (such as memory used for the page cache) are
+** not counted toward this limit.
+*/
+#ifndef SQLITE_MAX_HEAP_K
+# define SQLITE_MAX_HEAP_K 1048576
+#endif
index b25873bbd4144215824ff23b4f9aae51f41fbcb6..3afc5708750dd00a827d9414ead2ea8d32cc13e2 100644 (file)
@@ -6327,6 +6327,7 @@ static int SQLITE_TCLAPI test_limit(
     { "SQLITE_LIMIT_VARIABLE_NUMBER",     SQLITE_LIMIT_VARIABLE_NUMBER      },
     { "SQLITE_LIMIT_TRIGGER_DEPTH",       SQLITE_LIMIT_TRIGGER_DEPTH        },
     { "SQLITE_LIMIT_WORKER_THREADS",      SQLITE_LIMIT_WORKER_THREADS       },
+    { "SQLITE_LIMIT_HEAP_K",              SQLITE_LIMIT_HEAP_K               },
     
     /* Out of range test cases */
     { "SQLITE_LIMIT_TOOSMALL",            -1,                               },