/ Check-in [e05089aa]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Invoke sqlite3_log() whenever one or more frames are recovered from a WAL file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e05089aaefe02ec59a1923812349471a78075d29
User & Date: dan 2010-08-17 14:52:23
Context
2010-08-17
16:06
Add tests for the BETWEEN operator to e_expr.test. check-in: ced6a348 user: dan tags: trunk
14:52
Invoke sqlite3_log() whenever one or more frames are recovered from a WAL file. check-in: e05089aa user: dan tags: trunk
05:55
Fix some non-ANSI C code in test_demovfs.c. Also change the same file so that attempting to delete a file that does not exist does not return an error. check-in: 07570ce3 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test1.c.

  4945   4945       zDb = Tcl_GetString(objv[2]);
  4946   4946     }
  4947   4947     rc = sqlite3_wal_checkpoint(db, zDb);
  4948   4948     Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
  4949   4949     return TCL_OK;
  4950   4950   }
  4951   4951   
         4952  +/*
         4953  +** tclcmd:  test_sqlite3_log ?SCRIPT?
         4954  +*/
         4955  +static struct LogCallback {
         4956  +  Tcl_Interp *pInterp;
         4957  +  Tcl_Obj *pObj;
         4958  +} logcallback = {0, 0};
         4959  +static void xLogcallback(void *unused, int err, char *zMsg){
         4960  +  Tcl_Obj *pNew = Tcl_DuplicateObj(logcallback.pObj);
         4961  +  Tcl_IncrRefCount(pNew);
         4962  +  Tcl_ListObjAppendElement(
         4963  +      0, pNew, Tcl_NewStringObj(sqlite3TestErrorName(err), -1)
         4964  +  );
         4965  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zMsg, -1));
         4966  +  Tcl_EvalObjEx(logcallback.pInterp, pNew, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
         4967  +  Tcl_DecrRefCount(pNew);
         4968  +}
         4969  +static int test_sqlite3_log(
         4970  +  ClientData clientData,
         4971  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
         4972  +  int objc,              /* Number of arguments */
         4973  +  Tcl_Obj *CONST objv[]  /* Command arguments */
         4974  +){
         4975  +  if( objc>2 ){
         4976  +    Tcl_WrongNumArgs(interp, 1, objv, "SCRIPT");
         4977  +    return TCL_ERROR;
         4978  +  }
         4979  +  if( logcallback.pObj ){
         4980  +    Tcl_DecrRefCount(logcallback.pObj);
         4981  +    logcallback.pObj = 0;
         4982  +    logcallback.pInterp = 0;
         4983  +    sqlite3_config(SQLITE_CONFIG_LOG, 0, 0);
         4984  +  }
         4985  +  if( objc>1 ){
         4986  +    logcallback.pObj = objv[1];
         4987  +    Tcl_IncrRefCount(logcallback.pObj);
         4988  +    logcallback.pInterp = interp;
         4989  +    sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, 0);
         4990  +  }
         4991  +  return TCL_OK;
         4992  +}
  4952   4993   
  4953   4994   /*
  4954   4995   **     tcl_objproc COMMANDNAME ARGS...
  4955   4996   **
  4956   4997   ** Run a TCL command using its objProc interface.  Throw an error if
  4957   4998   ** the command has no objProc interface.
  4958   4999   */
................................................................................
  5168   5209        { "sqlite3_blob_write", test_blob_write, 0  },
  5169   5210   #endif
  5170   5211        { "pcache_stats",       test_pcache_stats, 0  },
  5171   5212   #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
  5172   5213        { "sqlite3_unlock_notify", test_unlock_notify, 0  },
  5173   5214   #endif
  5174   5215        { "sqlite3_wal_checkpoint", test_wal_checkpoint, 0  },
         5216  +     { "test_sqlite3_log",     test_sqlite3_log, 0  },
  5175   5217     };
  5176   5218     static int bitmask_size = sizeof(Bitmask)*8;
  5177   5219     int i;
  5178   5220     extern int sqlite3_sync_count, sqlite3_fullsync_count;
  5179   5221     extern int sqlite3_opentemp_count;
  5180   5222     extern int sqlite3_like_count;
  5181   5223     extern int sqlite3_xferopt_count;

