/ Check-in [38dd9b50]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 Unified Diffs Ignore Whitespace Patch

Changes to src/wal.c.

2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
        volatile ht_slot *aHash;
        volatile u32 *aPgno;
        u32 iZero;

        rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
        if( rc==SQLITE_OK ){
          u32 i, iMin, iMax;
          assert( iFirst >= iZero );
          iMin = (iFirst - iZero);
          iMax = (iHash==0) ? HASHTABLE_NPAGE_ONE : HASHTABLE_NPAGE;
          if( iMin<1 ) iMin = 1;
          if( iMax>head.mxFrame ) iMax = head.mxFrame;
          for(i=iMin; rc==SQLITE_OK && i<=iMax; i++){
            PgHdr *pPg;
            if( aPgno[i]==1 ){
              /* Check that the schema cookie has not been modified. If
              ** it has not, the commit can proceed. */
              u8 aNew[4];
              u8 *aOld = &((u8*)pPage1->pData)[40];







|
|

|
<







2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906

2907
2908
2909
2910
2911
2912
2913
        volatile ht_slot *aHash;
        volatile u32 *aPgno;
        u32 iZero;

        rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
        if( rc==SQLITE_OK ){
          u32 i, iMin, iMax;
          assert( head.mxFrame>=iZero );
          iMin = (iZero >= iFirst) ? 1 : (iFirst - iZero);
          iMax = (iHash==0) ? HASHTABLE_NPAGE_ONE : HASHTABLE_NPAGE;
          if( iMax>(head.mxFrame-iZero) ) iMax = (head.mxFrame-iZero);

          for(i=iMin; rc==SQLITE_OK && i<=iMax; i++){
            PgHdr *pPg;
            if( aPgno[i]==1 ){
              /* Check that the schema cookie has not been modified. If
              ** it has not, the commit can proceed. */
              u8 aNew[4];
              u8 *aOld = &((u8*)pPage1->pData)[40];

Changes to test/concurrent.test.

552
553
554
555
556
557
558
559
560



























































561
      INSERT INTO t2 VALUES(3, 'three');
    }
  } {}

  do_test 6.$tn.2 {
    list [catch { sql2 { COMMIT } } msg] $msg
  } {1 {database is locked}}
}




























































finish_test









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
      INSERT INTO t2 VALUES(3, 'three');
    }
  } {}

  do_test 6.$tn.2 {
    list [catch { sql2 { COMMIT } } msg] $msg
  } {1 {database is locked}}
}

do_multiclient_test tn {
  do_test 7.$tn.1 {
    sql1 {
      PRAGMA journal_mode = wal;
      CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
      WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100) 
      INSERT INTO t1 SELECT NULL, randomblob(400) FROM s;

      CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
      WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<50000) 
      INSERT INTO t2 SELECT NULL, randomblob(400) FROM s;

      CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
      WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100) 
      INSERT INTO t3 SELECT NULL, randomblob(400) FROM s;

      CREATE TABLE t4(a INTEGER PRIMARY KEY, b);

      PRAGMA wal_checkpoint;
    }
    set {} {}
  } {}

  do_test 7.$tn.2 {
    sql2 {
      BEGIN CONCURRENT;
        SELECT * FROM t1;
        INSERT INTO t4 VALUES(1, 2);
    }
    set {} {}
  } {}

  do_test 7.$tn.3 {
    sql3 {
      BEGIN CONCURRENT;
        SELECT * FROM t3;
        INSERT INTO t4 VALUES(1, 2);
    }
    set {} {}
  } {}

  do_test 7.$tn.4 {
    sql1 {
      UPDATE t1 SET b=randomblob(400);
      UPDATE t2 SET b=randomblob(400);
      UPDATE t3 SET b=randomblob(400);
    }
  } {}

  do_test 7.$tn.5 {
    csql2 { COMMIT } 
  } {1 {database is locked}}

  do_test 7.$tn.6 {
    csql3 { COMMIT } 
  } {1 {database is locked}}

}

finish_test