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:
Bomin Zhang 2025-04-03 13:28:09 +08:00 committed by GitHub
parent 337a4cebf1
commit a031d3ddd4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 57 additions and 111 deletions

View File

@ -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;

View File

@ -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,11 +1720,9 @@ 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
// TDB_BTREE_CURSOR ===================== // TDB_BTREE_CURSOR =====================

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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));