]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix another RBU case similar to the previous. This one for systems where the
authordan <dan@noemail.net>
Tue, 7 Mar 2017 14:46:25 +0000 (14:46 +0000)
committerdan <dan@noemail.net>
Tue, 7 Mar 2017 14:46:25 +0000 (14:46 +0000)
sector-size is larger than the page-size. Cherrypick of [4012bb3a].

FossilOrigin-Name: 59a11b7f1f4aeefec7102b4859deda70b0b934b9

ext/rbu/rbucrash2.test
ext/rbu/rbuprogress.test
ext/rbu/sqlite3rbu.c
manifest
manifest.uuid

index 89c2535a93aa42f46f91b9018c75dd43db177b26..5f2ba604d12714ddcb6488b345fa55483f270178 100644 (file)
@@ -45,7 +45,12 @@ db_save_and_close
 
 proc do_rbu_crash_test2 {tn script} {
 
-  foreach f {test.db test.db2} {
+  foreach {f blksz} {
+    test.db   512
+    test.db2  512
+    test.db   4096
+    test.db2  4096
+  } {
     set bDone 0
     for {set iDelay 1} {$bDone==0} {incr iDelay} {
       forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal
@@ -53,7 +58,7 @@ proc do_rbu_crash_test2 {tn script} {
   
       set res [
         crashsql -file $f -delay $iDelay -tclbody $script -dflt 1 -opendb {} \
-            -blocksize 512 {}
+            -blocksize $blksz {}
       ]
   
       set bDone 1
@@ -68,7 +73,7 @@ proc do_rbu_crash_test2 {tn script} {
       rbu close
   
       sqlite3 db test.db
-      do_execsql_test $tn.delay=$iDelay.f=$f {
+      do_execsql_test $tn.delay=$iDelay.f=$f.blksz=$blksz {
         PRAGMA integrity_check;
       } {ok}
       db close
index af202829c13570d00061632400abcb213cf3bd01..078b3b0d300521388dd44aac5aa6a366e942f1e8 100644 (file)
@@ -40,6 +40,7 @@ proc create_rbu1 {filename} {
 
 
 do_execsql_test 1.0 {
+  PRAGMA page_size = 4096;
   CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
 }
 
@@ -266,6 +267,7 @@ foreach bReopen {0 1} {
   do_test 3.$bReopen.1.0 {
     reset_db
     execsql {
+      PRAGMA page_size = 4096;
       CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
       CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
       CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
index 262f96ea3c62c2acb613080ddb4b0753416660ad..163a5442599da51ee5ca8775546b8db2c6071e7e 100644 (file)
@@ -356,6 +356,7 @@ struct sqlite3rbu {
   RbuObjIter objiter;             /* Iterator for skipping through tbl/idx */
   const char *zVfsName;           /* Name of automatically created rbu vfs */
   rbu_file *pTargetFd;            /* File handle open on target db */
+  int nPagePerSector;             /* Pages per sector for pTargetFd */
   i64 iOalSz;
   i64 nPhaseOneStep;
 
@@ -2620,6 +2621,16 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
     if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
       p->rc = SQLITE_DONE;
       p->eStage = RBU_STAGE_DONE;
+    }else{
+      int nSectorSize;
+      sqlite3_file *pDb = p->pTargetFd->pReal;
+      assert( p->nPagePerSector==0 );
+      nSectorSize = pDb->pMethods->xSectorSize(pDb);
+      if( nSectorSize>p->pgsz ){
+        p->nPagePerSector = nSectorSize / p->pgsz;
+      }else{
+        p->nPagePerSector = 1;
+      }
     }
   }
 }
@@ -3275,9 +3286,26 @@ int sqlite3rbu_step(sqlite3rbu *p){
               p->rc = SQLITE_DONE;
             }
           }else{
-            RbuFrame *pFrame = &p->aFrame[p->nStep];
-            rbuCheckpointFrame(p, pFrame);
-            p->nStep++;
+            /* At one point the following block copied a single frame from the
+            ** wal file to the database file. So that one call to sqlite3rbu_step()
+            ** checkpointed a single frame. 
+            **
+            ** However, if the sector-size is larger than the page-size, and the
+            ** application calls sqlite3rbu_savestate() or close() immediately
+            ** after this step, then rbu_step() again, then a power failure occurs,
+            ** then the database page written here may be damaged. Work around
+            ** this by checkpointing frames until the next page in the aFrame[]
+            ** lies on a different disk sector to the current one. */
+            u32 iSector;
+            do{
+              RbuFrame *pFrame = &p->aFrame[p->nStep];
+              iSector = (pFrame->iDbPage-1) / p->nPagePerSector;
+              rbuCheckpointFrame(p, pFrame);
+              p->nStep++;
+            }while( p->nStep<p->nFrame 
+                 && iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector)
+                 && p->rc==SQLITE_OK
+            );
           }
           p->nProgress++;
         }
index fde1b52ddd8543392a97a55ecc1dc41708b02dfb..156ffb6f1974c488c509998a930a135797616698 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C When\ssaving\sthe\sstate\sof\san\sRBU\supdate\sin\sthe\sincremental-checkpoint\sphase,\nsync\sthe\sdatabase\sfile.\sOtherwise,\sif\sa\spower\sfailure\soccurs\sand\sthe\sRBU\nupdate\sresumed\sfollowing\ssystem\srecovery,\sthe\sdatabase\smay\sbecome\scorrupt.\nCherrypick\sof\s[edee6a80].
-D 2017-03-07T14:45:52.361
+C Fix\sanother\sRBU\scase\ssimilar\sto\sthe\sprevious.\sThis\sone\sfor\ssystems\swhere\sthe\nsector-size\sis\slarger\sthan\sthe\spage-size.\sCherrypick\sof\s[4012bb3a].
+D 2017-03-07T14:46:25.116
 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99
@@ -248,7 +248,7 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2
 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831
 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead
 F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
-F ext/rbu/rbucrash2.test 7f3fe5d6d930be0965f27b49bdcdc8d4a078b73c
+F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d
 F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5
 F ext/rbu/rbudor.test 99b05cc0df613e962c2c8085cfb05686a09cf315
 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
@@ -256,12 +256,12 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca
 F ext/rbu/rbufault4.test 34e70701cbec51571ffbd9fbf9d4e0f2ec495ca7
 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
-F ext/rbu/rbuprogress.test e3e25fb7622641b8f2df7c6b7a7eb6fddfc46a4b
+F ext/rbu/rbuprogress.test 1849d4e0e50616edf5ce75ce7db86622e656b5cf
 F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83
 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0
 F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
-F ext/rbu/sqlite3rbu.c 3c2dfd3f27a3ecc5f017ecf82d563b522bbc341a
+F ext/rbu/sqlite3rbu.c cba23db39792175295b94ad0086825894b617921
 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba
 F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88
 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
@@ -1556,11 +1556,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c
-Q +edee6a80e1cc7e6a2b8c3c7f76dd794fc8ab9a72
-R 91db754cfeb563563988e769f6229ad8
-T *branch * version-3.17.0-rbu-fixes
-T *sym-version-3.17.0-rbu-fixes *
-T -sym-branch-3.17 *
+P 811a559967d886239fc0b16fac08707c78e60988
+Q +4012bb3aa91927156ba149caa4e5c622b0729d79
+R d9b66f58a0523dc7bc0a62014299d641
 U dan
-Z 7d44df21d9e63c1b485963a694227beb
+Z c2e9b5702f8f818cb604d64fafb45a3c
index a99a465b9d518502f5a9acc100f88419464139f7..a07d14ac758cf39e4f3da2a5e630a380433b8596 100644 (file)
@@ -1 +1 @@
-811a559967d886239fc0b16fac08707c78e60988
\ No newline at end of file
+59a11b7f1f4aeefec7102b4859deda70b0b934b9
\ No newline at end of file