Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Ensure master journal file is deleted when a transaction is committed. (CVS 1586) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
cb3cbe00be9a42e974688016a056053c |
User & Date: | danielk1977 2004-06-14 09:35:17.000 |
Context
2004-06-14
| ||
09:41 | Bugfix for previous checkin. (CVS 1587) (check-in: 2737505f28 user: danielk1977 tags: trunk) | |
09:35 | Ensure master journal file is deleted when a transaction is committed. (CVS 1586) (check-in: cb3cbe00be user: danielk1977 tags: trunk) | |
08:26 | Check the value of the schema cookie before reading the sqlite_master table. (CVS 1585) (check-in: 80c299f883 user: danielk1977 tags: trunk) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.220 2004/06/14 09:35:17 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
221 222 223 224 225 226 227 | ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. ** meta[3] Synchronous setting. 1:off, 2:normal, 3:full ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE ** meta[5] Pragma temp_store value. See comments on BtreeFactory | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. ** meta[3] Synchronous setting. 1:off, 2:normal, 3:full ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE ** meta[5] Pragma temp_store value. See comments on BtreeFactory ** meta[6] ** meta[7] ** meta[8] ** meta[9] ** ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to ** the possible values of meta[4]. */ |
︙ | ︙ |
Changes to src/os.h.
︙ | ︙ | |||
144 145 146 147 148 149 150 151 152 153 154 155 156 157 | int sqlite3OsDelete(const char*); int sqlite3OsFileExists(const char*); int sqliteOsFileRename(const char*, const char*); int sqlite3OsOpenReadWrite(const char*, OsFile*, int*); int sqlite3OsOpenExclusive(const char*, OsFile*, int); int sqlite3OsOpenReadOnly(const char*, OsFile*); int sqlite3OsOpenDirectory(const char*, OsFile*); int sqlite3OsTempFileName(char*); int sqlite3OsClose(OsFile*); int sqlite3OsRead(OsFile*, void*, int amt); int sqlite3OsWrite(OsFile*, const void*, int amt); int sqlite3OsSeek(OsFile*, off_t offset); int sqlite3OsSync(OsFile*); int sqlite3OsTruncate(OsFile*, off_t size); | > | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | int sqlite3OsDelete(const char*); int sqlite3OsFileExists(const char*); int sqliteOsFileRename(const char*, const char*); int sqlite3OsOpenReadWrite(const char*, OsFile*, int*); int sqlite3OsOpenExclusive(const char*, OsFile*, int); int sqlite3OsOpenReadOnly(const char*, OsFile*); int sqlite3OsOpenDirectory(const char*, OsFile*); int sqlite3OsSyncDirectory(const char*); int sqlite3OsTempFileName(char*); int sqlite3OsClose(OsFile*); int sqlite3OsRead(OsFile*, void*, int amt); int sqlite3OsWrite(OsFile*, const void*, int amt); int sqlite3OsSeek(OsFile*, off_t offset); int sqlite3OsSync(OsFile*); int sqlite3OsTruncate(OsFile*, off_t size); |
︙ | ︙ |
Changes to src/os_mac.c.
︙ | ︙ | |||
387 388 389 390 391 392 393 394 395 396 397 398 399 400 | if( PBFlushFileSync(¶ms) != noErr ){ # endif return SQLITE_IOERR; }else{ return SQLITE_OK; } } /* ** Truncate an open file to a specified size */ int sqlite3OsTruncate(OsFile *id, off_t nByte){ SimulateIOError(SQLITE_IOERR); # ifdef _LARGE_FILE | > > > > > > > > | 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | if( PBFlushFileSync(¶ms) != noErr ){ # endif return SQLITE_IOERR; }else{ return SQLITE_OK; } } /* ** Sync the directory zDirname. This is a no-op on operating systems other ** than UNIX. */ int sqlite3OsSyncDirectory(const char *zDirname){ return SQLITE_OK; } /* ** Truncate an open file to a specified size */ int sqlite3OsTruncate(OsFile *id, off_t nByte){ SimulateIOError(SQLITE_IOERR); # ifdef _LARGE_FILE |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
615 616 617 618 619 620 621 622 623 624 625 626 627 628 | fsync(id->dirfd); close(id->dirfd); /* Only need to sync once, so close the directory */ id->dirfd = -1; /* when we are done. */ } return SQLITE_OK; } } /* ** Truncate an open file to a specified size */ int sqlite3OsTruncate(OsFile *id, off_t nByte){ SimulateIOError(SQLITE_IOERR); return ftruncate(id->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR; | > > > > > > > > > > > > > > > > | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 | fsync(id->dirfd); close(id->dirfd); /* Only need to sync once, so close the directory */ id->dirfd = -1; /* when we are done. */ } return SQLITE_OK; } } /* ** Sync the directory zDirname. This is a no-op on operating systems other ** than UNIX. */ int sqlite3OsSyncDirectory(const char *zDirname){ int fd; int r; fd = open(zDirname, O_RDONLY|O_BINARY, 0644); if( fd<0 ){ return SQLITE_CANTOPEN; } r = fsync(fd); close(fd); return ((r==0)?SQLITE_OK:SQLITE_IOERR); } /* ** Truncate an open file to a specified size */ int sqlite3OsTruncate(OsFile *id, off_t nByte){ SimulateIOError(SQLITE_IOERR); return ftruncate(id->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR; |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
285 286 287 288 289 290 291 292 293 294 295 296 297 298 | TRACE3("SYNC %d lock=%d\n", id->h, id->locktype); if( FlushFileBuffers(id->h) ){ return SQLITE_OK; }else{ return SQLITE_IOERR; } } /* ** Truncate an open file to a specified size */ int sqlite3OsTruncate(OsFile *id, off_t nByte){ LONG upperBits = nByte>>32; TRACE3("TRUNCATE %d %lld\n", id->h, nByte); | > > > > > > > > | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | TRACE3("SYNC %d lock=%d\n", id->h, id->locktype); if( FlushFileBuffers(id->h) ){ return SQLITE_OK; }else{ return SQLITE_IOERR; } } /* ** Sync the directory zDirname. This is a no-op on operating systems other ** than UNIX. */ int sqlite3OsSyncDirectory(const char *zDirname){ return SQLITE_OK; } /* ** Truncate an open file to a specified size */ int sqlite3OsTruncate(OsFile *id, off_t nByte){ LONG upperBits = nByte>>32; TRACE3("TRUNCATE %d %lld\n", id->h, nByte); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqliteFree(zMaster); return rc; } rc = sqlite3OsSync(&master); if( rc!=SQLITE_OK ){ sqliteFree(zMaster); return rc; } | > < > > | > > > > > > > > > > > > > > > > | | 1083 1084 1085 1086 1087 1088 1089 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 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 | sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqliteFree(zMaster); return rc; } rc = sqlite3OsSync(&master); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqliteFree(zMaster); return rc; } /* Sync all the db files involved in the transaction. The same call ** sets the master journal pointer in each individual journal. If ** an error occurs here, do not delete the master journal file. ** ** If the error occurs during the first call to sqlite3BtreeSync(), ** then there is a chance that the master journal file will be ** orphaned. But we cannot delete it, in case the master journal ** file name was written into the journal file before the failure ** occured. */ for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt && sqlite3BtreeIsInTrans(pBt) ){ rc = sqlite3BtreeSync(pBt, zMaster); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqliteFree(zMaster); return rc; } } } sqlite3OsClose(&master); sqliteFree(zMaster); zMaster = 0; /* Delete the master journal file. This commits the transaction. After ** doing this the directory is synced again before any individual ** transaction files are deleted. */ rc = sqlite3OsDelete(zMaster); assert( rc==SQLITE_OK ); rc = sqlite3OsSyncDirectory(zMainFile); if( rc!=SQLITE_OK ){ /* This is not good. The master journal file has been deleted, but ** the directory sync failed. There is no completely safe course of ** action from here. The individual journals contain the name of the ** master journal file, but there is no way of knowing if that ** master journal exists now or if it will exist after the operating ** system crash that may follow the fsync() failure. */ assert(0); sqliteFree(zMaster); return rc; } /* 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); |
︙ | ︙ |
Changes to test/attach2.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # | | | 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 implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # # $Id: attach2.test,v 1.17 2004/06/14 09:35:17 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Ticket #354 |
︙ | ︙ | |||
299 300 301 302 303 304 305 306 307 | do_test attach2-4.15 { execsql {SELECT * FROM t1} db2 } {1 2 1 2} db close db2 close file delete -force test2.db finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | do_test attach2-4.15 { execsql {SELECT * FROM t1} db2 } {1 2 1 2} db close db2 close file delete -force test2.db if 0 { # These tests - attach2-5.* - check that the master journal file is deleted # correctly when a multi-file transaction is committed or rolled back. # # Update: It's not actually created if a rollback occurs, so that test # doesn't really prove too much. foreach f [glob test.db*] {file delete -force $f} do_test attach2-5.1 { sqlite db test.db execsql { ATTACH 'test.db2' AS aux; } } {} do_test attach2-5.2 { execsql { BEGIN; CREATE TABLE tbl(a, b, c); CREATE TABLE aux.tbl(a, b, c); COMMIT; } } {} do_test attach2-5.3 { glob test.db* } {test.db test.db2} do_test attach2-5.4 { execsql { BEGIN; DROP TABLE aux.tbl; DROP TABLE tbl; ROLLBACK; } } {} do_test attach2-5.5 { glob test.db* } {test.db test.db2} db close } finish_test |