vacuum.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. ** 2003 April 6
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. ** This file contains code used to implement the VACUUM command.
  13. **
  14. ** Most of the code in this file may be omitted by defining the
  15. ** SQLITE_OMIT_VACUUM macro.
  16. **
  17. ** $Id: vacuum.c,v 1.75 2007/12/05 01:38:24 drh Exp $
  18. */
  19. #include "sqliteInt.h"
  20. #include "vdbeInt.h"
  21. #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
  22. /*
  23. ** Execute zSql on database db. Return an error code.
  24. */
  25. static int execSql(sqlite3 *db, const char *zSql){
  26. sqlite3_stmt *pStmt;
  27. if( !zSql ){
  28. return SQLITE_NOMEM;
  29. }
  30. if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
  31. return sqlite3_errcode(db);
  32. }
  33. while( SQLITE_ROW==sqlite3_step(pStmt) ){}
  34. return sqlite3_finalize(pStmt);
  35. }
  36. /*
  37. ** Execute zSql on database db. The statement returns exactly
  38. ** one column. Execute this as SQL on the same database.
  39. */
  40. static int execExecSql(sqlite3 *db, const char *zSql){
  41. sqlite3_stmt *pStmt;
  42. int rc;
  43. rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  44. if( rc!=SQLITE_OK ) return rc;
  45. while( SQLITE_ROW==sqlite3_step(pStmt) ){
  46. rc = execSql(db, (char*)sqlite3_column_text(pStmt, 0));
  47. if( rc!=SQLITE_OK ){
  48. sqlite3_finalize(pStmt);
  49. return rc;
  50. }
  51. }
  52. return sqlite3_finalize(pStmt);
  53. }
  54. /*
  55. ** The non-standard VACUUM command is used to clean up the database,
  56. ** collapse free space, etc. It is modelled after the VACUUM command
  57. ** in PostgreSQL.
  58. **
  59. ** In version 1.0.x of SQLite, the VACUUM command would call
  60. ** gdbm_reorganize() on all the database tables. But beginning
  61. ** with 2.0.0, SQLite no longer uses GDBM so this command has
  62. ** become a no-op.
  63. */
  64. void sqlite3Vacuum(Parse *pParse){
  65. Vdbe *v = sqlite3GetVdbe(pParse);
  66. if( v ){
  67. sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);
  68. }
  69. return;
  70. }
  71. /*
  72. ** This routine implements the OP_Vacuum opcode of the VDBE.
  73. */
  74. int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
  75. int rc = SQLITE_OK; /* Return code from service routines */
  76. Btree *pMain; /* The database being vacuumed */
  77. Btree *pTemp; /* The temporary database we vacuum into */
  78. char *zSql = 0; /* SQL statements */
  79. int saved_flags; /* Saved value of the db->flags */
  80. Db *pDb = 0; /* Database to detach at end of vacuum */
  81. /* Save the current value of the write-schema flag before setting it. */
  82. saved_flags = db->flags;
  83. db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
  84. if( !db->autoCommit ){
  85. sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction",
  86. (char*)0);
  87. rc = SQLITE_ERROR;
  88. goto end_of_vacuum;
  89. }
  90. pMain = db->aDb[0].pBt;
  91. /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
  92. ** can be set to 'off' for this file, as it is not recovered if a crash
  93. ** occurs anyway. The integrity of the database is maintained by a
  94. ** (possibly synchronous) transaction opened on the main database before
  95. ** sqlite3BtreeCopyFile() is called.
  96. **
  97. ** An optimisation would be to use a non-journaled pager.
  98. */
  99. zSql = "ATTACH '' AS vacuum_db;";
  100. rc = execSql(db, zSql);
  101. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  102. pDb = &db->aDb[db->nDb-1];
  103. assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
  104. pTemp = db->aDb[db->nDb-1].pBt;
  105. sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain),
  106. sqlite3BtreeGetReserve(pMain));
  107. if( db->mallocFailed ){
  108. rc = SQLITE_NOMEM;
  109. goto end_of_vacuum;
  110. }
  111. assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
  112. rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
  113. if( rc!=SQLITE_OK ){
  114. goto end_of_vacuum;
  115. }
  116. #ifndef SQLITE_OMIT_AUTOVACUUM
  117. sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
  118. sqlite3BtreeGetAutoVacuum(pMain));
  119. #endif
  120. /* Begin a transaction */
  121. rc = execSql(db, "BEGIN EXCLUSIVE;");
  122. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  123. /* Query the schema of the main database. Create a mirror schema
  124. ** in the temporary database.
  125. */
  126. rc = execExecSql(db,
  127. "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
  128. " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
  129. " AND rootpage>0"
  130. );
  131. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  132. rc = execExecSql(db,
  133. "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
  134. " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
  135. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  136. rc = execExecSql(db,
  137. "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
  138. " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
  139. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  140. /* Loop through the tables in the main database. For each, do
  141. ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy
  142. ** the contents to the temporary database.
  143. */
  144. rc = execExecSql(db,
  145. "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
  146. "|| ' SELECT * FROM ' || quote(name) || ';'"
  147. "FROM sqlite_master "
  148. "WHERE type = 'table' AND name!='sqlite_sequence' "
  149. " AND rootpage>0"
  150. );
  151. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  152. /* Copy over the sequence table
  153. */
  154. rc = execExecSql(db,
  155. "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
  156. "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
  157. );
  158. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  159. rc = execExecSql(db,
  160. "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
  161. "|| ' SELECT * FROM ' || quote(name) || ';' "
  162. "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
  163. );
  164. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  165. /* Copy the triggers, views, and virtual tables from the main database
  166. ** over to the temporary database. None of these objects has any
  167. ** associated storage, so all we have to do is copy their entries
  168. ** from the SQLITE_MASTER table.
  169. */
  170. rc = execSql(db,
  171. "INSERT INTO vacuum_db.sqlite_master "
  172. " SELECT type, name, tbl_name, rootpage, sql"
  173. " FROM sqlite_master"
  174. " WHERE type='view' OR type='trigger'"
  175. " OR (type='table' AND rootpage=0)"
  176. );
  177. if( rc ) goto end_of_vacuum;
  178. /* At this point, unless the main db was completely empty, there is now a
  179. ** transaction open on the vacuum database, but not on the main database.
  180. ** Open a btree level transaction on the main database. This allows a
  181. ** call to sqlite3BtreeCopyFile(). The main database btree level
  182. ** transaction is then committed, so the SQL level never knows it was
  183. ** opened for writing. This way, the SQL transaction used to create the
  184. ** temporary database never needs to be committed.
  185. */
  186. if( rc==SQLITE_OK ){
  187. u32 meta;
  188. int i;
  189. /* This array determines which meta meta values are preserved in the
  190. ** vacuum. Even entries are the meta value number and odd entries
  191. ** are an increment to apply to the meta value after the vacuum.
  192. ** The increment is used to increase the schema cookie so that other
  193. ** connections to the same database will know to reread the schema.
  194. */
  195. static const unsigned char aCopy[] = {
  196. 1, 1, /* Add one to the old schema cookie */
  197. 3, 0, /* Preserve the default page cache size */
  198. 5, 0, /* Preserve the default text encoding */
  199. 6, 0, /* Preserve the user version */
  200. };
  201. assert( 1==sqlite3BtreeIsInTrans(pTemp) );
  202. assert( 1==sqlite3BtreeIsInTrans(pMain) );
  203. /* Copy Btree meta values */
  204. for(i=0; i<sizeof(aCopy)/sizeof(aCopy[0]); i+=2){
  205. rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
  206. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  207. rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
  208. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  209. }
  210. rc = sqlite3BtreeCopyFile(pMain, pTemp);
  211. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  212. rc = sqlite3BtreeCommit(pTemp);
  213. if( rc!=SQLITE_OK ) goto end_of_vacuum;
  214. rc = sqlite3BtreeCommit(pMain);
  215. }
  216. end_of_vacuum:
  217. /* Restore the original value of db->flags */
  218. db->flags = saved_flags;
  219. /* Currently there is an SQL level transaction open on the vacuum
  220. ** database. No locks are held on any other files (since the main file
  221. ** was committed at the btree level). So it safe to end the transaction
  222. ** by manually setting the autoCommit flag to true and detaching the
  223. ** vacuum database. The vacuum_db journal file is deleted when the pager
  224. ** is closed by the DETACH.
  225. */
  226. db->autoCommit = 1;
  227. if( pDb ){
  228. sqlite3BtreeClose(pDb->pBt);
  229. pDb->pBt = 0;
  230. pDb->pSchema = 0;
  231. }
  232. sqlite3ResetInternalSchema(db, 0);
  233. return rc;
  234. }
  235. #endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */