From: dan Date: Sat, 3 May 2014 19:33:00 +0000 (+0000) Subject: Fix a race condition in the sorter. X-Git-Tag: version-3.8.7~132^2~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e18e90ebafe89d444c0524f91088b0c9316cbbc0;p=thirdparty%2Fsqlite.git Fix a race condition in the sorter. FossilOrigin-Name: 32ccf3ae18531682dfd039fa8df6ad9a907ac455 --- diff --git a/manifest b/manifest index 53d89eafaf..917d67a6b3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\ssorter\scausing\sit\sto\sreturn\sspurious\sSQLITE_NOMEM\serrors\swhen\sconfigured\sto\suse\smemsys3\sor\smemsys5. -D 2014-05-03T14:28:14.676 +C Fix\sa\srace\scondition\sin\sthe\ssorter. +D 2014-05-03T19:33:00.713 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in ad0921c4b2780d01868cf69b419a4f102308d125 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -287,7 +287,7 @@ F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4 F src/vdbeaux.c 44d4d1f5711f71eaf0d624de5c3e4976fe4e180b F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447 -F src/vdbesort.c 3e8827bb9d12465556357c24641f8805a7e2bba0 +F src/vdbesort.c c443cdf00fc8b90b17fbeaa1ad833d3091b0bf5c F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 @@ -821,10 +821,10 @@ F test/skipscan1.test bed8cbe9d554c8c27afb6c88500f704c86a9196f F test/skipscan2.test d77f79cdbba25f0f6f35298136cff21a7d7a553a F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24 -F test/sort.test 8330b31b160483b52bb502a3ac4013f3f9028d73 +F test/sort.test 2af626b7963eddb8c93b6c87babf81396c379ef5 F test/sort2.test c5e25eb674689e291d06b5209fe8d337ae0ec010 F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2 -F test/sortfault.test 7fdc4a9bd76280a659c5782cdc6d95806d62d512 +F test/sortfault.test f875d29c58b2eafdca1b51c0810075570d5a3cbc F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb F test/speed1p.test b180e98609c7677382cf618c0ec9b69f789033a8 @@ -1170,7 +1170,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f49ba1c926c63ee1c4609930138389fca182c845 -R ecf8f8bb6befc88e6cfdbe14a65100aa +P 3a66c4e1bf311d38668dfcdcd77867feff6db7bd +R 07ad433b1f531db0a3f09b334b377488 U dan -Z 4d5ad6cf671998327bccef4dcd098843 +Z 8b4c7c15ef224489143b17033ef5ced9 diff --git a/manifest.uuid b/manifest.uuid index 500fa40c2b..6bfb75656c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a66c4e1bf311d38668dfcdcd77867feff6db7bd \ No newline at end of file +32ccf3ae18531682dfd039fa8df6ad9a907ac455 \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index 5efd6f112c..5676d96e37 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -651,6 +651,7 @@ static int vdbePmaReaderNext(PmaReader *pIter){ int rc = SQLITE_OK; /* Return Code */ u64 nRec = 0; /* Size of record in bytes */ + if( pIter->iReadOff>=pIter->iEof ){ IncrMerger *pIncr = pIter->pIncr; int bEof = 1; @@ -1844,10 +1845,18 @@ static int vdbeIncrInitMerger( ){ int rc = SQLITE_OK; /* Return code */ int i; /* For iterating through PmaReader objects */ + int nTree = pMerger->nTree; - for(i=0; rc==SQLITE_OK && inTree; i++){ + for(i=0; rc==SQLITE_OK && iaIter[i]); + /* Iterators should be normally initialized in order, as if they are + ** reading from the same temp file this makes for more linear file IO. + ** However, in the INCRINIT_ROOT case, if iterator aIter[nTask-1] is + ** in use it will block the vdbePmaReaderNext() call while it uses + ** the main thread to fill its buffer. So calling PmaReaderNext() + ** on this iterator before any of the multi-threaded iterators takes + ** better advantage of multi-processor hardware. */ + rc = vdbePmaReaderNext(&pMerger->aIter[nTree-i-1]); }else{ rc = vdbePmaReaderIncrInit(&pMerger->aIter[i], INCRINIT_NORMAL); } @@ -2196,7 +2205,13 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ PmaReader *p = &pMain->aIter[iTask]; assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] ); - if( p->pIncr ){ rc = vdbePmaReaderBgIncrInit(p); } + if( p->pIncr ){ + if( iTask==pSorter->nTask-1 ){ + rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK); + }else{ + rc = vdbePmaReaderBgIncrInit(p); + } + } } } } diff --git a/test/sort.test b/test/sort.test index c6c7fc6e41..0c87dd6441 100644 --- a/test/sort.test +++ b/test/sort.test @@ -541,7 +541,6 @@ foreach {tn mmap_limit nWorker tmpstore coremutex fakeheap} { 5 0 0 memory false true } { db close - sqlite3_shutdown sqlite3_config_worker_threads $nWorker if {$coremutex} { @@ -550,7 +549,6 @@ foreach {tn mmap_limit nWorker tmpstore coremutex fakeheap} { sqlite3_config singlethread } sqlite3_initialize - sorter_test_fakeheap $fakeheap reset_db @@ -597,7 +595,6 @@ foreach {tn mmap_limit nWorker tmpstore coremutex fakeheap} { db close sqlite3_shutdown -#sqlite3_config_worker_threads $sqlite_options(worker_threads) sqlite3_config_worker_threads 0 set t(0) singlethread set t(1) multithread diff --git a/test/sortfault.test b/test/sortfault.test index abe9af6854..7c58bb6833 100644 --- a/test/sortfault.test +++ b/test/sortfault.test @@ -23,27 +23,45 @@ do_execsql_test 1.0 { PRAGMA cache_size = 5; } -foreach {tn mmap_limit} { - 1 0 - 2 100000 +foreach {tn mmap_limit nWorker tmpstore threadsmode fakeheap} { + 1 0 0 file multithread false + 2 100000 0 file multithread false } { + catch { db close } + sqlite3_shutdown + sqlite3_config_worker_threads $nWorker + sqlite3_config $threadsmode + sqlite3_initialize + sorter_test_fakeheap $fakeheap + + set str [string repeat a 1000] + do_faultsim_test 1.$tn -prep { sqlite3 db test.db sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $::mmap_limit + execsql { PRAGMA cache_size = 5 } } -body { execsql { WITH r(x,y) AS ( - SELECT 1, randomblob(1000) + SELECT 1, $::str UNION ALL - SELECT x+1, randomblob(1000) FROM r - LIMIT 500 - ) - SELECT count(x), length(y) FROM r GROUP BY (x%5) - } + SELECT x+1, $::str FROM r + LIMIT 200 + ) + SELECT count(x), length(y) FROM r GROUP BY (x%5) + } } -test { - faultsim_test_result {0 {100 1000 100 1000 100 1000 100 1000 100 1000}} + faultsim_test_result {0 {40 1000 40 1000 40 1000 40 1000 40 1000}} } } +catch { db close } +sqlite3_shutdown +sqlite3_config_worker_threads 0 +set t(0) singlethread +set t(1) multithread +set t(2) serialized +sqlite3_config $t($sqlite_options(threadsafe)) +sqlite3_initialize finish_test