]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Create the new ext/repair folder and move checkfreelist.c there. Remove
authordrh <drh@noemail.net>
Thu, 12 Oct 2017 19:50:28 +0000 (19:50 +0000)
committerdrh <drh@noemail.net>
Thu, 12 Oct 2017 19:50:28 +0000 (19:50 +0000)
checkfreelist.c from the command-line shell (undoing check-in [48418f2e]).

FossilOrigin-Name: dfdebd12bfc80b91d234ab328cb6106d5d37ccb79b58e36e556c1a8af640a4ab

ext/repair/README.md [new file with mode: 0644]
ext/repair/checkfreelist.c [moved from ext/misc/checkfreelist.c with 100% similarity]
manifest
manifest.uuid
src/shell.c
src/shell.c.in

diff --git a/ext/repair/README.md b/ext/repair/README.md
new file mode 100644 (file)
index 0000000..927ceb7
--- /dev/null
@@ -0,0 +1,16 @@
+This folder contains extensions and utility programs intended to analyze
+live database files, detect problems, and possibly fix them.
+
+As SQLite is being used on larger and larger databases, database sizes
+are growing into the terabyte range.  At that size, hardware malfunctions
+and/or cosmic rays will occasionally corrupt a database file.  Detecting 
+problems and fixing errors a terabyte-sized databases can take hours or days,
+and it is undesirable to take applications that depend on the databases 
+off-line for such a long time.
+The utilities in the folder are intended to provide mechanisms for
+detecting and fixing problems in large databases while those databases
+are in active use.
+
+The utilities and extensions in this folder are experimental and under
+active development at the time of this writing (2017-10-12).  If and when
+they stabilize, this README will be updated to reflect that fact.
index e5589b7672fb0a42ea4b2926c177ff6c21be8fbf..5c8309403b9245e41aeb73c9e047ef7d78fd5345 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\sfixes\sfrom\sthe\s3.21\sbranch.
-D 2017-10-12T01:24:36.582
+C Create\sthe\snew\sext/repair\sfolder\sand\smove\scheckfreelist.c\sthere.\s\sRemove\ncheckfreelist.c\sfrom\sthe\scommand-line\sshell\s(undoing\scheck-in\s[48418f2e]).
+D 2017-10-12T19:50:28.969
 F Makefile.in 05d02ce8606a9e46cd413d0bb46873fe597e5e41f52c4110241c11e60adff018
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 523fd246fd801689c766945f6450615d3784fda2dc04993bcafc796ac6afd8df
@@ -259,7 +259,6 @@ F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601
 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87
 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
 F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
-F ext/misc/checkfreelist.c 0abb84b4545016d57ba1a2aa8884c72c73ed838968909858c03bc1f38fb6b054
 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
 F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f
 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
@@ -326,6 +325,8 @@ F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
 F ext/rbu/sqlite3rbu.c 64bd08c1011456f90564ed167abce3a9c2af421a924b21eb57231e078da04feb
 F ext/rbu/sqlite3rbu.h b42bcd4d8357268c6c39ab2a60b29c091e89328fa8cc49c8fac5ab8d007e79b2
 F ext/rbu/test_rbu.c 7073979b9cc80912bb03599ac8d85ab5d3bf03cfacd3463f2dcdd7822997533a
+F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
+F ext/repair/checkfreelist.c 0abb84b4545016d57ba1a2aa8884c72c73ed838968909858c03bc1f38fb6b054 w ext/misc/checkfreelist.c
 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
 F ext/rtree/rtree.c f2fd34db37ea053798f8e66b44a473449b21301d2b92505ee576823789e909fb
 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
@@ -461,8 +462,8 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c 42aca61e739c405ddd8a1b702977a7743c7d52a94885f7c5596bd7e73e6bff18
-F src/shell.c ffb06532d6667bf1bb64080a316120c67249636a12f008c2f9716d6778565d57
-F src/shell.c.in 7842db264d5512520c61d0353196eeefeb65b710dd0d97d4ad9844c56e313be5
+F src/shell.c b1c14539ae8f756a96a5604952e24fb8f2a65745290037f4f43dddfabac76e6e
+F src/shell.c.in 73d8000bb066cd7ceb9655ffdb0e19a80779e3c64506f5a1ecfa9838511bee18
 F src/sqlite.h.in ab4f8a29d1580dfaeb6891fa1b83cff8229ba0daa56994707ceaca71495d9ab7
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47
@@ -1660,7 +1661,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 48418f2ed5ab1cb270776166141ce32ed3ebf22ed4e33a66a204d4fde9d11f52 f0a2724f0a255cd5a262f31e4ee1f99ae713c25a9ecc56dc794c95f223453b9b
-R 9b46eb5073fd5db6110bab2092230089
+P 18d4654fd161900f98ff435ea9e0a3c44b9972f84ee9f43096f9998f844ff857
+Q -48418f2ed5ab1cb270776166141ce32ed3ebf22ed4e33a66a204d4fde9d11f52
+R 4a0d06893cd053abce709ab7740cd918
 U drh
