Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Another free-list related fix. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | freelist-rework |
Files: | files | file ages | folders |
SHA1: |
a8acce6c8721cb5275c4c3584848688f |
User & Date: | dan 2012-10-30 18:46:45.447 |
Context
2012-10-31
| ||
09:25 | Prevent auto-work from recycling blocks before the connection doing the auto-work has finished using them. check-in: 7b5a26996f user: dan tags: freelist-rework | |
2012-10-30
| ||
18:46 | Another free-list related fix. check-in: a8acce6c87 user: dan tags: freelist-rework | |
17:34 | Avoid writing completely empty segments to the snapshot. check-in: 803f36b62f user: dan tags: freelist-rework | |
Changes
Changes to src/lsm_shared.c.
︙ | ︙ | |||
573 574 575 576 577 578 579 580 581 582 | if( rc==LSM_OK ){ if( iRet>0 ){ #ifdef LSM_LOG_FREELIST lsmLogMessage(pDb, 0, "reusing block %d", iRet); #endif rc = freelistAppend(pDb, iRet, -1); }else{ #ifdef LSM_LOG_FREELIST lsmLogMessage(pDb, 0, "extending file to %d blocks", iRet); #endif | > < | 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | if( rc==LSM_OK ){ if( iRet>0 ){ #ifdef LSM_LOG_FREELIST lsmLogMessage(pDb, 0, "reusing block %d", iRet); #endif rc = freelistAppend(pDb, iRet, -1); }else{ iRet = ++(p->nBlock); #ifdef LSM_LOG_FREELIST lsmLogMessage(pDb, 0, "extending file to %d blocks", iRet); #endif } } assert( iRet>0 || rc!=LSM_OK ); *piBlk = iRet; return rc; } |
︙ | ︙ | |||
621 622 623 624 625 626 627 | int rc = LSM_OK; /* Return code */ Snapshot *p = pDb->pWorker; #ifdef LSM_LOG_FREELIST lsmLogMessage(pDb, LSM_OK, "lsmBlockRefree(): Refree block %d", iBlk); #endif | < < < | < < | 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | int rc = LSM_OK; /* Return code */ Snapshot *p = pDb->pWorker; #ifdef LSM_LOG_FREELIST lsmLogMessage(pDb, LSM_OK, "lsmBlockRefree(): Refree block %d", iBlk); #endif rc = freelistAppend(pDb, iBlk, 0); return rc; } /* ** If required, copy a database checkpoint from shared memory into the ** database itself. ** |
︙ | ︙ |
Changes to src/lsm_sorted.c.
︙ | ︙ | |||
3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 | #if 0 if( pNew->lhs.iFirst ){ lsmSortedDumpStructure(pDb, pDb->pWorker, 0, 0, "new-toplevel"); } #endif if( rc==LSM_OK ){ if( freelist.nEntry ){ Freelist *p = &pDb->pWorker->freelist; lsmFree(pDb->pEnv, p->aEntry); memcpy(p, &freelist, sizeof(freelist)); freelist.aEntry = 0; }else{ pDb->pWorker->freelist.nEntry = 0; | > | 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 | #if 0 if( pNew->lhs.iFirst ){ lsmSortedDumpStructure(pDb, pDb->pWorker, 0, 0, "new-toplevel"); } #endif if( rc==LSM_OK ){ assert( pNew->lhs.iFirst || pDb->pWorker->freelist.nEntry==0 ); if( freelist.nEntry ){ Freelist *p = &pDb->pWorker->freelist; lsmFree(pDb->pEnv, p->aEntry); memcpy(p, &freelist, sizeof(freelist)); freelist.aEntry = 0; }else{ pDb->pWorker->freelist.nEntry = 0; |
︙ | ︙ | |||
4455 4456 4457 4458 4459 4460 4461 | int flags, int nPage, /* Number of pages to write to disk */ int *pnWrite, /* OUT: Pages actually written to disk */ int *pbCkpt /* OUT: True if an auto-checkpoint is req. */ ){ int rc = LSM_OK; /* Return code */ int nOvfl = 0; | | < | > > > > > > | > | | | > | < < > | | < | 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 | int flags, int nPage, /* Number of pages to write to disk */ int *pnWrite, /* OUT: Pages actually written to disk */ int *pbCkpt /* OUT: True if an auto-checkpoint is req. */ ){ int rc = LSM_OK; /* Return code */ int nOvfl = 0; int bDirty = 0; int nMax = nPage; /* Maximum pages to write to disk */ int nRem = nPage; int bCkpt = 0; /* Open the worker 'transaction'. It will be closed before this function ** returns. */ assert( pDb->pWorker==0 ); rc = lsmBeginWork(pDb); if( rc!=LSM_OK ) return rc; /* If this connection is doing auto-checkpoints, set nMax (and nRem) so ** that this call stops writing when the auto-checkpoint is due. The ** caller will do the checkpoint, then possibly call this function again. */ if( bShutdown==0 && pDb->nAutockpt ){ u32 nSync; u32 nUnsync; int nPgsz; int nMax; lsmCheckpointSynced(pDb, 0, 0, &nSync); nUnsync = lsmCheckpointNWrite(pDb->pShmhdr->aSnap1, 0); nPgsz = lsmCheckpointPgsz(pDb->pShmhdr->aSnap1); nMax = (pDb->nAutockpt/nPgsz) - (nUnsync-nSync); if( nMax<nRem ){ bCkpt = 1; nRem = LSM_MAX(nMax, 0); } } /* If there exists in-memory data ready to be flushed to disk, attempt ** to flush it now. */ if( sortedTreeHasOld(pDb, &rc) ){ /* sortedDbIsFull() returns non-zero if either (a) there are too many ** levels in total in the db, or (b) there are too many levels with the ** the same age in the db. Either way, call sortedWork() to merge ** existing segments together until this condition is cleared. */ if( sortedDbIsFull(pDb) ){ int nPg = 0; rc = sortedWork(pDb, nRem, 0, 1, &nPg); nRem -= nPg; assert( rc!=LSM_OK || nRem<=0 || !sortedDbIsFull(pDb) ); } if( rc==LSM_OK && nRem>0 ){ int nPg = 0; rc = sortedNewToplevel(pDb, TREE_OLD, &nOvfl, &nPg); nRem -= nPg; if( rc==LSM_OK ){ if( pDb->nTransOpen>0 ){ lsmTreeDiscardOld(pDb); } rc = lsmCheckpointSaveWorker(pDb, 1, 0); } } } /* If nPage is still greater than zero, do some merging. */ if( rc==LSM_OK && nRem>0 && bShutdown==0 ){ int nPg = 0; int bOptimize = ((flags & LSM_WORK_OPTIMIZE) ? 1 : 0); rc = sortedWork(pDb, nRem, bOptimize, 0, &nPg); nRem -= nPg; if( nPg ) bDirty = 1; } /* If the in-memory part of the free-list is too large, write a new ** top-level containing just the in-memory free-list entries to disk. */ if( rc==LSM_OK && pDb->pWorker->freelist.nEntry > LSM_MAX_FREELIST_ENTRIES ){ int nPg = 0; while( rc==LSM_OK && sortedDbIsFull(pDb) ){ rc = sortedWork(pDb, 16, 0, 1, &nPg); nRem -= nPg; } if( rc==LSM_OK ){ rc = sortedNewToplevel(pDb, TREE_NONE, &nOvfl, &nPg); } nRem -= nPg; if( nPg ) bDirty = 1; } if( rc==LSM_OK && bDirty ){ lsmFinishWork(pDb, 0, 0, &rc); }else{ int rcdummy = LSM_BUSY; lsmFinishWork(pDb, 0, 0, &rcdummy); } assert( pDb->pWorker==0 ); if( rc==LSM_OK ){ if( pnWrite ) *pnWrite = (nMax - nRem); if( pbCkpt ) *pbCkpt = (bCkpt && nRem<=0); |
︙ | ︙ | |||
4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 | ); infoAppendBlob(&str, bHex, aKey, nKey); if( nVal>0 && bValues ){ lsmStringAppendf(&str, "%*s", nKeyWidth - (nKey*(1+bHex)), ""); lsmStringAppendf(&str, " "); infoAppendBlob(&str, bHex, aVal, nVal); } lsmStringAppendf(&str, "\n"); } if( bData ){ lsmStringAppendf(&str, "\n-------------------" "-------------------------------------------------------------\n"); lsmStringAppendf(&str, "Page %d\n", | > > > > > > > > > | 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 | ); infoAppendBlob(&str, bHex, aKey, nKey); if( nVal>0 && bValues ){ lsmStringAppendf(&str, "%*s", nKeyWidth - (nKey*(1+bHex)), ""); lsmStringAppendf(&str, " "); infoAppendBlob(&str, bHex, aVal, nVal); } if( rtTopic(eType) ){ int iBlk = (int)~lsmGetU32(aKey); lsmStringAppendf(&str, " (block=%d", iBlk); if( nVal>0 ){ i64 iSnap = lsmGetU64(aVal); lsmStringAppendf(&str, " snapshot=%lld", iSnap); } lsmStringAppendf(&str, ")"); } lsmStringAppendf(&str, "\n"); } if( bData ){ lsmStringAppendf(&str, "\n-------------------" "-------------------------------------------------------------\n"); lsmStringAppendf(&str, "Page %d\n", |
︙ | ︙ |