fix[TD-34340]: enable page recyling and ensure TDB cell size is at least the size of a free cell (#30606)
This commit is contained in:
parent
337a4cebf1
commit
a031d3ddd4
|
@ -121,6 +121,7 @@ static int32_t inline vnodeProposeMsg(SVnode *pVnode, SRpcMsg *pMsg, bool isWeak
|
||||||
bool wait = (code == 0 && vnodeIsMsgBlock(pMsg->msgType));
|
bool wait = (code == 0 && vnodeIsMsgBlock(pMsg->msgType));
|
||||||
if (wait) {
|
if (wait) {
|
||||||
if (pVnode->blocked) {
|
if (pVnode->blocked) {
|
||||||
|
(void)taosThreadMutexUnlock(&pVnode->lock);
|
||||||
return TSDB_CODE_INTERNAL_ERROR;
|
return TSDB_CODE_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
pVnode->blocked = true;
|
pVnode->blocked = true;
|
||||||
|
|
|
@ -181,12 +181,7 @@ void tdbBtreeClose(SBTree *pBt) {
|
||||||
|
|
||||||
int tdbBtreeInsert(SBTree *pBt, const void *pKey, int kLen, const void *pVal, int vLen, TXN *pTxn) {
|
int tdbBtreeInsert(SBTree *pBt, const void *pKey, int kLen, const void *pVal, int vLen, TXN *pTxn) {
|
||||||
SBTC btc;
|
SBTC btc;
|
||||||
SCell *pCell;
|
|
||||||
void *pBuf;
|
|
||||||
int szCell;
|
|
||||||
int szBuf;
|
|
||||||
int ret;
|
int ret;
|
||||||
int idx;
|
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
ret = tdbBtcOpen(&btc, pBt, pTxn);
|
ret = tdbBtcOpen(&btc, pBt, pTxn);
|
||||||
|
@ -1663,27 +1658,36 @@ static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell, int dropOfp, TXN *
|
||||||
vLen = pPage->vLen;
|
vLen = pPage->vLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nPayload = kLen + vLen;
|
int nSize = kLen + vLen + nHeader;
|
||||||
if (nHeader + nPayload <= pPage->maxLocal) {
|
if (nSize <= pPage->maxLocal) {
|
||||||
return nHeader + nPayload;
|
// cell size should be at least the size of a free cell, otherwise it
|
||||||
} else {
|
// cannot be added to the free list when dropped.
|
||||||
|
if (nSize < pPage->pPageMethods->szFreeCell) {
|
||||||
|
return pPage->pPageMethods->szFreeCell;
|
||||||
|
}
|
||||||
|
return nSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle overflow pages
|
||||||
int maxLocal = pPage->maxLocal;
|
int maxLocal = pPage->maxLocal;
|
||||||
|
|
||||||
// calc local storage size
|
// calc local storage size
|
||||||
int minLocal = pPage->minLocal;
|
int minLocal = pPage->minLocal;
|
||||||
int surplus = minLocal + (nPayload + nHeader - minLocal) % (maxLocal - sizeof(SPgno));
|
int surplus = minLocal + (nSize - minLocal) % (maxLocal - sizeof(SPgno));
|
||||||
int nLocal = surplus <= maxLocal ? surplus : minLocal;
|
int nLocal = surplus <= maxLocal ? surplus : minLocal;
|
||||||
|
|
||||||
|
if (!dropOfp) {
|
||||||
|
return nLocal;
|
||||||
|
}
|
||||||
|
|
||||||
// free ofp pages' cells
|
// free ofp pages' cells
|
||||||
if (dropOfp) {
|
|
||||||
int ret = 0;
|
|
||||||
SPgno pgno = *(SPgno *)(pCell + nLocal - sizeof(SPgno));
|
SPgno pgno = *(SPgno *)(pCell + nLocal - sizeof(SPgno));
|
||||||
int nLeft = nPayload - nLocal + sizeof(SPgno) + nHeader;
|
int nLeft = nSize - nLocal + sizeof(SPgno);
|
||||||
SPage *ofp;
|
|
||||||
int bytes;
|
|
||||||
|
|
||||||
while (pgno != 0) {
|
while (pgno != 0) {
|
||||||
ret = tdbLoadOvflPage(&pgno, &ofp, pTxn, pBt);
|
SPage *ofp;
|
||||||
|
int bytes;
|
||||||
|
int ret = tdbLoadOvflPage(&pgno, &ofp, pTxn, pBt);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1704,13 +1708,6 @@ static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell, int dropOfp, TXN *
|
||||||
tdbError("failed to write page since %s", terrstr());
|
tdbError("failed to write page since %s", terrstr());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
tdbPageDropCell(ofp, 0, pTxn, pBt);
|
|
||||||
*/
|
|
||||||
// SIntHdr *pIntHdr = (SIntHdr *)(ofp->pData);
|
|
||||||
// pIntHdr->flags = TDB_FLAG_ADD(0, TDB_BTREE_OVFL);
|
|
||||||
// pIntHdr->pgno = 0;
|
|
||||||
// ofp->pPager = NULL;
|
|
||||||
|
|
||||||
SArray *ofps = pPage->pPager->ofps;
|
SArray *ofps = pPage->pPager->ofps;
|
||||||
if (ofps) {
|
if (ofps) {
|
||||||
|
@ -1723,10 +1720,8 @@ static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell, int dropOfp, TXN *
|
||||||
|
|
||||||
nLeft -= bytes;
|
nLeft -= bytes;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nLocal;
|
return nLocal;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// TDB_BTREE_CELL
|
// TDB_BTREE_CELL
|
||||||
|
|
||||||
|
|
|
@ -491,8 +491,7 @@ static int tdbPageFree(SPage *pPage, int idx, SCell *pCell, int szCell) {
|
||||||
if (pCell == pPage->pFreeEnd) {
|
if (pCell == pPage->pFreeEnd) {
|
||||||
pPage->pFreeEnd += szCell;
|
pPage->pFreeEnd += szCell;
|
||||||
TDB_PAGE_CCELLS_SET(pPage, pPage->pFreeEnd - pPage->pData);
|
TDB_PAGE_CCELLS_SET(pPage, pPage->pFreeEnd - pPage->pData);
|
||||||
} else {
|
} else if (szCell >= TDB_PAGE_FREE_CELL_SIZE(pPage)) {
|
||||||
if (szCell >= TDB_PAGE_FREE_CELL_SIZE(pPage)) {
|
|
||||||
cellFree = TDB_PAGE_FCELL(pPage);
|
cellFree = TDB_PAGE_FCELL(pPage);
|
||||||
pPage->pPageMethods->setFreeCellInfo(pCell, szCell, cellFree);
|
pPage->pPageMethods->setFreeCellInfo(pCell, szCell, cellFree);
|
||||||
TDB_PAGE_FCELL_SET(pPage, pCell - pPage->pData);
|
TDB_PAGE_FCELL_SET(pPage, pCell - pPage->pData);
|
||||||
|
@ -500,7 +499,6 @@ static int tdbPageFree(SPage *pPage, int idx, SCell *pCell, int szCell) {
|
||||||
tdbError("tdb/page-free: invalid cell size: %d", szCell);
|
tdbError("tdb/page-free: invalid cell size: %d", szCell);
|
||||||
return TSDB_CODE_INVALID_PARA;
|
return TSDB_CODE_INVALID_PARA;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dest = pPage->pCellIdx + TDB_PAGE_OFFSET_SIZE(pPage) * idx;
|
dest = pPage->pCellIdx + TDB_PAGE_OFFSET_SIZE(pPage) * idx;
|
||||||
src = dest + TDB_PAGE_OFFSET_SIZE(pPage);
|
src = dest + TDB_PAGE_OFFSET_SIZE(pPage);
|
||||||
|
|
|
@ -746,50 +746,15 @@ int tdbPagerInsertFreePage(SPager *pPager, SPage *pPage, TXN *pTxn) {
|
||||||
int code = 0;
|
int code = 0;
|
||||||
SPgno pgno = TDB_PAGE_PGNO(pPage);
|
SPgno pgno = TDB_PAGE_PGNO(pPage);
|
||||||
|
|
||||||
#if ENABLE_PAGE_RECYLING
|
|
||||||
|
|
||||||
if (pPager->frps) {
|
|
||||||
if (taosArrayPush(pPager->frps, &pgno) == NULL) {
|
|
||||||
return terrno;
|
|
||||||
}
|
|
||||||
pPage->pPager = NULL;
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
pPager->frps = taosArrayInit(8, sizeof(SPgno));
|
|
||||||
if (pPager->frps == NULL) {
|
|
||||||
return terrno;
|
|
||||||
}
|
|
||||||
// memset(pPage->pData, 0, pPage->pageSize);
|
|
||||||
tdbTrace("tdb/insert-free-page: tbc recycle page: %d.", pgno);
|
tdbTrace("tdb/insert-free-page: tbc recycle page: %d.", pgno);
|
||||||
// printf("tdb/insert-free-page: tbc recycle page: %d.\n", pgno);
|
|
||||||
code = tdbTbInsert(pPager->pEnv->pFreeDb, &pgno, sizeof(pgno), NULL, 0, pTxn);
|
code = tdbTbInsert(pPager->pEnv->pFreeDb, &pgno, sizeof(pgno), NULL, 0, pTxn);
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
tdbError("tdb/insert-free-page: tb insert failed with ret: %d.", code);
|
tdbError("tdb/insert-free-page: tb insert failed with ret: %d.", code);
|
||||||
taosArrayDestroy(pPager->frps);
|
|
||||||
pPager->frps = NULL;
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (TARRAY_SIZE(pPager->frps) > 0) {
|
|
||||||
pgno = *(SPgno *)taosArrayPop(pPager->frps);
|
|
||||||
|
|
||||||
code = tdbTbInsert(pPager->pEnv->pFreeDb, &pgno, sizeof(pgno), NULL, 0, pTxn);
|
|
||||||
if (code < 0) {
|
|
||||||
tdbError("tdb/insert-free-page: tb insert failed with ret: %d.", code);
|
|
||||||
taosArrayDestroy(pPager->frps);
|
|
||||||
pPager->frps = NULL;
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
taosArrayDestroy(pPager->frps);
|
|
||||||
pPager->frps = NULL;
|
|
||||||
|
|
||||||
pPage->pPager = NULL;
|
pPage->pPager = NULL;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,10 +766,6 @@ static int tdbPagerRemoveFreePage(SPager *pPager, SPgno *pPgno, TXN *pTxn) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pPager->frps) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = tdbTbcOpen(pPager->pEnv->pFreeDb, &pCur, pTxn);
|
code = tdbTbcOpen(pPager->pEnv->pFreeDb, &pCur, pTxn);
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -843,11 +804,7 @@ static int tdbPagerRemoveFreePage(SPager *pPager, SPgno *pPgno, TXN *pTxn) {
|
||||||
|
|
||||||
static int tdbPagerAllocFreePage(SPager *pPager, SPgno *ppgno, TXN *pTxn) {
|
static int tdbPagerAllocFreePage(SPager *pPager, SPgno *ppgno, TXN *pTxn) {
|
||||||
// Allocate a page from the free list
|
// Allocate a page from the free list
|
||||||
#if ENABLE_PAGE_RECYLING
|
|
||||||
return tdbPagerRemoveFreePage(pPager, ppgno, pTxn);
|
return tdbPagerRemoveFreePage(pPager, ppgno, pTxn);
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tdbPagerAllocNewPage(SPager *pPager, SPgno *ppgno) {
|
static int tdbPagerAllocNewPage(SPager *pPager, SPgno *ppgno) {
|
||||||
|
|
|
@ -402,7 +402,6 @@ struct SPager {
|
||||||
// u8 inTran;
|
// u8 inTran;
|
||||||
TXN *pActiveTxn;
|
TXN *pActiveTxn;
|
||||||
SArray *ofps;
|
SArray *ofps;
|
||||||
SArray *frps;
|
|
||||||
SPager *pNext; // used by TDB
|
SPager *pNext; // used by TDB
|
||||||
SPager *pHashNext; // used by TDB
|
SPager *pHashNext; // used by TDB
|
||||||
#ifdef USE_MAINDB
|
#ifdef USE_MAINDB
|
||||||
|
|
|
@ -52,7 +52,6 @@ typedef int32_t FileFd;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
typedef struct TdFile {
|
typedef struct TdFile {
|
||||||
TdThreadRwlock rwlock;
|
TdThreadRwlock rwlock;
|
||||||
int refId;
|
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int32_t tdFileOptions;
|
int32_t tdFileOptions;
|
||||||
|
@ -60,7 +59,6 @@ typedef struct TdFile {
|
||||||
#else
|
#else
|
||||||
typedef struct TdFile {
|
typedef struct TdFile {
|
||||||
TdThreadRwlock rwlock;
|
TdThreadRwlock rwlock;
|
||||||
int refId;
|
|
||||||
FileFd fd;
|
FileFd fd;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
} TdFile;
|
} TdFile;
|
||||||
|
@ -1196,7 +1194,6 @@ TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
||||||
(void)taosThreadRwlockInit(&(pFile->rwlock), NULL);
|
(void)taosThreadRwlockInit(&(pFile->rwlock), NULL);
|
||||||
#endif
|
#endif
|
||||||
pFile->fp = fp;
|
pFile->fp = fp;
|
||||||
pFile->refId = 0;
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
pFile->hFile = hFile;
|
pFile->hFile = hFile;
|
||||||
|
@ -1252,7 +1249,6 @@ int32_t taosCloseFile(TdFilePtr *ppFile) {
|
||||||
(*ppFile)->fd = -1;
|
(*ppFile)->fd = -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
(*ppFile)->refId = 0;
|
|
||||||
#if FILE_WITH_LOCK
|
#if FILE_WITH_LOCK
|
||||||
(void)taosThreadRwlockUnlock(&((*ppFile)->rwlock));
|
(void)taosThreadRwlockUnlock(&((*ppFile)->rwlock));
|
||||||
(void)taosThreadRwlockDestroy(&((*ppFile)->rwlock));
|
(void)taosThreadRwlockDestroy(&((*ppFile)->rwlock));
|
||||||
|
|
Loading…
Reference in New Issue