/ Check-in [221ff63e]
Login

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

Overview
Comment:In wal mode, if a "BEGIN EXCLUSIVE" command (or any other command that upgrades from no transaction directly to a write transaction) hits an SQLITE_BUSY_SNAPSHOT error, change the error code to SQLITE_BUSY to indicate to the caller that the condition may be transient.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | exp-busy-snapshot-fix
Files: files | file ages | folders
SHA3-256: 221ff63e7902226ebf728bb7442727420636831163708f360724506ce9487ab6
User & Date: dan 2018-07-05 15:46:55
Context
2018-07-05
17:03
Fix a typo inside an assert() statement introduced by the previous commit. Closed-Leaf check-in: e3357728 user: dan tags: exp-busy-snapshot-fix
15:46
In wal mode, if a "BEGIN EXCLUSIVE" command (or any other command that upgrades from no transaction directly to a write transaction) hits an SQLITE_BUSY_SNAPSHOT error, change the error code to SQLITE_BUSY to indicate to the caller that the condition may be transient. check-in: 221ff63e user: dan tags: exp-busy-snapshot-fix
2018-07-03
20:17
Test that a race condition can cause a "BEGIN EXCLUSIVE" to return SQLITE_BUSY_SNAPSHOT in wal mode. check-in: 5a12db75 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  3420   3420         if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){
  3421   3421           rc = sqlite3PagerWrite(pPage1->pDbPage);
  3422   3422           if( rc==SQLITE_OK ){
  3423   3423             put4byte(&pPage1->aData[28], pBt->nPage);
  3424   3424           }
  3425   3425         }
  3426   3426       }
         3427  +  }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
         3428  +    /* Even if there was no transaction opened when this function was
         3429  +    ** called, a race condition may cause an SQLITE_BUSY_SNAPSHOT error
         3430  +    ** in wal mode (since the code above opens a read-transaction and then
         3431  +    ** upgrades it to a write-transaction - it does not take the write lock
         3432  +    ** atomically). In this case change the error code to SQLITE_BUSY.  */
         3433  +    assert( wrFlag );
         3434  +    rc = SQLITE_BUSY;
  3427   3435     }
  3428   3436   
  3429   3437   
  3430   3438   trans_begun:
  3431   3439     if( rc==SQLITE_OK ){
  3432   3440       if( pSchemaVersion ){
  3433   3441         *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);

Changes to test/walprotocol2.test.

    68     68     }
    69     69   }
    70     70   do_catchsql_test 2.2 {
    71     71     BEGIN EXCLUSIVE;
    72     72   } {1 {database is locked}}
    73     73   do_test 2.3 {
    74     74     sqlite3_extended_errcode db
    75         -} {SQLITE_BUSY_SNAPSHOT}
           75  +} {SQLITE_BUSY}
    76     76   
    77     77   #---------------------------------------------------------------
    78     78   # Same again, but with a busy-handler. This time, following the
    79     79   # SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the 
    80     80   # whole thing retried from the beginning. This time it succeeds.
    81     81   #
    82     82   proc lock_callback {method filename handle lock} {