Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Test handling of IO errors that occur in OsDelete() or OsTruncate() operations. Also use an anonymous file for temporary storage during a VACUUM. (CVS 3729) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b24a6e7b024c8b9a0b6fd15bd8f247e4 |
User & Date: | danielk1977 2007-03-27 16:19:52.000 |
Context
2007-03-27
| ||
17:37 | Remove a c++ comment in pager.c. (CVS 3730) (check-in: e4452e8aed user: danielk1977 tags: trunk) | |
16:19 | Test handling of IO errors that occur in OsDelete() or OsTruncate() operations. Also use an anonymous file for temporary storage during a VACUUM. (CVS 3729) (check-in: b24a6e7b02 user: danielk1977 tags: trunk) | |
15:00 | Updates to the VACUUM documentation. Ticket #2257. (CVS 3728) (check-in: c61c97c978 user: drh tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
779 780 781 782 783 784 785 786 787 788 789 790 791 792 | # define transferOwnership(X) SQLITE_OK #endif /* ** Delete the named file */ int sqlite3UnixDelete(const char *zFilename){ unlink(zFilename); return SQLITE_OK; } /* ** Return TRUE if the named file exists. */ | > | 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 | # define transferOwnership(X) SQLITE_OK #endif /* ** Delete the named file */ int sqlite3UnixDelete(const char *zFilename){ SimulateIOError(return SQLITE_IOERR_DELETE); unlink(zFilename); return SQLITE_OK; } /* ** Return TRUE if the named file exists. */ |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
592 593 594 595 596 597 598 599 600 601 602 603 604 605 | int sqlite3WinDelete(const char *zFilename){ int cnt = 0; int rc; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } if( isNT() ){ do{ rc = DeleteFileW(zConverted); }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); }else{ #if OS_WINCE | > | 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 | int sqlite3WinDelete(const char *zFilename){ int cnt = 0; int rc; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } SimulateIOError(return SQLITE_IOERR_DELETE); if( isNT() ){ do{ rc = DeleteFileW(zConverted); }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); }else{ #if OS_WINCE |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** 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. ** | | | 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.302 2007/03/27 16:19:52 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
475 476 477 478 479 480 481 | ** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_PROTOCOL, ** the error becomes persistent. All subsequent API calls on this Pager ** will immediately return the same error code. */ static int pager_error(Pager *pPager, int rc){ int rc2 = rc & 0xff; assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK ); | | | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | ** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_PROTOCOL, ** the error becomes persistent. All subsequent API calls on this Pager ** will immediately return the same error code. */ static int pager_error(Pager *pPager, int rc){ int rc2 = rc & 0xff; assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK ); if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR || rc2==SQLITE_CORRUPT || rc2==SQLITE_PROTOCOL ){ pPager->errCode = rc; } |
︙ | ︙ | |||
918 919 920 921 922 923 924 925 926 927 928 929 930 | ** TODO: Consider keeping the journal file open for temporary databases. ** This might give a performance improvement on windows where opening ** a file is an expensive operation. */ static int pager_unwritelock(Pager *pPager){ PgHdr *pPg; int rc = SQLITE_OK; assert( !MEMDB ); if( pPager->state<PAGER_RESERVED ){ return SQLITE_OK; } sqlite3PagerStmtCommit(pPager); if( pPager->stmtOpen && !pPager->exclusiveMode ){ | > < | | < < < | | > | > | | 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 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 972 973 974 975 976 977 978 979 980 981 982 983 984 | ** TODO: Consider keeping the journal file open for temporary databases. ** This might give a performance improvement on windows where opening ** a file is an expensive operation. */ static int pager_unwritelock(Pager *pPager){ PgHdr *pPg; int rc = SQLITE_OK; int rc2 = SQLITE_OK; assert( !MEMDB ); if( pPager->state<PAGER_RESERVED ){ return SQLITE_OK; } 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; rc = sqlite3OsDelete(pPager->zJournal); } sqliteFree( pPager->aInJournal ); pPager->aInJournal = 0; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ pPg->inJournal = 0; pPg->dirty = 0; pPg->needSync = 0; pPg->alwaysRollback = 0; #ifdef SQLITE_CHECK_PAGES pPg->pageHash = pager_pagehash(pPg); #endif } pPager->pDirty = 0; pPager->dirtyCache = 0; pPager->nRec = 0; }else{ assert( pPager->aInJournal==0 ); assert( pPager->dirtyCache==0 || pPager->useJournal==0 ); } if( !pPager->exclusiveMode ){ rc2 = sqlite3OsUnlock(pPager->fd, SHARED_LOCK); pPager->state = PAGER_SHARED; }else if( pPager->state==PAGER_SYNCED ){ pPager->state = PAGER_EXCLUSIVE; } pPager->origDbSize = 0; pPager->setMaster = 0; pPager->needSync = 0; pPager->pFirstSynced = pPager->pFirst; pPager->dbSize = -1; return (rc==SQLITE_OK?rc2:rc); } /* ** Compute and return a checksum for the page of data. ** ** This is not a real checksum. It is really just the sum of the ** random initial value and the page number. We experimented with |
︙ | ︙ | |||
1189 1190 1191 1192 1193 1194 1195 | goto delmaster_out; } } zJournal += (strlen(zJournal)+1); } } | | | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 | goto delmaster_out; } } zJournal += (strlen(zJournal)+1); } } rc = sqlite3OsDelete(zMaster); delmaster_out: if( zMasterJournal ){ sqliteFree(zMasterJournal); } if( master_open ){ sqlite3OsClose(&master); |
︙ | ︙ | |||
1413 1414 1415 1416 1417 1418 1419 | assert( 0 ); end_playback: if( rc==SQLITE_OK ){ rc = pager_unwritelock(pPager); } if( zMaster ){ | | | 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 | assert( 0 ); end_playback: if( rc==SQLITE_OK ){ rc = pager_unwritelock(pPager); } if( zMaster ){ /* If there was a master journal and this routine will return success, ** see if it is possible to delete the master journal. */ if( rc==SQLITE_OK ){ rc = pager_delmaster(zMaster); } sqliteFree(zMaster); } |
︙ | ︙ | |||
2701 2702 2703 2704 2705 2706 2707 2708 | /* Open the journal for reading only. Return SQLITE_BUSY if ** we are unable to open the journal file. ** ** The journal file does not need to be locked itself. The ** journal file is never open unless the main database file holds ** a write lock, so there is never any chance of two or more ** processes opening the journal at the same time. */ | > > > > > > > > > | > > > > | 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 | /* Open the journal for reading only. Return SQLITE_BUSY if ** we are unable to open the journal file. ** ** The journal file does not need to be locked itself. The ** journal file is never open unless the main database file holds ** a write lock, so there is never any chance of two or more ** processes opening the journal at the same time. ** ** Open the journal for read/write access. This is because in ** exclusive-access mode the file descriptor will be kept open and ** possibly used for a transaction later on. On some systems, the ** OsTruncate() call used in exclusive-access mode also requires ** a read/write file handle. */ rc = SQLITE_BUSY; if( sqlite3OsFileExists(pPager->zJournal) ){ int ro; rc = sqlite3OsOpenReadWrite(pPager->zJournal, &pPager->jfd, &ro); if( ro ){ rc = SQLITE_BUSY; } } if( rc!=SQLITE_OK ){ pager_unlock(pPager); return SQLITE_BUSY; } pPager->journalOpen = 1; pPager->journalStarted = 0; pPager->journalOff = 0; |
︙ | ︙ | |||
2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 | return rc; } assert( pPager->state!=PAGER_UNLOCK ); pPg = pager_lookup(pPager, pgno); if( pPg==0 ){ /* The requested page is not in the page cache. */ int h; TEST_INCR(pPager->nMiss); if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB || (pPager->pFirstSynced==0 && pPager->doNotSync) ){ /* Create a new page */ if( pPager->nPage>=pPager->nHash ){ | > | 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 | return rc; } assert( pPager->state!=PAGER_UNLOCK ); pPg = pager_lookup(pPager, pgno); if( pPg==0 ){ /* The requested page is not in the page cache. */ int nMax; int h; TEST_INCR(pPager->nMiss); if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB || (pPager->pFirstSynced==0 && pPager->doNotSync) ){ /* Create a new page */ if( pPager->nPage>=pPager->nHash ){ |
︙ | ︙ | |||
2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 | pPg->nRef = 1; REFINFO(pPg); pPager->nRef++; if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } if( pPager->errCode ){ sqlite3PagerUnref(pPg); rc = pPager->errCode; return rc; } /* Populate the page with data, either by reading from the database ** file, or by setting the entire page to zero. */ | > < | < | 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 | pPg->nRef = 1; REFINFO(pPg); pPager->nRef++; if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } nMax = sqlite3PagerPagecount(pPager); if( pPager->errCode ){ sqlite3PagerUnref(pPg); rc = pPager->errCode; return rc; } /* Populate the page with data, either by reading from the database ** file, or by setting the entire page to zero. */ if( nMax<(int)pgno || MEMDB || (clrFlag && !pPager->alwaysRollback) ){ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); }else{ assert( MEMDB==0 ); rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize); if( rc==SQLITE_OK ){ rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize); |
︙ | ︙ | |||
3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 | } /* When all pages reach the freelist, drop the read lock from ** the database file. */ pPager->nRef--; assert( pPager->nRef>=0 ); if( pPager->nRef==0 && !pPager->exclusiveMode ){ pagerUnlockAndRollback(pPager); } } return SQLITE_OK; } | > | 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 | } /* When all pages reach the freelist, drop the read lock from ** the database file. */ pPager->nRef--; assert( pPager->nRef>=0 ); // assert( pPager->nRef>0 || !pPager->journalOpen || pPager->journalOff==0 ); if( pPager->nRef==0 && !pPager->exclusiveMode ){ pagerUnlockAndRollback(pPager); } } return SQLITE_OK; } |
︙ | ︙ | |||
3082 3083 3084 3085 3086 3087 3088 | pPager->aInJournal = 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. */ | | | 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 | pPager->aInJournal = 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{ pager_reset(pPager); } return rc; } /* |
︙ | ︙ | |||
3607 3608 3609 3610 3611 3612 3613 | return SQLITE_OK; } if( pPager->dirtyCache==0 ){ /* Exit early (without doing the time-consuming sqlite3OsSync() calls) ** if there have been no changes to the database file. */ assert( pPager->needSync==0 ); rc = pager_unwritelock(pPager); | < | | | | | | > | | 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 | return SQLITE_OK; } if( pPager->dirtyCache==0 ){ /* Exit early (without doing the time-consuming sqlite3OsSync() calls) ** if there have been no changes to the database file. */ assert( pPager->needSync==0 ); rc = pager_unwritelock(pPager); }else{ assert( pPager->journalOpen ); rc = sqlite3PagerSync(pPager, 0, 0); if( rc==SQLITE_OK ){ rc = pager_unwritelock(pPager); } } return pager_error(pPager, rc); } /* ** Rollback all changes. The database falls back to PAGER_SHARED mode. ** All in-memory cache pages revert to their original data contents. ** The journal is deleted. ** |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** ** @(#) $Id: pager.h,v 1.56 2007/03/27 16:19:52 danielk1977 Exp $ */ #ifndef _PAGER_H_ #define _PAGER_H_ /* ** The default size of a database page. |
︙ | ︙ | |||
131 132 133 134 135 136 137 138 139 | int sqlite3PagerLockstate(Pager*); #endif #ifdef SQLITE_TEST void sqlite3PagerRefdump(Pager*); int pager3_refinfo_enable; #endif #endif /* _PAGER_H_ */ | > > > > > > > > | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | int sqlite3PagerLockstate(Pager*); #endif #ifdef SQLITE_TEST void sqlite3PagerRefdump(Pager*); int pager3_refinfo_enable; #endif #ifdef SQLITE_TEST void disable_simulated_io_errors(void); void enable_simulated_io_errors(void); #else # define disable_simulated_io_errors() # define enable_simulated_io_errors() #endif #endif /* _PAGER_H_ */ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.199 2007/03/27 16:19:52 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
226 227 228 229 230 231 232 233 234 235 236 237 238 239 | #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) #define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) #define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) #define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) #define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) #define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) #define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) /* ** Enable or disable the extended result codes. */ int sqlite3_extended_result_codes(sqlite3*, int onoff); /* | > | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) #define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) #define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) #define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) #define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) #define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) #define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) #define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) /* ** Enable or disable the extended result codes. */ int sqlite3_extended_result_codes(sqlite3*, int onoff); /* |
︙ | ︙ |
Changes to src/vacuum.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** ** $Id: vacuum.c,v 1.69 2007/03/27 16:19:52 danielk1977 Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #include "os.h" #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) /* |
︙ | ︙ | |||
79 80 81 82 83 84 85 | int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ int rc = SQLITE_OK; /* Return code from service routines */ Btree *pMain; /* The database being vacuumed */ Btree *pTemp; /* The temporary database we vacuum into */ char *zSql = 0; /* SQL statements */ int saved_flags; /* Saved value of the db->flags */ Db *pDb = 0; /* Database to detach at end of vacuum */ | < < | < < < < < < | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ int rc = SQLITE_OK; /* Return code from service routines */ Btree *pMain; /* The database being vacuumed */ Btree *pTemp; /* The temporary database we vacuum into */ char *zSql = 0; /* SQL statements */ int saved_flags; /* Saved value of the db->flags */ Db *pDb = 0; /* Database to detach at end of vacuum */ /* Save the current value of the write-schema flag before setting it. */ saved_flags = db->flags; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", (char*)0); rc = SQLITE_ERROR; goto end_of_vacuum; } pMain = db->aDb[0].pBt; /* Attach the temporary database as 'vacuum_db'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** ** An optimisation would be to use a non-journaled pager. */ zSql = "ATTACH '' AS vacuum_db;"; rc = execSql(db, zSql); if( rc!=SQLITE_OK ) goto end_of_vacuum; pDb = &db->aDb[db->nDb-1]; assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 ); pTemp = db->aDb[db->nDb-1].pBt; sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), sqlite3BtreeGetReserve(pMain)); if( sqlite3MallocFailed() ){ |
︙ | ︙ | |||
259 260 261 262 263 264 265 | sqlite3MallocDisallow(); sqlite3BtreeClose(pDb->pBt); sqlite3MallocAllow(); pDb->pBt = 0; pDb->pSchema = 0; } | < < < < | 251 252 253 254 255 256 257 258 259 260 261 262 | sqlite3MallocDisallow(); sqlite3BtreeClose(pDb->pBt); sqlite3MallocAllow(); pDb->pBt = 0; pDb->pSchema = 0; } sqlite3ResetInternalSchema(db, 0); return rc; } #endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 | for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ rc = sqlite3BtreeSync(pBt, 0); } } | | | > > > | | | | | | > | 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 | for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ rc = sqlite3BtreeSync(pBt, 0); } } /* Do the commit only if all databases successfully synced. ** If one of the BtreeCommit() calls fails, this indicates an IO error ** while deleting or truncating a journal file. It is unlikely, but ** could happen. In this case abandon processing and return the error. */ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ rc = sqlite3BtreeCommit(pBt); } } if( rc==SQLITE_OK ){ sqlite3VtabCommit(db); } } /* The complex case - There is a multi-file write-transaction active. ** This requires a master journal file to ensure the transaction is ** committed atomicly. |
︙ | ︙ | |||
1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 | /* All files and directories have already been synced, so the following ** calls to sqlite3BtreeCommit() are only closing files and deleting ** journals. If something goes wrong while this is happening we don't ** really care. The integrity of the transaction is already guaranteed, ** but some stray 'cold' journals may be lying around. Returning an ** error code won't help matters. */ for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ sqlite3BtreeCommit(pBt); } } sqlite3VtabCommit(db); } #endif return rc; } | > > > | 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 | /* All files and directories have already been synced, so the following ** calls to sqlite3BtreeCommit() are only closing files and deleting ** journals. If something goes wrong while this is happening we don't ** really care. The integrity of the transaction is already guaranteed, ** but some stray 'cold' journals may be lying around. Returning an ** error code won't help matters. */ disable_simulated_io_errors(); for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ sqlite3BtreeCommit(pBt); } } enable_simulated_io_errors(); sqlite3VtabCommit(db); } #endif return rc; } |
︙ | ︙ |
Changes to test/exclusive3.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file runs the tests in the file ioerr.test with auto-vacuum enabled # databases. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # # This file runs the tests in the file ioerr.test with auto-vacuum enabled # databases. # # $Id: exclusive3.test,v 1.2 2007/03/27 16:19:52 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!pager_pragmas} { finish_test return |
︙ | ︙ | |||
43 44 45 46 47 48 49 | } #source $testdir/rollback.test #source $testdir/select1.test #source $testdir/select2.test source $testdir/malloc.test | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | } #source $testdir/rollback.test #source $testdir/select1.test #source $testdir/select2.test source $testdir/malloc.test source $testdir/ioerr.test rename sqlite3 "" rename real_sqlite3 sqlite3 rename finish_test "" rename really_finish_test2 finish_test rename do_test "" rename really_do_test do_test finish_test |