/ Check-in [38dd9b50]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a problem allowing a conflicting transaction to be committed in the case where more than one 32KB shared-memory page has been written to since the transaction was started.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent
Files: files | file ages | folders
SHA3-256: 38dd9b50fe260d853cbc2551bc1bb60ddf5752f0456e0da3afe4cbf728c891d8
User & Date: dan 2017-08-11 21:16:23
Wiki:begin-concurrent
Context
2017-08-15
01:07
Fix a problem allowing a conflicting transaction to be committed in the case where more than one 32KB shared-memory page has been written to since the transaction was started. check-in: 346a710d user: drh tags: begin-concurrent-branch-3.19
2017-08-12
14:06
Add a more rigorous test case for the bug fixed by the previous commit on this branch. check-in: 42560723 user: dan tags: begin-concurrent
2017-08-11
21:16
Fix a problem allowing a conflicting transaction to be committed in the case where more than one 32KB shared-memory page has been written to since the transaction was started. check-in: 38dd9b50 user: dan tags: begin-concurrent
20:22
Add another PAGERTRACE() macro to show when pages are added to Pager.pAllRead. No impact on production builds. check-in: 11054cf5 user: drh tags: begin-concurrent
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/wal.c.

  2896   2896           volatile ht_slot *aHash;
  2897   2897           volatile u32 *aPgno;
  2898   2898           u32 iZero;
  2899   2899   
  2900   2900           rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
  2901   2901           if( rc==SQLITE_OK ){
  2902   2902             u32 i, iMin, iMax;
  2903         -          assert( iFirst >= iZero );
  2904         -          iMin = (iFirst - iZero);
         2903  +          assert( head.mxFrame>=iZero );
         2904  +          iMin = (iZero >= iFirst) ? 1 : (iFirst - iZero);
  2905   2905             iMax = (iHash==0) ? HASHTABLE_NPAGE_ONE : HASHTABLE_NPAGE;
  2906         -          if( iMin<1 ) iMin = 1;
  2907         -          if( iMax>head.mxFrame ) iMax = head.mxFrame;
         2906  +          if( iMax>(head.mxFrame-iZero) ) iMax = (head.mxFrame-iZero);
  2908   2907             for(i=iMin; rc==SQLITE_OK && i<=iMax; i++){
  2909   2908               PgHdr *pPg;
  2910   2909               if( aPgno[i]==1 ){
  2911   2910                 /* Check that the schema cookie has not been modified. If
  2912   2911                 ** it has not, the commit can proceed. */
  2913   2912                 u8 aNew[4];
  2914   2913                 u8 *aOld = &((u8*)pPage1->pData)[40];

Changes to test/concurrent.test.

   552    552         INSERT INTO t2 VALUES(3, 'three');
   553    553       }
   554    554     } {}
   555    555   
   556    556     do_test 6.$tn.2 {
   557    557       list [catch { sql2 { COMMIT } } msg] $msg
   558    558     } {1 {database is locked}}
          559  +}
          560  +
          561  +do_multiclient_test tn {
          562  +  do_test 7.$tn.1 {
          563  +    sql1 {
          564  +      PRAGMA journal_mode = wal;
          565  +      CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
          566  +      WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100) 
          567  +      INSERT INTO t1 SELECT NULL, randomblob(400) FROM s;
          568  +
          569  +      CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
          570  +      WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<50000) 
          571  +      INSERT INTO t2 SELECT NULL, randomblob(400) FROM s;
          572  +
          573  +      CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
          574  +      WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100) 
          575  +      INSERT INTO t3 SELECT NULL, randomblob(400) FROM s;
          576  +
          577  +      CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
          578  +
          579  +      PRAGMA wal_checkpoint;
          580  +    }
          581  +    set {} {}
          582  +  } {}
          583  +
          584  +  do_test 7.$tn.2 {
          585  +    sql2 {
          586  +      BEGIN CONCURRENT;
          587  +        SELECT * FROM t1;
          588  +        INSERT INTO t4 VALUES(1, 2);
          589  +    }
          590  +    set {} {}
          591  +  } {}
          592  +
          593  +  do_test 7.$tn.3 {
          594  +    sql3 {
          595  +      BEGIN CONCURRENT;
          596  +        SELECT * FROM t3;
          597  +        INSERT INTO t4 VALUES(1, 2);
          598  +    }
          599  +    set {} {}
          600  +  } {}
          601  +
          602  +  do_test 7.$tn.4 {
          603  +    sql1 {
          604  +      UPDATE t1 SET b=randomblob(400);
          605  +      UPDATE t2 SET b=randomblob(400);
          606  +      UPDATE t3 SET b=randomblob(400);
          607  +    }
          608  +  } {}
          609  +
          610  +  do_test 7.$tn.5 {
          611  +    csql2 { COMMIT } 
          612  +  } {1 {database is locked}}
          613  +
          614  +  do_test 7.$tn.6 {
          615  +    csql3 { COMMIT } 
          616  +  } {1 {database is locked}}
          617  +
   559    618   }
   560    619   
   561    620   finish_test