From 6fa255fd5c728be68381ce23beead03d38a10dac Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 28 Oct 2015 19:46:57 +0000 Subject: [PATCH 1/6] Add experimental API sqlite3_db_cacheflush(). FossilOrigin-Name: 65b86dc1fa4a57cc3cde86a820d9f848aa288a15 --- manifest | 27 +++--- manifest.uuid | 2 +- src/main.c | 33 +++++++ src/pager.c | 17 ++++ src/pager.h | 1 + src/sqlite.h.in | 30 +++++++ src/test1.c | 29 ++++++ test/cacheflush.test | 207 +++++++++++++++++++++++++++++++++++++++++++ test/cffault.test | 57 ++++++++++++ 9 files changed, 391 insertions(+), 12 deletions(-) create mode 100644 test/cacheflush.test create mode 100644 test/cffault.test diff --git a/manifest b/manifest index b070a768f7..866a53b656 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\sout\sadding\sNOT\sexpression\snodes\sin\sthe\sparser\sinto\sa\ssubroutine. -D 2015-10-28T16:05:10.981 +C Add\sexperimental\sAPI\ssqlite3_db_cacheflush(). +D 2015-10-28T19:46:57.460 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -305,7 +305,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012 F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 -F src/main.c 1cae029707c323292b5691e4d0a4c5c44561c877 +F src/main.c b9d020342b2a2b13808c6260792ef233d7af5b1d F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -327,8 +327,8 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 2fbeeba28f4e6d08a15bc106f36c43346a81f09e -F src/pager.h ac213f8143ebfee6a8bfb91cf4ca02c9a83343c5 +F src/pager.c 059991ce76b1a857cb84dd2469cfcfaaae1d77fa +F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9 @@ -342,7 +342,7 @@ F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 167b4e9058bc8e997d18d6b6b20ecbb0c9c457af F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621 -F src/sqlite.h.in 070b49c253bd41607ec43505a16163aa4b537b83 +F src/sqlite.h.in e7da8d15141d0753bfe14945bd64592a42575c04 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 F src/sqliteInt.h b1e72ffe282c91ae30a2bf403319126dbaebd556 @@ -350,7 +350,7 @@ F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 -F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a +F src/test1.c 9ac5cbfe3c859ab7518edc5109a2959d6bf7b059 F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d F src/test3.c f7ae1d6a4aa07aac257de18a43800c1199b513fc F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -503,6 +503,7 @@ F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99 F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de +F test/cacheflush.test 95944e4210100c525ec301c060721e82210c33a5 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 @@ -510,6 +511,7 @@ F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 +F test/cffault.test 1383919788fa50db60f6119da5785c62fbc8b527 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 @@ -1395,7 +1397,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a85c2a4758c27e8d5d0395751eb3cfd9985ce696 -R fb08eb2aea7ef14b6808d0fed46a7f2e -U drh -Z 776eb09f5d20f370f46eb3dbeaa8d2e2 +P 001854181640bd9b088f2bc16083d84808c3da18 +R 2dbc861fa3cf60b53d3ec06b17c9981a +T *branch * cacheflush +T *sym-cacheflush * +T -sym-trunk * +U dan +Z c07109c8cca9fe678b00367209f93a20 diff --git a/manifest.uuid b/manifest.uuid index 0f39a06726..ac6d5b874a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -001854181640bd9b088f2bc16083d84808c3da18 \ No newline at end of file +65b86dc1fa4a57cc3cde86a820d9f848aa288a15 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9dd05cdf1d..324415b0cf 100644 --- a/src/main.c +++ b/src/main.c @@ -740,6 +740,39 @@ int sqlite3_db_release_memory(sqlite3 *db){ return SQLITE_OK; } +/* +** Flush any dirty pages in the pager-cache for any attached database +** to disk. +*/ +int sqlite3_db_cacheflush(sqlite3 *db){ + int i; + int rc = SQLITE_OK; + int bSeenBusy = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeIsInTrans(pBt) ){ + Pager *pPager = sqlite3BtreePager(pBt); + rc = sqlite3PagerFlush(pPager); + if( rc==SQLITE_BUSY ){ + bSeenBusy = 1; + rc = SQLITE_OK; + } + } + } + if( rc!=SQLITE_OK ){ + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc); +} + /* ** Configuration settings for an individual database connection */ diff --git a/src/pager.c b/src/pager.c index 399070af01..f21f0802ba 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4473,6 +4473,23 @@ static int pagerStress(void *p, PgHdr *pPg){ return pager_error(pPager, rc); } +/* +** Flush all unreferenced dirty pages to disk. +*/ +int sqlite3PagerFlush(Pager *pPager){ + int rc = SQLITE_OK; + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + + while( rc==SQLITE_OK && pList ){ + PgHdr *pNext = pList->pDirty; + if( pList->nRef==0 ){ + rc = pagerStress((void*)pPager, pList); + } + pList = pNext; + } + + return rc; +} /* ** Allocate and initialize a new Pager object and put a pointer to it diff --git a/src/pager.h b/src/pager.h index 99a7aebc78..8e0e942efe 100644 --- a/src/pager.h +++ b/src/pager.h @@ -132,6 +132,7 @@ int sqlite3PagerGetJournalMode(Pager*); int sqlite3PagerOkToChangeJournalMode(Pager*); i64 sqlite3PagerJournalSizeLimit(Pager *, i64); sqlite3_backup **sqlite3PagerBackupPtr(Pager*); +int sqlite3PagerFlush(Pager*); /* Functions used to obtain and release page references. */ int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d9be3a5e6f..6c04ff5102 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7792,6 +7792,36 @@ int sqlite3_stmt_scanstatus( */ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); +/* +** CAPI3REF: Flush caches to disk mid-transaction +** +** If a write-transaction is open when this function is called, any dirty +** pages in the pager-cache that are not currently in use are written out +** to disk. A dirty page may be in use if a database cursor created by an +** active SQL statement is reading from it, or if it is page 1 of a database +** file (page 1 is always "in use"). Dirty pages are flushed for all +** databases - "main", "temp" and any attached databases. +** +** If this function needs to obtain extra database locks before dirty pages +** can be flushed to disk, it does so. If said locks cannot be obtained +** immediately and there is a busy-handler callback configured, it is invoked +** in the usual manner. If the required lock still cannot be obtained, then +** the database is skipped and an attempt made to flush any dirty pages +** belonging to the next (if any) database. If any databases are skipped +** because locks cannot be obtained, but no other error occurs, this +** function returns SQLITE_BUSY. +** +** If any other error occurs while flushing dirty pages to disk (for +** example an IO error or out-of-memory condition), then processing is +** abandoned and an SQLite error code returned to the caller immediately. +** In this case the open transaction may be automatically rolled back. +** +** Otherwise, if no error occurs, SQLITE_OK is returned. +** +** This function does not set the database handle error code or message +** returned by the sqlite3_errcode() and sqlite3_errmsg() functions. +*/ +int sqlite3_db_cacheflush(sqlite3*); /* ** Undo the hack that converts floating point types to integer for diff --git a/src/test1.c b/src/test1.c index 6c47754bf9..dd190feebc 100644 --- a/src/test1.c +++ b/src/test1.c @@ -4688,6 +4688,34 @@ static int test_db_release_memory( return TCL_OK; } +/* +** Usage: sqlite3_db_cacheflush DB +** +** Attempt to flush any dirty pages to disk. +*/ +static int test_db_cacheflush( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int rc; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + rc = sqlite3_db_cacheflush(db); + if( rc ){ + Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC); + return TCL_ERROR; + } + + Tcl_ResetResult(interp); + return TCL_OK; +} + /* ** Usage: sqlite3_db_filename DB DBNAME ** @@ -6876,6 +6904,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_db_release_memory", test_db_release_memory, 0}, + { "sqlite3_db_cacheflush", test_db_cacheflush, 0}, { "sqlite3_db_filename", test_db_filename, 0}, { "sqlite3_db_readonly", test_db_readonly, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, diff --git a/test/cacheflush.test b/test/cacheflush.test new file mode 100644 index 0000000000..a9ee672b9f --- /dev/null +++ b/test/cacheflush.test @@ -0,0 +1,207 @@ +# 2011 November 16 +# +# 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. +# +#*********************************************************************** +# +# This file contains test cases for sqlite3_db_cacheflush API. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix cacheflush +test_set_config_pagecache 0 0 + +# Run the supplied SQL on a copy of the database currently stored on +# disk in file $dbfile. +proc diskquery {dbfile sql} { + forcecopy $dbfile dq.db + sqlite3 dq dq.db + set res [execsql $sql dq] + dq close + set res +} + +# Simplest possible test. +# +do_execsql_test 1.1.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + BEGIN; + INSERT INTO t1 VALUES(3, 4); +} +do_test 1.1.1 { + diskquery test.db { SELECT * FROM t1 } +} {1 2} +do_test 1.1.2 { + sqlite3_db_cacheflush db + diskquery test.db { SELECT * FROM t1 } +} {1 2 3 4} + +# Test that multiple pages may be flushed to disk. +# +do_execsql_test 1.2.0 { + COMMIT; + CREATE TABLE t2(a, b); + BEGIN; + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t2 VALUES('a', 'b'); +} +do_test 1.2.1 { + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + } +} {1 2 3 4} +do_test 1.2.2 { + sqlite3_db_cacheflush db + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + } +} {1 2 3 4 5 6 a b} + +# Test that pages with nRef!=0 are not flushed to disk. +# +do_execsql_test 1.3.0 { + COMMIT; + CREATE TABLE t3(a, b); + BEGIN; + INSERT INTO t1 VALUES(7, 8); + INSERT INTO t2 VALUES('c', 'd'); + INSERT INTO t3 VALUES('i', 'ii'); +} +do_test 1.3.1 { + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 2 3 4 5 6 a b} +do_test 1.3.2 { + db eval { SELECT a FROM t1 } { + if {$a==3} { + sqlite3_db_cacheflush db + } + } + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 2 3 4 5 6 a b c d i ii} +do_test 1.3.2 { + sqlite3_db_cacheflush db + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 2 3 4 5 6 7 8 a b c d i ii} + +# Check that SQLITE_BUSY is returned if pages cannot be flushed due to +# conflicting read locks. +# +do_execsql_test 1.4.0 { + COMMIT; + BEGIN; + INSERT INTO t1 VALUES(9, 10); +} +do_test 1.4.1 { + sqlite3 db2 test.db + db2 eval { + BEGIN; + SELECT * FROM t1; + } + diskquery test.db { + SELECT * FROM t1; + } +} {1 2 3 4 5 6 7 8} +do_test 1.4.2 { + list [catch { sqlite3_db_cacheflush db } msg] $msg +} {1 {database is locked}} +do_test 1.4.3 { + diskquery test.db { + SELECT * FROM t1; + } +} {1 2 3 4 5 6 7 8} +do_test 1.4.4 { + db2 close + sqlite3_db_cacheflush db + diskquery test.db { + SELECT * FROM t1; + } +} {1 2 3 4 5 6 7 8 9 10} +do_execsql_test 1.4.5 { COMMIT } + +#------------------------------------------------------------------------- +# Test that ATTACHed database caches are also flushed. +# +forcedelete test.db2 +do_execsql_test 2.1.0 { + ATTACH 'test.db2' AS aux; + CREATE TABLE aux.t4(x, y); + INSERT INTO t4 VALUES('A', 'B'); + BEGIN; + INSERT INTO t1 VALUES(11, 12); + INSERT INTO t4 VALUES('C', 'D'); +} +do_test 2.1.1 { + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10} +do_test 2.1.2 { + diskquery test.db2 { SELECT * FROM t4; } +} {A B} +do_test 2.1.3 { + sqlite3_db_cacheflush db + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10 11 12} +do_test 2.1.4 { + sqlite3_db_cacheflush db + diskquery test.db2 { SELECT * FROM t4; } +} {A B C D} +do_execsql_test 2.1.5 { COMMIT } + +# And that hitting an SQLITE_BUSY when flushing "main" does not stop +# SQLite from going on to flush "aux". +# +do_execsql_test 2.2.0 { + BEGIN; + INSERT INTO t1 VALUES(13, 14); + INSERT INTO t4 VALUES('E', 'F'); +} +do_test 2.2.1 { + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10 11 12} +do_test 2.2.2 { + diskquery test.db2 { SELECT * FROM t4; } +} {A B C D} +do_test 2.2.3 { + sqlite3 db2 test.db + execsql { + BEGIN; + SELECT * FROM t1; + } db2 + list [catch { sqlite3_db_cacheflush db } msg] $msg +} {1 {database is locked}} +do_test 2.2.4 { + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10 11 12} +do_test 2.2.5 { + diskquery test.db2 { SELECT * FROM t4; } +} {A B C D E F} +do_test 2.2.6 { + db2 close + sqlite3_db_cacheflush db + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14} +do_execsql_test 2.2.7 { COMMIT } + +test_restore_config_pagecache +finish_test + diff --git a/test/cffault.test b/test/cffault.test new file mode 100644 index 0000000000..e90bbac55f --- /dev/null +++ b/test/cffault.test @@ -0,0 +1,57 @@ +# 2011 November 16 +# +# 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. +# +#*********************************************************************** +# +# This file contains fault-injection test cases for the +# sqlite3_db_cacheflush API. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix cacheflush +source $testdir/malloc_common.tcl + +# Run the supplied SQL on a copy of the database currently stored on +# disk in file $dbfile. +proc diskquery {dbfile sql} { + forcecopy $dbfile dq.db + sqlite3 dq dq.db + set res [execsql $sql dq] + dq close + set res +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); +} +faultsim_save_and_close + +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b+1; + } +} -body { + sqlite3_db_cacheflush db +} -test { + faultsim_test_result {0 {}} {1 {disk I/O error}} + catch { db eval COMMIT } + faultsim_integrity_check +} + + +finish_test + From dbf6773e881abf83383122fa381b07960f0f86ac Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Oct 2015 18:16:40 +0000 Subject: [PATCH 2/6] Avoid automatically rolling back the transaction if an SQLITE_IOERR or SQLITE_FULL error occurs within sqlite3_db_cacheflush(). FossilOrigin-Name: 370b5d520c6523526988d0db5299f1bd09567782 --- manifest | 21 ++++------ manifest.uuid | 2 +- src/main.c | 3 -- src/pager.c | 20 +++++---- src/sqlite.h.in | 1 - test/cffault.test | 104 +++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 125 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 866a53b656..4ea95b624f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sexperimental\sAPI\ssqlite3_db_cacheflush(). -D 2015-10-28T19:46:57.460 +C Avoid\sautomatically\srolling\sback\sthe\stransaction\sif\san\sSQLITE_IOERR\sor\sSQLITE_FULL\serror\soccurs\swithin\ssqlite3_db_cacheflush(). +D 2015-10-29T18:16:40.382 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -305,7 +305,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012 F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 -F src/main.c b9d020342b2a2b13808c6260792ef233d7af5b1d +F src/main.c f393acc6e5d604cbe0054376d62f668a5560b3f1 F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -327,7 +327,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 059991ce76b1a857cb84dd2469cfcfaaae1d77fa +F src/pager.c 2f9de81ebc87f92814ffc1e34f478a6de7c869b0 F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef @@ -342,7 +342,7 @@ F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 167b4e9058bc8e997d18d6b6b20ecbb0c9c457af F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621 -F src/sqlite.h.in e7da8d15141d0753bfe14945bd64592a42575c04 +F src/sqlite.h.in 3cfc86c55e57c63d86b9e1e92869e2bfb162ca8e F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 F src/sqliteInt.h b1e72ffe282c91ae30a2bf403319126dbaebd556 @@ -511,7 +511,7 @@ F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 -F test/cffault.test 1383919788fa50db60f6119da5785c62fbc8b527 +F test/cffault.test 1647eef45512817265c360ed4539538eed26ac69 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 @@ -1397,10 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 001854181640bd9b088f2bc16083d84808c3da18 -R 2dbc861fa3cf60b53d3ec06b17c9981a -T *branch * cacheflush -T *sym-cacheflush * -T -sym-trunk * +P 65b86dc1fa4a57cc3cde86a820d9f848aa288a15 +R a2eb49b0b44e5f6d387cfe5db61ab944 U dan -Z c07109c8cca9fe678b00367209f93a20 +Z 0108dff3f79bd94c840ccf22fb26067f diff --git a/manifest.uuid b/manifest.uuid index ac6d5b874a..114b47522f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65b86dc1fa4a57cc3cde86a820d9f848aa288a15 \ No newline at end of file +370b5d520c6523526988d0db5299f1bd09567782 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 324415b0cf..56d4588494 100644 --- a/src/main.c +++ b/src/main.c @@ -765,9 +765,6 @@ int sqlite3_db_cacheflush(sqlite3 *db){ } } } - if( rc!=SQLITE_OK ){ - sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - } sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc); diff --git a/src/pager.c b/src/pager.c index f21f0802ba..09d4935f27 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4477,9 +4477,10 @@ static int pagerStress(void *p, PgHdr *pPg){ ** Flush all unreferenced dirty pages to disk. */ int sqlite3PagerFlush(Pager *pPager){ - int rc = SQLITE_OK; + int rc = pPager->errCode; PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + assert( assert_pager_state(pPager) ); while( rc==SQLITE_OK && pList ){ PgHdr *pNext = pList->pDirty; if( pList->nRef==0 ){ @@ -6093,14 +6094,17 @@ int sqlite3PagerSync(Pager *pPager, const char *zMaster){ ** returned. */ int sqlite3PagerExclusiveLock(Pager *pPager){ - int rc = SQLITE_OK; - assert( pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - || pPager->eState==PAGER_WRITER_LOCKED - ); + int rc = pPager->errCode; assert( assert_pager_state(pPager) ); - if( 0==pagerUseWal(pPager) ){ - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + if( rc==SQLITE_OK ){ + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_WRITER_LOCKED + ); + assert( assert_pager_state(pPager) ); + if( 0==pagerUseWal(pPager) ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } } return rc; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 6c04ff5102..961c5169fc 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7814,7 +7814,6 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); ** If any other error occurs while flushing dirty pages to disk (for ** example an IO error or out-of-memory condition), then processing is ** abandoned and an SQLite error code returned to the caller immediately. -** In this case the open transaction may be automatically rolled back. ** ** Otherwise, if no error occurs, SQLITE_OK is returned. ** diff --git a/test/cffault.test b/test/cffault.test index e90bbac55f..a89477b617 100644 --- a/test/cffault.test +++ b/test/cffault.test @@ -38,7 +38,7 @@ do_execsql_test 1.0 { } faultsim_save_and_close -do_faultsim_test 1 -prep { +do_faultsim_test 1.1 -prep { faultsim_restore_and_reopen db eval { BEGIN; @@ -47,11 +47,113 @@ do_faultsim_test 1 -prep { } -body { sqlite3_db_cacheflush db } -test { + if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" } faultsim_test_result {0 {}} {1 {disk I/O error}} catch { db eval COMMIT } faultsim_integrity_check } +do_faultsim_test 1.2 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b+1; + } +} -body { + set result [list] + db eval { SELECT * FROM t1 } { + if {$a==5} { catch { sqlite3_db_cacheflush db } } + lappend result $a $b + } + set result +} -test { + faultsim_test_result {0 {1 3 3 5 5 7 7 9}} {1 {disk I/O error}} + catch { db eval COMMIT } + faultsim_integrity_check +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + CREATE INDEX i2 ON t1(c, b); + INSERT INTO t1 VALUES(1, 2, randomblob(600)); + INSERT INTO t1 VALUES(3, 4, randomblob(600)); + INSERT INTO t1 VALUES(5, 6, randomblob(600)); + INSERT INTO t1 VALUES(7, 8, randomblob(600)); + INSERT INTO t1 VALUES(9, 10, randomblob(600)); +} +faultsim_save_and_close + +do_faultsim_test 2.1 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b+1; + } +} -body { + set result [list] + db eval { SELECT * FROM t1 } { + if {$a==5} { catch { sqlite3_db_cacheflush db } } + lappend result $a $b + } + set result +} -test { + faultsim_test_result {0 {1 3 3 5 5 7 7 9 9 11}} {1 {disk I/O error}} + catch { db eval { INSERT INTO t1 VALUES(11, 12, randomblob(600)) } } + catch { db eval COMMIT } + faultsim_integrity_check +} + +do_faultsim_test 2.2 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b+1; + } +} -body { + sqlite3_db_cacheflush db +} -test { + if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" } + faultsim_test_result {0 {}} {1 {disk I/O error}} + catch { db eval { SELECT * FROM t1 } } + catch { db eval COMMIT } + faultsim_integrity_check +} + +do_faultsim_test 2.3 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b-1; + } +} -body { + sqlite3_db_cacheflush db +} -test { + if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" } + faultsim_test_result {0 {}} {1 {disk I/O error}} + catch { db eval { INSERT INTO t1 VALUES(11, 12, randomblob(600)) } } + catch { db eval COMMIT } + faultsim_integrity_check +} + +do_faultsim_test 2.4 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b-1; + } +} -body { + catch { sqlite3_db_cacheflush db } + catch { sqlite3_db_release_memory db } + catch { sqlite3_db_cacheflush db } + execsql { SELECT a, b FROM t1 } +} -test { + faultsim_test_result {0 {1 1 3 3 5 5 7 7 9 9}} {1 {disk I/O error}} + catchsql ROLLBACK + faultsim_integrity_check +} finish_test From 4a6beac28b3d76f20147ab6a62c8445051fffd9a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Oct 2015 20:57:06 +0000 Subject: [PATCH 3/6] Add a test case that calls sqlite3_db_cacheflush() on an in-memory database. FossilOrigin-Name: f0cdfb547b0976e753e94958f29cb294edf31bed --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/cacheflush.test | 28 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 4ea95b624f..8aa65b5535 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sautomatically\srolling\sback\sthe\stransaction\sif\san\sSQLITE_IOERR\sor\sSQLITE_FULL\serror\soccurs\swithin\ssqlite3_db_cacheflush(). -D 2015-10-29T18:16:40.382 +C Add\sa\stest\scase\sthat\scalls\ssqlite3_db_cacheflush()\son\san\sin-memory\sdatabase. +D 2015-10-29T20:57:06.654 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -503,7 +503,7 @@ F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99 F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de -F test/cacheflush.test 95944e4210100c525ec301c060721e82210c33a5 +F test/cacheflush.test 42855120d2b00ff75033b54ba7693927f1ce4de8 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 65b86dc1fa4a57cc3cde86a820d9f848aa288a15 -R a2eb49b0b44e5f6d387cfe5db61ab944 +P 370b5d520c6523526988d0db5299f1bd09567782 +R e469742ef6d00761a1fbbbbf9de3f4b1 U dan -Z 0108dff3f79bd94c840ccf22fb26067f +Z 9ba99da9a0f7b492a3cba8ddbf944bbf diff --git a/manifest.uuid b/manifest.uuid index 114b47522f..b806a0d731 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -370b5d520c6523526988d0db5299f1bd09567782 \ No newline at end of file +f0cdfb547b0976e753e94958f29cb294edf31bed \ No newline at end of file diff --git a/test/cacheflush.test b/test/cacheflush.test index a9ee672b9f..785bc0c77a 100644 --- a/test/cacheflush.test +++ b/test/cacheflush.test @@ -202,6 +202,34 @@ do_test 2.2.6 { } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} do_execsql_test 2.2.7 { COMMIT } +#------------------------------------------------------------------------- +# Test that nothing terrible happens if sqlite3_db_cacheflush() is +# called on an in-memory database. +# +do_test 3.0 { + db close + sqlite3 db :memory: + db eval { + CREATE TABLE t1(x PRIMARY KEY); + CREATE TABLE t2(y PRIMARY KEY); + BEGIN; + INSERT INTO t1 VALUES(randomblob(100)); + INSERT INTO t2 VALUES(randomblob(100)); + INSERT INTO t1 VALUES(randomblob(100)); + INSERT INTO t2 VALUES(randomblob(100)); + } + sqlite3_db_cacheflush db +} {} + +do_execsql_test 3.1 { PRAGMA integrity_check } ok +do_execsql_test 3.2 { COMMIT } +do_execsql_test 3.3 { PRAGMA integrity_check } ok +do_execsql_test 3.4 { + SELECT count(*) FROM t1; + SELECT count(*) FROM t2; +} {2 2} + + test_restore_config_pagecache finish_test From 9fb13abc6ef9f1a02c99f173a586ed24922c4a46 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Oct 2015 21:11:22 +0000 Subject: [PATCH 4/6] Do not attempt to flush the pages of an in-memory database to disk if sqlite3_db_cacheflush() is called. FossilOrigin-Name: 9b79a390440a23542a370b591e567b31ebb35c42 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 17 +++++++++-------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 8aa65b5535..2b97b8e039 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sthat\scalls\ssqlite3_db_cacheflush()\son\san\sin-memory\sdatabase. -D 2015-10-29T20:57:06.654 +C Do\snot\sattempt\sto\sflush\sthe\spages\sof\san\sin-memory\sdatabase\sto\sdisk\sif\ssqlite3_db_cacheflush()\sis\scalled. +D 2015-10-29T21:11:22.422 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -327,7 +327,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 2f9de81ebc87f92814ffc1e34f478a6de7c869b0 +F src/pager.c b588107ee55ff4121c114949ff51a56aab21f3ac F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 370b5d520c6523526988d0db5299f1bd09567782 -R e469742ef6d00761a1fbbbbf9de3f4b1 +P f0cdfb547b0976e753e94958f29cb294edf31bed +R dcdd2b431259b301d28dfb5e7d9d6d5d U dan -Z 9ba99da9a0f7b492a3cba8ddbf944bbf +Z 1371a31e24aaed4ace229bd9de4453e9 diff --git a/manifest.uuid b/manifest.uuid index b806a0d731..8abded1106 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0cdfb547b0976e753e94958f29cb294edf31bed \ No newline at end of file +9b79a390440a23542a370b591e567b31ebb35c42 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 09d4935f27..ea867127e0 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4478,15 +4478,16 @@ static int pagerStress(void *p, PgHdr *pPg){ */ int sqlite3PagerFlush(Pager *pPager){ int rc = pPager->errCode; - PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); - - assert( assert_pager_state(pPager) ); - while( rc==SQLITE_OK && pList ){ - PgHdr *pNext = pList->pDirty; - if( pList->nRef==0 ){ - rc = pagerStress((void*)pPager, pList); + if( !MEMDB ){ + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + assert( assert_pager_state(pPager) ); + while( rc==SQLITE_OK && pList ){ + PgHdr *pNext = pList->pDirty; + if( pList->nRef==0 ){ + rc = pagerStress((void*)pPager, pList); + } + pList = pNext; } - pList = pNext; } return rc; From e8e6657fa7c3f977afa4a9237a747e80b931bb43 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Oct 2015 09:13:29 +0000 Subject: [PATCH 5/6] Test that calling sqlite3_db_cacheflush() does not interfere with savepoints. FossilOrigin-Name: 0e09e4a26938cfe0f573449526a8f0f527cef921 --- manifest | 12 +++--- manifest.uuid | 2 +- test/cacheflush.test | 89 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 2b97b8e039..2da7a2f9cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sattempt\sto\sflush\sthe\spages\sof\san\sin-memory\sdatabase\sto\sdisk\sif\ssqlite3_db_cacheflush()\sis\scalled. -D 2015-10-29T21:11:22.422 +C Test\sthat\scalling\ssqlite3_db_cacheflush()\sdoes\snot\sinterfere\swith\ssavepoints. +D 2015-10-30T09:13:29.814 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -503,7 +503,7 @@ F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99 F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de -F test/cacheflush.test 42855120d2b00ff75033b54ba7693927f1ce4de8 +F test/cacheflush.test a755c93482ce2e20c04825304bef27e7b7ea0111 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f0cdfb547b0976e753e94958f29cb294edf31bed -R dcdd2b431259b301d28dfb5e7d9d6d5d +P 9b79a390440a23542a370b591e567b31ebb35c42 +R b3b377e425858b0fc40d0f4a8e28ca4d U dan -Z 1371a31e24aaed4ace229bd9de4453e9 +Z 2687c0f7a67bbeeb26b2f80bb787cd41 diff --git a/manifest.uuid b/manifest.uuid index 8abded1106..6b4639c096 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b79a390440a23542a370b591e567b31ebb35c42 \ No newline at end of file +0e09e4a26938cfe0f573449526a8f0f527cef921 \ No newline at end of file diff --git a/test/cacheflush.test b/test/cacheflush.test index 785bc0c77a..007ee8a065 100644 --- a/test/cacheflush.test +++ b/test/cacheflush.test @@ -229,6 +229,95 @@ do_execsql_test 3.4 { SELECT count(*) FROM t2; } {2 2} +#------------------------------------------------------------------------- +# Test that calling sqlite3_db_cacheflush() does not interfere with +# savepoint transactions. +# +do_test 4.0 { + reset_db + execsql { + CREATE TABLE ta(a, aa); + CREATE TABLE tb(b, bb); + INSERT INTO ta VALUES('a', randomblob(500)); + INSERT INTO tb VALUES('b', randomblob(500)); + BEGIN; + UPDATE ta SET a = 'A'; + SAVEPOINT one; + UPDATE tb SET b = 'B'; + } + + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A B} + +do_test 4.1 { + execsql { + ROLLBACK TO one; + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A b} + +do_test 4.2 { + execsql { + INSERT INTO tb VALUES('c', randomblob(10)); + INSERT INTO tb VALUES('d', randomblob(10)); + INSERT INTO tb VALUES('e', randomblob(10)); + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A b c d e} + +do_test 4.3 { + execsql { + SAVEPOINT two; + UPDATE tb SET b = upper(b); + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A B C D E} + +do_test 4.4 { + execsql { + ROLLBACK TO two; + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A b c d e} + +do_test 4.4 { + execsql { + ROLLBACK TO one; + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A b} + +do_test 4.5 { + execsql { + ROLLBACK; + SELECT a FROM ta; + SELECT b FROM tb; + } +} {a b} test_restore_config_pagecache finish_test From 5596eb30209450b22d9e61f038f9cf68d637a5b3 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Oct 2015 14:28:16 +0000 Subject: [PATCH 6/6] Return immediately if sqlite3PagerWrite() is called when the pager is in PAGER_ERROR state. FossilOrigin-Name: a6695b008487aeb7badf572fa32bfcba3c9fab03 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2da7a2f9cb..0497ff0353 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\sthat\scalling\ssqlite3_db_cacheflush()\sdoes\snot\sinterfere\swith\ssavepoints. -D 2015-10-30T09:13:29.814 +C Return\simmediately\sif\ssqlite3PagerWrite()\sis\scalled\swhen\sthe\spager\sis\sin\sPAGER_ERROR\sstate. +D 2015-10-30T14:28:16.049 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -327,7 +327,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c b588107ee55ff4121c114949ff51a56aab21f3ac +F src/pager.c 9c1eec0d88133484b165fa0b5284a411c24b964c F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9b79a390440a23542a370b591e567b31ebb35c42 -R b3b377e425858b0fc40d0f4a8e28ca4d +P 0e09e4a26938cfe0f573449526a8f0f527cef921 +R f396f7a1d6ed17b52257ec59a2b63902 U dan -Z 2687c0f7a67bbeeb26b2f80bb787cd41 +Z 76885908163af131d9fcc88a11feb178 diff --git a/manifest.uuid b/manifest.uuid index 6b4639c096..07944153ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e09e4a26938cfe0f573449526a8f0f527cef921 \ No newline at end of file +a6695b008487aeb7badf572fa32bfcba3c9fab03 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index ea867127e0..314f792aa0 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5915,9 +5915,10 @@ int sqlite3PagerWrite(PgHdr *pPg){ Pager *pPager = pPg->pPager; assert( (pPg->flags & PGHDR_MMAP)==0 ); assert( pPager->eState>=PAGER_WRITER_LOCKED ); - assert( pPager->eState!=PAGER_ERROR ); assert( assert_pager_state(pPager) ); - if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ + if( pPager->errCode ){ + return pPager->errCode; + }else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); return SQLITE_OK; }else if( pPager->sectorSize > (u32)pPager->pageSize ){