-Z b5c9a13e106677edbcab94b5f19597c5
+Z 46634faecfbbf65605db6fcff2dbe040
index f8e3904fb942d24adcd29b1bb700f2bd1dc7501d..58e6b4a3f7a34f84d58e8ed24f9bb8734c500c57 100644 (file)
@@ -1 +1 @@
-18d4654fd161900f98ff435ea9e0a3c44b9972f84ee9f43096f9998f844ff857
\ No newline at end of file
+dfdebd12bfc80b91d234ab328cb6106d5d37ccb79b58e36e556c1a8af640a4ab
\ No newline at end of file
index 6c14db9fdd9f39e20301ecaa05cab6589b3f2384..2b77d482e629c30a88fdc98c685b10153a65a917 100644 (file)
@@ -2156,307 +2156,6 @@ int sqlite3_completion_init(
 }
 
 /************************* End ../ext/misc/completion.c ********************/
-/************************* Begin ../ext/misc/checkfreelist.c ******************/
-/*
-** 2017 October 11
-**
-** 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.
-**
-*************************************************************************
-**
-** This module exports a single C function:
-**
-**   int sqlite3_check_freelist(sqlite3 *db, const char *zDb);
-**
-** This function checks the free-list in database zDb (one of "main", 
-** "temp", etc.) and reports any errors by invoking the sqlite3_log()
-** function. It returns SQLITE_OK if successful, or an SQLite error
-** code otherwise. It is not an error if the free-list is corrupted but
-** no IO or OOM errors occur.
-**
-** If this file is compiled and loaded as an SQLite loadable extension,
-** it adds an SQL function "checkfreelist" to the database handle, to
-** be invoked as follows:
-**
-**   SELECT checkfreelist(<database-name>);
-**
-** This function performs the same checks as sqlite3_check_freelist(),
-** except that it returns all error messages as a single text value,
-** separated by newline characters. If the freelist is not corrupted
-** in any way, an empty string is returned.
-**
-** To compile this module for use as an SQLite loadable extension:
-**
-**   gcc -Os -fPIC -shared checkfreelist.c -o checkfreelist.so
-*/
-
-SQLITE_EXTENSION_INIT1
-
-#ifndef SQLITE_AMALGAMATION
-# include <string.h>
-# include <stdio.h>
-# include <stdlib.h>
-# include <assert.h>
-# define ALWAYS(X)  1
-# define NEVER(X)   0
-  typedef unsigned char u8;
-  typedef unsigned short u16;
-  typedef unsigned int u32;
-#define get4byte(x) (        \
-    ((u32)((x)[0])<<24) +    \
-    ((u32)((x)[1])<<16) +    \
-    ((u32)((x)[2])<<8) +     \
-    ((u32)((x)[3]))          \
-)
-#endif
-
-/*
-** Execute a single PRAGMA statement and return the integer value returned
-** via output parameter (*pnOut).
-**
-** The SQL statement passed as the third argument should be a printf-style
-** format string containing a single "%s" which will be replace by the
-** value passed as the second argument. e.g.
-**
-**   sqlGetInteger(db, "main", "PRAGMA %s.page_count", pnOut)
-**
-** executes "PRAGMA main.page_count" and stores the results in (*pnOut).
-*/
-static int sqlGetInteger(
-  sqlite3 *db,                    /* Database handle */
-  const char *zDb,                /* Database name ("main", "temp" etc.) */
-  const char *zFmt,               /* SQL statement format */
-  u32 *pnOut                      /* OUT: Integer value */
-){
-  int rc, rc2;
-  char *zSql;
-  sqlite3_stmt *pStmt = 0;
-  int bOk = 0;
-
-  zSql = sqlite3_mprintf(zFmt, zDb);
-  if( zSql==0 ){
-    rc = SQLITE_NOMEM;
-  }else{
-    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
-    sqlite3_free(zSql);
-  }
-
-  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
-    *pnOut = (u32)sqlite3_column_int(pStmt, 0);
-    bOk = 1;
-  }
-
-  rc2 = sqlite3_finalize(pStmt);
-  if( rc==SQLITE_OK ) rc = rc2;
-  if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_ERROR;
-  return rc;
-}
-
-/*
-** Argument zFmt must be a printf-style format string and must be 
-** followed by its required arguments. If argument pzOut is NULL, 
-** then the results of printf()ing the format string are passed to
-** sqlite3_log(). Otherwise, they are appended to the string
-** at (*pzOut).
-*/
-static int checkFreelistError(char **pzOut, const char *zFmt, ...){
-  int rc = SQLITE_OK;
-  char *zErr = 0;
-  va_list ap;
-
-  va_start(ap, zFmt);
-  zErr = sqlite3_vmprintf(zFmt, ap);
-  if( zErr==0 ){
-    rc = SQLITE_NOMEM;
-  }else{
-    if( pzOut ){
-      *pzOut = sqlite3_mprintf("%s%z%s", *pzOut?"\n":"", *pzOut, zErr);
-      if( *pzOut==0 ) rc = SQLITE_NOMEM;
-    }else{
-      sqlite3_log(SQLITE_ERROR, "checkfreelist: %s", zErr);
-    }
-    sqlite3_free(zErr);
-  }
-  va_end(ap);
-  return rc;
-}
-
-static int checkFreelist(
-  sqlite3 *db, 
-  const char *zDb,
-  char **pzOut
-){
-  /* This query returns one row for each page on the free list. Each row has
-  ** two columns - the page number and page content.  */
-  const char *zTrunk = 
-    "WITH freelist_trunk(i, d, n) AS ("
-      "SELECT 1, NULL, sqlite_readint32(data, 32) "
-      "FROM sqlite_dbpage(:1) WHERE pgno=1 "
-        "UNION ALL "
-      "SELECT n, data, sqlite_readint32(data) "
-      "FROM freelist_trunk, sqlite_dbpage(:1) WHERE pgno=n "
-    ")"
-    "SELECT i, d FROM freelist_trunk WHERE i!=1;";
-
-  int rc, rc2;                    /* Return code */
-  sqlite3_stmt *pTrunk = 0;       /* Compilation of zTrunk */
-  u32 nPage = 0;                  /* Number of pages in db */
-  u32 nExpected = 0;              /* Expected number of free pages */
-  u32 nFree = 0;                  /* Number of pages on free list */
-
-  if( zDb==0 ) zDb = "main";
-
-  if( (rc = sqlGetInteger(db, zDb, "PRAGMA %s.page_count", &nPage))
-   || (rc = sqlGetInteger(db, zDb, "PRAGMA %s.freelist_count", &nExpected))
-  ){
-    return rc;
-  }
-
-  rc = sqlite3_prepare_v2(db, zTrunk, -1, &pTrunk, 0);
-  if( rc!=SQLITE_OK ) return rc;
-  sqlite3_bind_text(pTrunk, 1, zDb, -1, SQLITE_STATIC);
-  while( rc==SQLITE_OK && sqlite3_step(pTrunk)==SQLITE_ROW ){
-    u32 i;
-    u32 iTrunk = (u32)sqlite3_column_int(pTrunk, 0);
-    const u8 *aData = (const u8*)sqlite3_column_blob(pTrunk, 1);
-    int nData = sqlite3_column_bytes(pTrunk, 1);
-    u32 iNext = get4byte(&aData[0]);
-    u32 nLeaf = get4byte(&aData[4]);
-
-    if( nLeaf>((nData/4)-2-6) ){
-      rc = checkFreelistError(pzOut, 
-          "leaf count out of range (%d) on trunk page %d", 
-          (int)nLeaf, (int)iTrunk
-      );
-      nLeaf = (nData/4) - 2 - 6;
-    }
-
-    nFree += 1+nLeaf;
-    if( iNext>nPage ){
-      rc = checkFreelistError(pzOut, 
-          "trunk page %d is out of range", (int)iNext
-      );
-    }
-
-    for(i=0; rc==SQLITE_OK && i<nLeaf; i++){
-      u32 iLeaf = get4byte(&aData[8 + 4*i]);
-      if( iLeaf==0 || iLeaf>nPage ){
-        rc = checkFreelistError(pzOut,
-            "leaf page %d is out of range (child %d of trunk page %d)", 
-            (int)iLeaf, (int)i, (int)iTrunk
-        );
-      }
-    }
-  }
-
-  if( rc==SQLITE_OK && nFree!=nExpected ){
-    rc = checkFreelistError(pzOut,
-        "free-list count mismatch: actual=%d header=%d", 
-        (int)nFree, (int)nExpected
-    );
-  }
-
-  rc2 = sqlite3_finalize(pTrunk);
-  if( rc==SQLITE_OK ) rc = rc2;
-  return rc;
-}
-
-int sqlite3_check_freelist(sqlite3 *db, const char *zDb){
-  return checkFreelist(db, zDb, 0);
-}
-
-static void checkfreelist_function(
-  sqlite3_context *pCtx,
-  int nArg,
-  sqlite3_value **apArg
-){
-  const char *zDb;
-  int rc;
-  char *zOut = 0;
-  sqlite3 *db = sqlite3_context_db_handle(pCtx);
-
-  assert( nArg==1 );
-  zDb = (const char*)sqlite3_value_text(apArg[0]);
-  rc = checkFreelist(db, zDb, &zOut);
-  if( rc==SQLITE_OK ){
-    sqlite3_result_text(pCtx, zOut?zOut:"ok", -1, SQLITE_TRANSIENT);
-  }else{
-    sqlite3_result_error_code(pCtx, rc);
-  }
-
-  sqlite3_free(zOut);
-}
-
-/*
-** An SQL function invoked as follows:
-**
-**   sqlite_readint32(BLOB)           -- Decode 32-bit integer from start of blob
-*/
-static void readint_function(
-  sqlite3_context *pCtx,
-  int nArg,
-  sqlite3_value **apArg
-){
-  const u8 *zBlob;
-  int nBlob;
-  int iOff = 0;
-  u32 iRet = 0;
-
-  if( nArg!=1 && nArg!=2 ){
-    sqlite3_result_error(
-        pCtx, "wrong number of arguments to function sqlite_readint32()", -1
-    );
-    return;
-  }
-  if( nArg==2 ){
-    iOff = sqlite3_value_int(apArg[1]);
-  }
-
-  zBlob = sqlite3_value_blob(apArg[0]);
-  nBlob = sqlite3_value_bytes(apArg[0]);
-
-  if( nBlob>=(iOff+4) ){
-    iRet = get4byte(&zBlob[iOff]);
-  }
-
-  sqlite3_result_int64(pCtx, (sqlite3_int64)iRet);
-}
-
-/*
-** Register the SQL functions.
-*/
-static int cflRegister(sqlite3 *db){
-  int rc = sqlite3_create_function(
-      db, "sqlite_readint32", -1, SQLITE_UTF8, 0, readint_function, 0, 0
-  );
-  if( rc!=SQLITE_OK ) return rc;
-  rc = sqlite3_create_function(
-      db, "checkfreelist", 1, SQLITE_UTF8, 0, checkfreelist_function, 0, 0
-  );
-  return rc;
-}
-
-/*
-** Extension load function.
-*/
-#ifdef _WIN32
-
-#endif
-int sqlite3_checkfreelist_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  SQLITE_EXTENSION_INIT2(pApi);
-  return cflRegister(db);
-}
-
-/************************* End ../ext/misc/checkfreelist.c ********************/
 
 #if defined(SQLITE_ENABLE_SESSION)
 /*
@@ -4547,7 +4246,6 @@ static void open_db(ShellState *p, int keepAlive){
     sqlite3_fileio_init(p->db, 0, 0);
     sqlite3_shathree_init(p->db, 0, 0);
     sqlite3_completion_init(p->db, 0, 0);
-    sqlite3_checkfreelist_init(p->db, 0, 0);
     sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
                             shellAddSchemaName, 0, 0);
   }
index de170887f7b8f14ec9ab23e3a65da8ff1a2aea14..54a61b94563d57b67b9789d3610301d8f903327b 100644 (file)
@@ -796,7 +796,6 @@ static void shellAddSchemaName(
 INCLUDE ../ext/misc/shathree.c
 INCLUDE ../ext/misc/fileio.c
 INCLUDE ../ext/misc/completion.c
-INCLUDE ../ext/misc/checkfreelist.c
 
 #if defined(SQLITE_ENABLE_SESSION)
 /*
@@ -2887,7 +2886,6 @@ static void open_db(ShellState *p, int keepAlive){
     sqlite3_fileio_init(p->db, 0, 0);
     sqlite3_shathree_init(p->db, 0, 0);
     sqlite3_completion_init(p->db, 0, 0);
-    sqlite3_checkfreelist_init(p->db, 0, 0);
     sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
                             shellAddSchemaName, 0, 0);
   }