Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Allow VACUUM to detach the auxillary database after malloc() fails. (CVS 2804) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6824a78bc7b8582fc5c3a6ab05dd3ed9 |
User & Date: | danielk1977 2005-12-06 17:48:32.000 |
Context
2005-12-07
| ||
06:27 | Add some tests for malloc() failure within the column_name() and column_decl() APIs. (CVS 2805) (check-in: 78f10ca0a6 user: danielk1977 tags: trunk) | |
2005-12-06
| ||
17:48 | Allow VACUUM to detach the auxillary database after malloc() fails. (CVS 2804) (check-in: 6824a78bc7 user: danielk1977 tags: trunk) | |
17:19 | Modify ATTACH and DETACH to execute at runtime instead of compile time. (CVS 2803) (check-in: 5e04ec694a user: danielk1977 tags: trunk) | |
Changes
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 25 26 27 | ** ************************************************************************* ** 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.51 2005/12/06 17:48:32 danielk1977 Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #include "os.h" #ifndef SQLITE_OMIT_VACUUM /* ** Generate a random name of 20 character in length. */ static void randomName(unsigned char *zBuf){ |
︙ | ︙ | |||
98 99 100 101 102 103 104 105 106 107 108 109 110 111 | int nFilename; /* number of characters in zFilename[] */ char *zTemp = 0; /* a temporary file in same directory as zFilename */ Btree *pMain; /* The database being vacuumed */ Btree *pTemp; char *zSql = 0; int rc2; int saved_flags; /* Saved value of the db->flags */ /* 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", | > | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | int nFilename; /* number of characters in zFilename[] */ char *zTemp = 0; /* a temporary file in same directory as zFilename */ Btree *pMain; /* The database being vacuumed */ Btree *pTemp; char *zSql = 0; int rc2; int saved_flags; /* Saved value of the db->flags */ sqlite3_stmt *pDetach = 0; /* 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", |
︙ | ︙ | |||
143 144 145 146 147 148 149 150 151 152 153 154 155 156 | ** enough that this loop will always terminate (and terminate quickly) ** that we don't even bother to set a maximum loop count. */ do { zTemp[nFilename] = '-'; randomName((unsigned char*)&zTemp[nFilename+1]); } while( sqlite3Os.xFileExists(zTemp) ); /* 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. ** | > > > > > > > > > | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | ** enough that this loop will always terminate (and terminate quickly) ** that we don't even bother to set a maximum loop count. */ do { zTemp[nFilename] = '-'; randomName((unsigned char*)&zTemp[nFilename+1]); } while( sqlite3Os.xFileExists(zTemp) ); /* Before we even attach it, compile a DETACH statement for vacuum_db. This ** way, if malloc() fails we can detach the database without needing to ** dynamically allocate memory. */ rc = sqlite3_prepare(db, "DETACH vacuum_db", -1, &pDetach, 0); if( rc!=SQLITE_OK ){ goto end_of_vacuum; } /* 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. ** |
︙ | ︙ | |||
283 284 285 286 287 288 289 | if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeCommit(pTemp); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeCommit(pMain); } end_of_vacuum: | < < < < < < < < | | < < < < | | > > > > > > > > > | 294 295 296 297 298 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 | if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeCommit(pTemp); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeCommit(pMain); } end_of_vacuum: /* Restore the original value of db->flags */ db->flags = saved_flags; /* Currently there is an SQL level transaction open on the vacuum ** database. No locks are held on any other files (since the main file ** was committed at the btree level). So it safe to end the transaction ** by manually setting the autoCommit flag to true and detaching the ** vacuum database. The vacuum_db journal file is deleted when the pager ** is closed by the DETACH. */ db->autoCommit = 1; if( pDetach ){ ((Vdbe *)pDetach)->expired = 0; sqlite3_step(pDetach); rc2 = sqlite3_finalize(pDetach); if( rc==SQLITE_OK ){ rc = rc2; } } /* If one of the execSql() calls above returned SQLITE_NOMEM, then the ** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()). ** Fix this so the flag and return code match. */ if( rc==SQLITE_NOMEM ){ sqlite3Tsd()->mallocFailed = 1; } if( zTemp ){ sqlite3Os.xDelete(zTemp); sqliteFree(zTemp); } sqliteFree( zSql ); sqlite3ResetInternalSchema(db, 0); #endif return rc; } |
Changes to test/malloc3.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2005 November 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2005 November 30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: malloc3.test,v 1.2 2005/12/06 17:48:32 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. if {[info command sqlite_malloc_stat]==""} { puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." |
︙ | ︙ | |||
452 453 454 455 456 457 458 | } } {a b c a b c 1 2 3 1 2 3} } # Test a simple multi-file transaction # file delete -force test2.db | | | 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | } } {a b c a b c 1 2 3 1 2 3} } # Test a simple multi-file transaction # file delete -force test2.db SQL {ATTACH 'test2.db' AS aux;} SQL {BEGIN} SQL {CREATE TABLE aux.tbl2(x, y, z)} SQL {INSERT INTO tbl2 VALUES(1, 2, 3)} SQL {INSERT INTO def VALUES(4, 5, 6)} TEST 30 { do_test $testid { execsql { |
︙ | ︙ |