SQLite

Check-in [22e10cc24e]
Login

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

Overview
Comment:If an IO error is encountered on a commit, close the journal so that it persists and can (hopefully) rollback the failed transaction later. (CVS 3792)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 22e10cc24e4407feb276abfa8cc9964f20c6e54a
User & Date: drh 2007-04-02 11:22:22.000
Context
2007-04-02
12:22
In the amalgamation, put date.c before os.c so that the time_t typedef can be correctly resolved by windows compilers. (CVS 3793) (check-in: 9c5697c70f user: drh tags: trunk)
11:22
If an IO error is encountered on a commit, close the journal so that it persists and can (hopefully) rollback the failed transaction later. (CVS 3792) (check-in: 22e10cc24e user: drh tags: trunk)
11:08
Correctly handle the obscure case of a read-only hot-journal file. (CVS 3791) (check-in: 4d8c6bf44e user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.315 2007/04/02 11:08:59 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.316 2007/04/02 11:22:22 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
  }
  sqlite3PagerStmtCommit(pPager);
  if( pPager->stmtOpen && !pPager->exclusiveMode ){
    sqlite3OsClose(&pPager->stfd);
    pPager->stmtOpen = 0;
  }
  if( pPager->journalOpen ){
    if( pPager->exclusiveMode ){
      rc = sqlite3OsTruncate(pPager->jfd, 0);
      sqlite3OsSeek(pPager->jfd, 0);
      pPager->journalOff = 0;
      pPager->journalStarted = 0;
    }else{
      sqlite3OsClose(&pPager->jfd);
      pPager->journalOpen = 0;
      /* If this is a temporary pager file, then the journal file should
      ** have been configured as delete-on-close. Otherwise, it should still
      ** be in the file system. This pager still holds a RESERVED or greater
      ** lock on the database file, so there is no chance another process
      ** could create or remove a journal file.
      **
      ** These asserts are not valid for asynchronous I/O such as is found
      ** in async.test
      */
      /*assert( sqlite3OsFileExists(pPager->zJournal) || pPager->tempFile );*/
      /*assert( !sqlite3OsFileExists(pPager->zJournal) || !pPager->tempFile );*/
      if( !pPager->tempFile ){
        rc = sqlite3OsDelete(pPager->zJournal);
      }
    }
    sqliteFree( pPager->aInJournal );
    pPager->aInJournal = 0;
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
      pPg->inJournal = 0;







|
|






<
<
<
<
<
<
<
<
<
<
<
|







938
939
940
941
942
943
944
945
946
947
948
949
950
951
952











953
954
955
956
957
958
959
960
  }
  sqlite3PagerStmtCommit(pPager);
  if( pPager->stmtOpen && !pPager->exclusiveMode ){
    sqlite3OsClose(&pPager->stfd);
    pPager->stmtOpen = 0;
  }
  if( pPager->journalOpen ){
    if( pPager->exclusiveMode 
          && (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){;
      sqlite3OsSeek(pPager->jfd, 0);
      pPager->journalOff = 0;
      pPager->journalStarted = 0;
    }else{
      sqlite3OsClose(&pPager->jfd);
      pPager->journalOpen = 0;











      if( rc==SQLITE_OK ){
        rc = sqlite3OsDelete(pPager->zJournal);
      }
    }
    sqliteFree( pPager->aInJournal );
    pPager->aInJournal = 0;
    for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
      pPg->inJournal = 0;
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
    }
  }
  return rc;

failed_to_open_journal:
  sqliteFree(pPager->aInJournal);
  pPager->aInJournal = 0;
#if 0
  if( rc==SQLITE_NOMEM ){
    /* If this was a malloc() failure, then we will not be closing the pager
    ** file. So delete any journal file we may have just created. Otherwise,
    ** the system will get confused, we have a read-lock on the file and a
    ** mysterious journal has appeared in the filesystem.
    */
    /* sqlite3OsDelete(pPager->zJournal); */
  }else{
    /* If we reset the pager here, we will delete pages out from under
    ** various cursors and will ultimately segfault. */
    /* pager_reset(pPager); */
  }
#endif
  return rc;
}

/*
** Acquire a write-lock on the database.  The lock is removed when
** the any of the following happen:
**







<
<
<
<
<
<
<
<
<
<
<
<
<
<







3173
3174
3175
3176
3177
3178
3179














3180
3181
3182
3183
3184
3185
3186
    }
  }
  return rc;

failed_to_open_journal:
  sqliteFree(pPager->aInJournal);
  pPager->aInJournal = 0;














  return rc;
}

/*
** Acquire a write-lock on the database.  The lock is removed when
** the any of the following happen:
**