]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a race condition to do with very large index keys in shared-cache mode.
authordan <dan@noemail.net>
Thu, 11 Dec 2014 16:38:18 +0000 (16:38 +0000)
committerdan <dan@noemail.net>
Thu, 11 Dec 2014 16:38:18 +0000 (16:38 +0000)
FossilOrigin-Name: fc157dd7f18c94b7ae5f155e1b4a5d7714b7da8c

manifest
manifest.uuid
src/btree.c
src/vdbeapi.c
test/threadtest3.c
test/tt3_index.c
test/tt3_lookaside1.c [new file with mode: 0644]

index 17ec6c7d04d064e4b9fd6e053359a57ffb3d71de..69fe0301032f3ea481495b563c4192f3ed9198b2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\stypo\sin\sthe\sdocumentation\sfor\ssqlite3_threadsafe().
-D 2014-12-11T15:27:04.851
+C Fix\sa\srace\scondition\sto\sdo\swith\svery\slarge\sindex\skeys\sin\sshared-cache\smode.
+D 2014-12-11T16:38:18.086
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 6c4f961fa91d0b4fa121946a19f9e5eac2f2f809
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -173,7 +173,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea
 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
 F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
-F src/btree.c ea6692ce58bfba55b12c75d2947fec0906d1ef7a
+F src/btree.c ab4b60fcf9920d862ff4d96efb1d605e4e7701a0
 F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e
 F src/btreeInt.h 3363e18fd76f69a27a870b25221b2345b3fd4d21
 F src/build.c 67bb05b1077e0cdaccb2e36bfcbe7a5df9ed31e8
@@ -294,7 +294,7 @@ F src/vacuum.c 9b30ec729337dd012ed88d4c292922c8ef9cf00c
 F src/vdbe.c 1a9e671c9cfc259e4d2affc71f7df4a4c00a842c
 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
 F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
-F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83
+F src/vdbeapi.c f8dd2d33a30938188fc292d524e88a91f2e65887
 F src/vdbeaux.c 6f7f39c3fcf0f5923758df8561bb5d843908a553
 F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778
 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
@@ -912,7 +912,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46
 F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd
 F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
 F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9
-F test/threadtest3.c fca8d360b470405ae3ed431b5cb4cdf031f85a74
+F test/threadtest3.c 2b6e07e915c383c250a5b531cf6ef163a3047d7e
 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
 F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
 F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
@@ -1076,7 +1076,8 @@ F test/triggerC.test a68980c5955d62ee24be6f97129d824f199f9a4c
 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
 F test/triggerE.test 355e9c5cbaed5cd039a60baad1fb2197caeb8e52
 F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
-F test/tt3_index.c 2e7f3151a0ae522f031e8e2761ca2bda63f4d221
+F test/tt3_index.c 14f4b0cc3f4c05353e25778cf531c9d6e3b0d27f
+F test/tt3_lookaside1.c 0b5b79ba37f21a1eb849cd4a54eed367f4d4aaaf
 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
 F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84
 F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
@@ -1227,7 +1228,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P d9f916ba09f1a61684b4d59548ab6cf71cdb6a37
-R be485ee74d8699a155e9699a0ceccb5f
-U drh
-Z 8b7cdafef867d0fe5e1164d6f32f45ce
+P 258e747bb7e3a2bc46f932cc2b06c2689d43aeb0
+R 016d1b9c16d412ff926cdf599ae97f64
+U dan
+Z 8da7cca75b292da60a4687ff246cc6b3
index de0c011b0bf96b52a642b0e1b6dc31948acad91a..0de4da36020bd8c929195377b8dc78146be32fc8 100644 (file)
@@ -1 +1 @@
-258e747bb7e3a2bc46f932cc2b06c2689d43aeb0
\ No newline at end of file
+fc157dd7f18c94b7ae5f155e1b4a5d7714b7da8c
\ No newline at end of file
index 4283d00fd33cbd8ba0081114edc0ec92407723ab..a73c831219eed89cd0abe37664c47567db26ac7e 100644 (file)
@@ -3913,7 +3913,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
       releasePage(pCur->apPage[i]);
     }
     unlockBtreeIfUnused(pBt);
-    sqlite3DbFree(pBtree->db, pCur->aOverflow);
+    sqlite3_free(pCur->aOverflow);
     /* sqlite3_free(pCur); */
     sqlite3BtreeLeave(pBtree);
   }
@@ -4208,6 +4208,7 @@ static int accessPayload(
     offset -= pCur->info.nLocal;
   }
 
