/ Check-in [3674b25e]
Login

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

Overview
Comment:Turn on the atomic multifile commit logic. It does not work right yet, but it has at least stopped failing asserts. (CVS 1550)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3674b25edc37145b2b1275dd20580015ace66aa7
User & Date: drh 2004-06-09 20:03:09
Context
2004-06-09
21:01
If a commit fails due to lock contention right after the COMMIT command, take the database back out of autocommit mode. Do not rollback. This gives the user the chance to try the COMMIT again. (CVS 1551) check-in: 39b4ba95 user: drh tags: trunk
20:03
Turn on the atomic multifile commit logic. It does not work right yet, but it has at least stopped failing asserts. (CVS 1550) check-in: 3674b25e user: drh tags: trunk
19:03
Remove legacy journal formats. (CVS 1549) check-in: a12bef4a user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.162 2004/06/09 17:37:23 drh Exp $
           12  +** $Id: btree.c,v 1.163 2004/06/09 20:03:09 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
  1246   1246     }
  1247   1247   
  1248   1248     if( pBt->pPage1==0 ){
  1249   1249       rc = lockBtree(pBt);
  1250   1250     }
  1251   1251   
  1252   1252     if( rc==SQLITE_OK && wrflag ){
  1253         -    rc = sqlite3pager_begin(pBt->pPage1->aData, 0);
         1253  +    rc = sqlite3pager_begin(pBt->pPage1->aData, nMaster);
  1254   1254       if( rc==SQLITE_OK ){
  1255   1255         rc = newDatabase(pBt);
  1256   1256       }
  1257   1257     }
  1258   1258   
  1259   1259     if( rc==SQLITE_OK ){
  1260   1260       pBt->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.209 2004/06/09 12:30:06 danielk1977 Exp $
           17  +** $Id: main.c,v 1.210 2004/06/09 20:03:09 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** A pointer to this structure is used to communicate information
................................................................................
  1029   1029   
  1030   1030     /* Also add a UTF-8 case-insensitive collation sequence. */
  1031   1031     sqlite3_create_collation(db, "NOCASE", 0, 0, nocaseCollatingFunc);
  1032   1032   
  1033   1033     /* Open the backend database driver */
  1034   1034     if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
  1035   1035       db->temp_store = 2;
         1036  +    db->nMaster = 0;    /* Disable atomic multi-file commit for :memory: */
         1037  +  }else{
         1038  +    db->nMaster = -1;   /* Size of master journal filename initially unknown */
  1036   1039     }
  1037   1040     rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
  1038   1041     if( rc!=SQLITE_OK ){
  1039   1042       /* FIX ME: sqlite3BtreeFactory() should call sqlite3Error(). */
  1040   1043       sqlite3Error(db, rc, 0);
  1041   1044       db->magic = SQLITE_MAGIC_CLOSED;
  1042   1045       goto opendb_out;
................................................................................
  1157   1160   ){
  1158   1161     int rc;
  1159   1162     char *zName8 = sqlite3utf16to8(zName, -1, SQLITE_BIGENDIAN);
  1160   1163     rc = sqlite3_create_collation(db, zName8, pref16, pCtx, xCompare);
  1161   1164     sqliteFree(zName8);
  1162   1165     return rc;
  1163   1166   }
  1164         -

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.116 2004/06/09 19:03:55 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.117 2004/06/09 20:03:09 drh Exp $
    22     22   */
    23     23   #include "os.h"         /* Must be first to enable large file support */
    24     24   #include "sqliteInt.h"
    25     25   #include "pager.h"
    26     26   #include <assert.h>
    27     27   #include <string.h>
    28     28   
