SQLite4
Check-in [3423d37092]
Not logged in

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

Overview
Comment:Fix a bug in the test used to determine if a free block is ready for reuse.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | multi-process
Files: files | file ages | folders
SHA1: 3423d3709297502fa734aff78848259166f4bb2a
User & Date: dan 2012-09-01 09:11:30
Context
2012-09-01
11:09
When loading free-list elements from the lsm, merge them into the existing free-list so that free blocks are always sorted from least to most recently used. check-in: 4a2be461c1 user: dan tags: multi-process
09:11
Fix a bug in the test used to determine if a free block is ready for reuse. check-in: 3423d37092 user: dan tags: multi-process
2012-08-31
20:26
Avoid reusing a block before it is guaranteed that it is not required even if a crash occurs. check-in: 5f9bb542f7 user: dan tags: multi-process
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/lsmInt.h.

480
481
482
483
484
485
486

487
488
489
490
491
492
493
int lsmCheckpointPgsz(u32 *);
int lsmCheckpointBlksz(u32 *);
void lsmCheckpointLogoffset(u32 *aCkpt, DbLog *pLog);
void lsmCheckpointZeroLogoffset(lsm_db *);

int lsmCheckpointSaveWorker(lsm_db *pDb, int, int);
int lsmDatabaseFull(lsm_db *pDb);



/* 
** Functions from file "lsm_tree.c".
*/
int lsmTreeNew(lsm_env *, int (*)(void *, int, void *, int), Tree **ppTree);
void lsmTreeRelease(lsm_env *, Tree *);







>







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
int lsmCheckpointPgsz(u32 *);
int lsmCheckpointBlksz(u32 *);
void lsmCheckpointLogoffset(u32 *aCkpt, DbLog *pLog);
void lsmCheckpointZeroLogoffset(lsm_db *);

int lsmCheckpointSaveWorker(lsm_db *pDb, int, int);
int lsmDatabaseFull(lsm_db *pDb);
int lsmCheckpointSynced(lsm_db *pDb, i64 *piId);


/* 
** Functions from file "lsm_tree.c".
*/
int lsmTreeNew(lsm_env *, int (*)(void *, int, void *, int), Tree **ppTree);
void lsmTreeRelease(lsm_env *, Tree *);

Changes to src/lsm_shared.c.

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
...
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
    lsmMutexDel(pEnv, p->pClientMutex);

    /* Free the memory allocated for the Database struct itself */
    lsmFree(pEnv, p);
  }
}

static int doDbDisconnect(lsm_db *pDb){
  int rc;

  /* Block for an exclusive lock on DMS1. This lock serializes all calls
  ** to doDbConnect() and doDbDisconnect() across all processes.  */
  rc = lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL, 1);
  if( rc==LSM_OK ){

................................................................................
    for(ppDb=&p->pConn; *ppDb!=pDb; ppDb=&((*ppDb)->pNext));
    *ppDb = pDb->pNext;
    lsmMutexLeave(pDb->pEnv, p->pClientMutex);

    enterGlobalMutex(pDb->pEnv);
    p->nDbRef--;
    if( p->nDbRef==0 ){
      int rc = LSM_OK;
      int i;
      Database **pp;

      /* Remove the Database structure from the linked list. */
      for(pp=&gShared.pDatabase; *pp!=p; pp=&((*pp)->pDbNext));
      *pp = p->pDbNext;

................................................................................
    /* The "is in use" bit */
    rc = lsmLsmInUse(pDb, iFree, &bInUse);

    /* The "has been checkpointed" bit */
    if( rc==LSM_OK && bInUse==0 ){
      i64 iId = 0;
      rc = lsmCheckpointSynced(pDb, &iId);
      if( rc==LSM_OK && iId<iFree ) bInUse = 1;
      if( rc==LSM_BUSY ) rc = LSM_OK;
    }

    if( rc==LSM_OK && bInUse==0 ){
      iRet = pFree->aEntry[0].iBlk;
      flRemoveEntry0(pFree);
      assert( iRet!=0 );
................................................................................
  }

  /* If no error has occured, then the snapshot currently in pDb->aSnapshot
  ** has been synced to disk. This means it may be possible to wrap the
  ** log file. Obtain the WRITER lock and update the relevent tree-header
  ** fields to reflect this.  */
  if( rc==LSM_OK ){
    int rc2;
    u64 iLogoff = lsmCheckpointLogOffset(pDb->aSnapshot);
    rc = lsmShmLock(pDb, LSM_LOCK_WRITER, LSM_LOCK_EXCL, 0);
    if( rc==LSM_OK ) rc = lsmTreeLoadHeader(pDb);
    if( rc==LSM_OK ) lsmLogCheckpoint(pDb, iLogoff);
    if( rc==LSM_OK ) lsmTreeEndTransaction(pDb, 1);
    if( rc==LSM_BUSY ) rc = LSM_OK;
  }







|







 







<







 







|







 







<







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
...
337
338
339
340
341
342
343

344
345
346
347
348
349
350
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
...
512
513
514
515
516
517
518

519
520
521
522
523
524
525
    lsmMutexDel(pEnv, p->pClientMutex);

    /* Free the memory allocated for the Database struct itself */
    lsmFree(pEnv, p);
  }
}

static void doDbDisconnect(lsm_db *pDb){
  int rc;

  /* Block for an exclusive lock on DMS1. This lock serializes all calls
  ** to doDbConnect() and doDbDisconnect() across all processes.  */
  rc = lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL, 1);
  if( rc==LSM_OK ){

................................................................................
    for(ppDb=&p->pConn; *ppDb!=pDb; ppDb=&((*ppDb)->pNext));
    *ppDb = pDb->pNext;
    lsmMutexLeave(pDb->pEnv, p->pClientMutex);

    enterGlobalMutex(pDb->pEnv);
    p->nDbRef--;
    if( p->nDbRef==0 ){

      int i;
      Database **pp;

      /* Remove the Database structure from the linked list. */
      for(pp=&gShared.pDatabase; *pp!=p; pp=&((*pp)->pDbNext));
      *pp = p->pDbNext;

................................................................................
    /* The "is in use" bit */
    rc = lsmLsmInUse(pDb, iFree, &bInUse);

    /* The "has been checkpointed" bit */
    if( rc==LSM_OK && bInUse==0 ){
      i64 iId = 0;
      rc = lsmCheckpointSynced(pDb, &iId);
      if( rc!=LSM_OK || iId<iFree ) bInUse = 1;
      if( rc==LSM_BUSY ) rc = LSM_OK;
    }

    if( rc==LSM_OK && bInUse==0 ){
      iRet = pFree->aEntry[0].iBlk;
      flRemoveEntry0(pFree);
      assert( iRet!=0 );
................................................................................
  }

  /* If no error has occured, then the snapshot currently in pDb->aSnapshot
  ** has been synced to disk. This means it may be possible to wrap the
  ** log file. Obtain the WRITER lock and update the relevent tree-header
  ** fields to reflect this.  */
  if( rc==LSM_OK ){

    u64 iLogoff = lsmCheckpointLogOffset(pDb->aSnapshot);
    rc = lsmShmLock(pDb, LSM_LOCK_WRITER, LSM_LOCK_EXCL, 0);
    if( rc==LSM_OK ) rc = lsmTreeLoadHeader(pDb);
    if( rc==LSM_OK ) lsmLogCheckpoint(pDb, iLogoff);
    if( rc==LSM_OK ) lsmTreeEndTransaction(pDb, 1);
    if( rc==LSM_BUSY ) rc = LSM_OK;
  }