Changes to src/wal.c.

  1158   1158       ** currently holding locks that exclude all other readers, writers and
  1159   1159       ** checkpointers.
  1160   1160       */
  1161   1161       pInfo = walCkptInfo(pWal);
  1162   1162       pInfo->nBackfill = 0;
  1163   1163       pInfo->aReadMark[0] = 0;
  1164   1164       for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
         1165  +
         1166  +    /* If more than one frame was recovered from the log file, report an
         1167  +    ** event via sqlite3_log(). This is to help with identifying performance
         1168  +    ** problems caused by applications routinely shutting down without
         1169  +    ** checkpointing the log file.
         1170  +    */
         1171  +    if( pWal->hdr.nPage ){
         1172  +      sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s",
         1173  +          pWal->hdr.nPage, pWal->zWalName
         1174  +      );
         1175  +    }
  1165   1176     }
  1166   1177   
  1167   1178   recovery_error:
  1168   1179     WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
  1169   1180     walUnlockExclusive(pWal, iLock, nLock);
  1170   1181     return rc;
  1171   1182   }

Changes to test/wal.test.

  1445   1445   } {ok}
  1446   1446   
  1447   1447   #-------------------------------------------------------------------------
  1448   1448   # Test reading and writing of databases with different page-sizes.
  1449   1449   #
  1450   1450   foreach pgsz {512 1024 2048 4096 8192 16384 32768 65536} {
  1451   1451     do_multiclient_test tn [string map [list %PGSZ% $pgsz] {
  1452         -    do_test e_expr-22.%PGSZ%.$tn.1 {
         1452  +    do_test wal-22.%PGSZ%.$tn.1 {
  1453   1453         sql1 {
  1454   1454           PRAGMA main.page_size = %PGSZ%;
  1455   1455           PRAGMA auto_vacuum = 0;
  1456   1456           PRAGMA journal_mode = WAL;
  1457   1457           CREATE TABLE t1(x UNIQUE);
  1458   1458           INSERT INTO t1 SELECT randomblob(800);
  1459   1459           INSERT INTO t1 SELECT randomblob(800);
  1460   1460           INSERT INTO t1 SELECT randomblob(800);
  1461   1461         }
  1462   1462       } {wal}
  1463         -    do_test e_expr-22.%PGSZ%.$tn.2 { sql2 { PRAGMA integrity_check } } {ok}
  1464         -    do_test e_expr-22.%PGSZ%.$tn.3 {
         1463  +    do_test wal-22.%PGSZ%.$tn.2 { sql2 { PRAGMA integrity_check } } {ok}
         1464  +    do_test wal-22.%PGSZ%.$tn.3 {
  1465   1465         sql1 {PRAGMA wal_checkpoint}
  1466   1466         expr {[file size test.db] % %PGSZ%}
  1467   1467       } {0}
  1468   1468     }]
  1469   1469   }
         1470  +
         1471  +#-------------------------------------------------------------------------
         1472  +# Test that when 1 or more pages are recovered from a WAL file, 
         1473  +# sqlite3_log() is invoked to report this to the user.
         1474  +#
         1475  +set walfile [file join [pwd] test.db-wal]
         1476  +catch {db close}
         1477  +file delete -force test.db
         1478  +do_test wal-23.1 {
         1479  +  faultsim_delete_and_reopen
         1480  +  execsql {
         1481  +    CREATE TABLE t1(a, b);
         1482  +    PRAGMA journal_mode = WAL;
         1483  +    INSERT INTO t1 VALUES(1, 2);
         1484  +    INSERT INTO t1 VALUES(3, 4);
         1485  +  }
         1486  +  faultsim_save_and_close
         1487  +
         1488  +  sqlite3_shutdown
         1489  +  test_sqlite3_log [list lappend ::log]
         1490  +  set ::log [list]
         1491  +  sqlite3 db test.db
         1492  +  execsql { SELECT * FROM t1 }
         1493  +} {1 2 3 4}
         1494  +do_test wal-23.2 { set ::log } {}
         1495  +
         1496  +do_test wal-23.3 {
         1497  +  db close
         1498  +  set ::log [list]
         1499  +  faultsim_restore_and_reopen
         1500  +  execsql { SELECT * FROM t1 }
         1501  +} {1 2 3 4}
         1502  +do_test wal-23.4 { 
         1503  +  set ::log 
         1504  +} [list SQLITE_OK "Recovered 2 frames from WAL file $walfile"]
         1505  +
         1506  +db close
         1507  +sqlite3_shutdown
         1508  +test_sqlite3_log
         1509  +sqlite3_initialize
  1470   1510   
  1471   1511   finish_test