................................................................................
  1930   1930     if( rc==SQLITE_OK ){
  1931   1931       rc = write32bits(&pPager->jfd, pPager->dbSize);
  1932   1932     }
  1933   1933     if( rc==SQLITE_OK ){
  1934   1934       rc = write32bits(&pPager->jfd, pPager->nMaster);
  1935   1935     }
  1936   1936     if( rc==SQLITE_OK ){
  1937         -    rc = sqlite3OsSeek(&pPager->jfd, 24 + pPager->nMaster);
         1937  +    sqlite3OsSeek(&pPager->jfd, 24 + pPager->nMaster - 1);
         1938  +    rc = sqlite3OsWrite(&pPager->jfd, "\000", 1);
  1938   1939     }
  1939   1940     if( pPager->stmtAutoopen && rc==SQLITE_OK ){
  1940   1941       rc = sqlite3pager_stmt_begin(pPager);
  1941   1942     }
  1942   1943     if( rc!=SQLITE_OK ){
  1943   1944       rc = pager_unwritelock(pPager);
  1944   1945       if( rc==SQLITE_OK ){

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.275 2004/06/09 14:01:51 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.276 2004/06/09 20:03:09 drh Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite3.h"
    18     18   #include "hash.h"
    19     19   #include "parse.h"
    20     20   #include <stdio.h>
    21     21   #include <stdlib.h>
................................................................................
   418    418   #endif
   419    419   
   420    420     int errCode;                  /* Most recent error code (SQLITE_*) */
   421    421     char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
   422    422     void *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
   423    423     u8 enc;                       /* Text encoding for this database. */
   424    424     u8 autoCommit;                /* The auto-commit flag. */
          425  +  int nMaster;                  /* Length of master journal name. -1=unknown */
   425    426   };
   426    427   
   427    428   /*
   428    429   ** Possible values for the sqlite.flags and or Db.flags fields.
   429    430   **
   430    431   ** On sqlite.flags, the SQLITE_InTrans value means that we have
   431    432   ** executed a BEGIN.  On Db.flags, SQLITE_InTrans means a statement

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.361 2004/06/09 09:55:19 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.362 2004/06/09 20:03:10 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  2315   2315     int i = pOp->p1;
  2316   2316     Btree *pBt;
  2317   2317   
  2318   2318     assert( i>=0 && i<db->nDb );
  2319   2319     pBt = db->aDb[i].pBt;
  2320   2320   
  2321   2321     if( pBt ){
  2322         -    int nMaster = strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt))+11;
  2323         -    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, nMaster);
         2322  +    if( db->nMaster<0 ){
         2323  +      db->nMaster = strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt))+20;
         2324  +    }
         2325  +    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, db->nMaster);
  2324   2326       if( rc==SQLITE_BUSY ){
  2325   2327           if( db->busyHandler.xFunc==0 ){
  2326   2328             p->pc = pc;
  2327   2329             p->rc = SQLITE_BUSY;
  2328   2330             p->pTos = pTos;
  2329   2331             return SQLITE_BUSY;
  2330   2332           }else{

Changes to src/vdbeaux.c.

   929    929         return SQLITE_CONSTRAINT;
   930    930       }
   931    931     }
   932    932   
   933    933     /* The simple case - no more than one database file (not counting the TEMP
   934    934     ** database) has a transaction active.   There is no need for the
   935    935     ** master-journal.
          936  +  **
          937  +  ** if db->nMaster==0, it means the main database is :memory:.  In that case
          938  +  ** we do not support atomic multi-file commits, so use the simple case then
          939  +  ** too.
   936    940     */
   937         -  if( nTrans<=100 ){  /**** FIX ME ****/
          941  +  if( db->nMaster<=0 || nTrans<=1 ){
   938    942       for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
   939    943         Btree *pBt = db->aDb[i].pBt;
   940    944         if( pBt ){
   941    945           rc = sqlite3BtreeSync(pBt, 0);
   942    946         }
   943    947       }
   944    948   
................................................................................
   970    974         zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random);
   971    975         if( !zMaster ){
   972    976           return SQLITE_NOMEM;
   973    977         }
   974    978       }while( sqlite3OsFileExists(zMaster) );
   975    979   
   976    980       /* Open the master journal. */
          981  +    assert( strlen(zMaster)<db->nMaster );
   977    982       rc = sqlite3OsOpenExclusive(zMaster, &master, 0);
   978    983       if( rc!=SQLITE_OK ){
   979    984         sqliteFree(zMaster);
   980    985         return rc;
   981    986       }
   982    987    
   983    988       /* Write the name of each database file in the transaction into the new
................................................................................
   984    989       ** master journal file. If an error occurs at this point close
   985    990       ** and delete the master journal file. All the individual journal files
   986    991       ** still have 'null' as the master journal pointer, so they will roll
   987    992       ** back independantly if a failure occurs.
   988    993       */
   989    994       for(i=0; i<db->nDb; i++){ 
   990    995         Btree *pBt = db->aDb[i].pBt;
          996  +      if( i==1 ) continue;   /* Ignore the TEMP database */
   991    997         if( pBt && sqlite3BtreeIsInTrans(pBt) ){
   992    998           char const *zFile = sqlite3BtreeGetFilename(pBt);
   993         -        rc = sqlite3OsWrite(&master, zFile, strlen(zFile));
   994         -        if( rc!=SQLITE_OK ){
   995         -          sqlite3OsClose(&master);
   996         -          sqlite3OsDelete(zMaster);
   997         -          sqliteFree(zMaster);
   998         -          return rc;
   999         -        }
  1000         -        rc = sqlite3OsWrite(&master, "\0", 1);
          999  +        if( zFile[0]==0 ) continue;  /* Ignore :memory: databases */
         1000  +        rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1);
  1001   1001           if( rc!=SQLITE_OK ){
  1002   1002             sqlite3OsClose(&master);
  1003   1003             sqlite3OsDelete(zMaster);
  1004   1004             sqliteFree(zMaster);
  1005   1005             return rc;
  1006   1006           }
  1007   1007         }
  1008   1008       }
  1009   1009   
  1010   1010       /* Sync the master journal file */
  1011   1011       rc = sqlite3OsSync(&master);
  1012   1012       sqlite3OsClose(&master);
         1013  +
         1014  +    /* FIXME:  Sync the directory that contains the master journal to
         1015  +    ** make sure the i-node is up to date. */
  1013   1016   
  1014   1017       /* Sync all the db files involved in the transaction. The same call
  1015   1018       ** sets the master journal pointer in each individual journal. If
  1016   1019       ** an error occurs here, do not delete the master journal file.
  1017   1020       **
  1018   1021       ** If the error occurs during the first call to sqlite3BtreeSync(),
  1019   1022       ** then there is a chance that the master journal file will be

Changes to test/pager2.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is page cache subsystem.
    13     13   #
    14         -# $Id: pager2.test,v 1.1 2004/05/12 13:30:09 drh Exp $
           14  +# $Id: pager2.test,v 1.2 2004/06/09 20:03:10 drh Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   if {[info commands pager_open]!=""} {
    21     21   db close
................................................................................
   118    118     set v [catch {
   119    119       page_write $::g1 "Page-One"
   120    120     } msg]
   121    121     lappend v $msg
   122    122   } {0 {}}
   123    123   do_test pager2-2.15 {
   124    124     pager_stats $::p1
   125         -} {ref 1 page 1 max 10 size 1 state 2 err 0 hit 1 miss 1 ovfl 0}
          125  +} {ref 1 page 1 max 10 size 1 state 3 err 0 hit 1 miss 1 ovfl 0}
   126    126   do_test pager2-2.16 {
   127    127     page_read $::g1
   128    128   } {Page-One}
   129    129   do_test pager2-2.17 {
   130    130     set v [catch {
   131    131       pager_commit $::p1
   132    132     } msg]
................................................................................
   291    291         }
   292    292       }
   293    293       set res
   294    294     } {}
   295    295     do_test pager2-4.5.$i.1 {
   296    296       page_write $g1 "Page-1 v$i"
   297    297       lrange [pager_stats $p1] 8 9
   298         -  } {state 2}
          298  +  } {state 3}
   299    299     do_test pager2-4.5.$i.2 {
   300    300       for {set j 2} {$j<=20} {incr j} {
   301    301         set gx [page_get $p1 $j]
   302    302         page_write $gx "Page-$j v$i"
   303    303         page_unref $gx
   304    304         if {$j==$i} {
   305    305           pager_stmt_begin $p1
................................................................................
   332    332         }
   333    333       }
   334    334       set res
   335    335     } {}
   336    336     do_test pager2-4.5.$i.5 {
   337    337       page_write $g1 "Page-1 v$i"
   338    338       lrange [pager_stats $p1] 8 9
   339         -  } {state 2}
          339  +  } {state 3}
   340    340     do_test pager2-4.5.$i.6 {
   341    341       for {set j 2} {$j<=20} {incr j} {
   342    342         set gx [page_get $p1 $j]
   343    343         page_write $gx "Page-$j v$i"
   344    344         page_unref $gx
   345    345         if {$j==$i} {
   346    346           pager_stmt_begin $p1