+
   if( rc==SQLITE_OK && amt>0 ){
     const u32 ovflSize = pBt->usableSize - 4;  /* Bytes content per ovfl page */
     Pgno nextPage;
@@ -4225,8 +4226,8 @@ static int accessPayload(
     if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
       int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
       if( nOvfl>pCur->nOvflAlloc ){
-        Pgno *aNew = (Pgno*)sqlite3DbRealloc(
-            pCur->pBtree->db, pCur->aOverflow, nOvfl*2*sizeof(Pgno)
+        Pgno *aNew = (Pgno*)sqlite3Realloc(
+            pCur->aOverflow, nOvfl*2*sizeof(Pgno)
         );
         if( aNew==0 ){
           rc = SQLITE_NOMEM;
@@ -4273,6 +4274,7 @@ static int accessPayload(
         */
         assert( eOp!=2 );
         assert( pCur->curFlags & BTCF_ValidOvfl );
+        assert( pCur->pBtree->db==pBt->db );
         if( pCur->aOverflow[iIdx+1] ){
           nextPage = pCur->aOverflow[iIdx+1];
         }else{
index 5744c28632ddbd0d58f0cf6607333441b2b197f1..c6116881937cc4fdf6785bc2718af49308f5b277 100644 (file)
@@ -580,7 +580,6 @@ int sqlite3_step(sqlite3_stmt *pStmt){
     ** sqlite3_errmsg() and sqlite3_errcode().
     */
     const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
-    assert( zErr!=0 || db->mallocFailed );
     sqlite3DbFree(db, v->zErrMsg);
     if( !db->mallocFailed ){
       v->zErrMsg = sqlite3DbStrDup(db, zErr);
index 084ca022a9808e83a78315b759c76f097bf14ff1..afa4197ee21fdcf2c22d41365efea06adc309f0f 100644 (file)
@@ -1398,6 +1398,7 @@ static void dynamic_triggers(int nMs){
 
 #include "tt3_checkpoint.c"
 #include "tt3_index.c"
+#include "tt3_lookaside1.c"
 
 int main(int argc, char **argv){
   struct ThreadTest {
@@ -1419,6 +1420,7 @@ int main(int argc, char **argv){
     { checkpoint_starvation_2, "checkpoint_starvation_2", 10000 },
 
     { create_drop_index_1, "create_drop_index_1", 10000 },
+    { lookaside1, "lookaside1", 10000 },
   };
 
   int i;
index b79768c6c71905faa59bdf9826ac30ac4d7f6a25..4bad64aabc15d852c6fbe93e794b05bda5bcc651 100644 (file)
@@ -67,8 +67,8 @@ static void create_drop_index_1(int nMs){
   launch_thread(&err, &threads, create_drop_index_thread, 0);
   launch_thread(&err, &threads, create_drop_index_thread, 0);
   launch_thread(&err, &threads, create_drop_index_thread, 0);
-  sqlite3_enable_shared_cache(0);
 
   join_all_threads(&err, &threads);
+  sqlite3_enable_shared_cache(0);
   print_and_free_err(&err);
 }
diff --git a/test/tt3_lookaside1.c b/test/tt3_lookaside1.c
new file mode 100644 (file)
index 0000000..486de80
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+** 2014 December 9
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+**     lookaside1
+*/
+
+/*
+** The test in this file attempts to expose a specific race condition
+** that is suspected to exist at time of writing.
+*/
+
+static char *lookaside1_thread_reader(int iTid, int iArg){
+  Error err = {0};                /* Error code and message */
+  Sqlite db = {0};                /* SQLite database connection */
+
+  opendb(&err, &db, "test.db", 0);
+
+  while( !timetostop(&err) ){
+    sqlite3_stmt *pStmt = 0;
+    int rc;
+
+    sqlite3_prepare_v2(db.db, "SELECT 1 FROM t1", -1, &pStmt, 0);
+    while( sqlite3_step(pStmt)==SQLITE_ROW ){
+      execsql(&err, &db, "SELECT length(x||y||z) FROM t2");
+    }
+    rc = sqlite3_finalize(pStmt);
+    if( err.rc==SQLITE_OK && rc!=SQLITE_OK ){
+      sqlite_error(&err, &db, "finalize");
+    }
+  }
+
+  closedb(&err, &db);
+  print_and_free_err(&err);
+  return sqlite3_mprintf("ok");
+}
+
+static char *lookaside1_thread_writer(int iTid, int iArg){
+  Error err = {0};                /* Error code and message */
+  Sqlite db = {0};                /* SQLite database connection */
+
+  opendb(&err, &db, "test.db", 0);
+
+  do{
+    sql_script(&err, &db, 
+      "BEGIN;"
+        "UPDATE t3 SET i=i+1 WHERE x=1;"
+      "ROLLBACK;"
+    );
+  }while( !timetostop(&err) );
+
+  closedb(&err, &db);
+  print_and_free_err(&err);
+  return sqlite3_mprintf("ok");
+}
+
+
+static void lookaside1(int nMs){
+  Error err = {0};
+  Sqlite db = {0};
+  Threadset threads = {0};
+
+  opendb(&err, &db, "test.db", 1);
+  sql_script(&err, &db, 
+     "CREATE TABLE t1(x PRIMARY KEY) WITHOUT ROWID;"
+     "WITH data(x,y) AS ("
+     "  SELECT 1, quote(randomblob(750)) UNION ALL "
+     "  SELECT x*2, y||y FROM data WHERE x<5) "
+     "INSERT INTO t1 SELECT y FROM data;"
+
+     "CREATE TABLE t3(x PRIMARY KEY,i) WITHOUT ROWID;"
+     "INSERT INTO t3 VALUES(1, 1);"
+
+     "CREATE TABLE t2(x,y,z);"
+     "INSERT INTO t2 VALUES(randomblob(50), randomblob(50), randomblob(50));"
+  );
+  closedb(&err, &db);
+
+  setstoptime(&err, nMs);
+
+  sqlite3_enable_shared_cache(1);
+  launch_thread(&err, &threads, lookaside1_thread_reader, 0);
+  launch_thread(&err, &threads, lookaside1_thread_reader, 0);
+  launch_thread(&err, &threads, lookaside1_thread_reader, 0);
+  launch_thread(&err, &threads, lookaside1_thread_reader, 0);
+  launch_thread(&err, &threads, lookaside1_thread_reader, 0);
+  launch_thread(&err, &threads, lookaside1_thread_writer, 0);
+  join_all_threads(&err, &threads);
+  sqlite3_enable_shared_cache(0);
+  print_and_free_err(&err);
+}