fix/journal: restore interrupted(abort, power failure, etc.) tdb txn
This commit is contained in:
parent
0efc892933
commit
25fdcac305
|
@ -56,14 +56,9 @@ typedef struct {
|
||||||
} SIntHdr;
|
} SIntHdr;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u8 flags;
|
|
||||||
SBTree *pBt;
|
|
||||||
} SBtreeInitPageArg;
|
|
||||||
|
|
||||||
static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2);
|
static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2);
|
||||||
static int tdbBtreeOpenImpl(SBTree *pBt);
|
static int tdbBtreeOpenImpl(SBTree *pBt);
|
||||||
static int tdbBtreeInitPage(SPage *pPage, void *arg, int init);
|
//static int tdbBtreeInitPage(SPage *pPage, void *arg, int init);
|
||||||
static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const void *pVal, int vLen, SCell *pCell,
|
static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const void *pVal, int vLen, SCell *pCell,
|
||||||
int *szCell, TXN *pTxn, SBTree *pBt);
|
int *szCell, TXN *pTxn, SBTree *pBt);
|
||||||
static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder, TXN *pTxn, SBTree *pBt);
|
static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder, TXN *pTxn, SBTree *pBt);
|
||||||
|
@ -348,7 +343,7 @@ static int tdbBtreeOpenImpl(SBTree *pBt) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tdbBtreeInitPage(SPage *pPage, void *arg, int init) {
|
int tdbBtreeInitPage(SPage *pPage, void *arg, int init) {
|
||||||
SBTree *pBt;
|
SBTree *pBt;
|
||||||
u8 flags;
|
u8 flags;
|
||||||
u8 leaf;
|
u8 leaf;
|
||||||
|
|
|
@ -424,4 +424,71 @@ static int tdbPagerWritePageToDB(SPager *pPager, SPage *pPage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tdbPagerRestore(SPager *pPager, SBTree *pBt) {
|
||||||
|
int ret = 0;
|
||||||
|
SPgno journalSize = 0;
|
||||||
|
u8 *pageBuf = NULL;
|
||||||
|
|
||||||
|
tdb_fd_t jfd = tdbOsOpen(pPager->jFileName, TDB_O_RDWR, 0755);
|
||||||
|
if (jfd < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tdbGetFileSize(jfd, pPager->pageSize, &journalSize);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pageBuf = tdbOsCalloc(1, pPager->pageSize);
|
||||||
|
if (pageBuf == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TXN txn;
|
||||||
|
tdbTxnOpen(&txn, 0, tdbDefaultMalloc, tdbDefaultFree, NULL, 0);
|
||||||
|
SBtreeInitPageArg iArg;
|
||||||
|
iArg.pBt = pBt;
|
||||||
|
iArg.flags = 0;
|
||||||
|
|
||||||
|
for (int pgIndex = 0; pgIndex < journalSize; ++pgIndex) {
|
||||||
|
// read pgno & the page from journal
|
||||||
|
SPgno pgno;
|
||||||
|
SPage *pPage;
|
||||||
|
|
||||||
|
int ret = tdbOsRead(jfd, &pgno, sizeof(pgno));
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tdbOsRead(jfd, pageBuf, pPager->pageSize);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tdbPagerFetchPage(pPager, &pgno, &pPage, tdbBtreeInitPage, &iArg, &txn);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the page to db
|
||||||
|
ret = tdbPagerWritePageToDB(pPager, pPage);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tdbPCacheRelease(pPager->pCache, pPage, &txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
tdbOsFSync(pPager->fd);
|
||||||
|
|
||||||
|
tdbTxnClose(&txn);
|
||||||
|
|
||||||
|
tdbOsFree(pageBuf);
|
||||||
|
|
||||||
|
tdbOsClose(jfd);
|
||||||
|
tdbOsRemove(pPager->jFileName);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -61,6 +61,11 @@ int tdbTbOpen(const char *tbname, int keyLen, int valLen, tdb_cmpr_fn_t keyCmprF
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = tdbPagerRestore(pPager, pTb->pBt);
|
||||||
|
if (ret < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
*ppTb = pTb;
|
*ppTb = pTb;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,4 +64,4 @@ int tdbGetFileSize(tdb_fd_t fd, int szPage, SPgno *size) {
|
||||||
|
|
||||||
*size = szBytes / szPage;
|
*size = szBytes / szPage;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,13 @@ int tdbBtreeUpsert(SBTree *pBt, const void *pKey, int nKey, const void *pData, i
|
||||||
int tdbBtreeGet(SBTree *pBt, const void *pKey, int kLen, void **ppVal, int *vLen);
|
int tdbBtreeGet(SBTree *pBt, const void *pKey, int kLen, void **ppVal, int *vLen);
|
||||||
int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkLen, void **ppVal, int *vLen);
|
int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkLen, void **ppVal, int *vLen);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 flags;
|
||||||
|
SBTree *pBt;
|
||||||
|
} SBtreeInitPageArg;
|
||||||
|
|
||||||
|
int tdbBtreeInitPage(SPage *pPage, void *arg, int init);
|
||||||
|
|
||||||
// SBTC
|
// SBTC
|
||||||
int tdbBtcOpen(SBTC *pBtc, SBTree *pBt, TXN *pTxn);
|
int tdbBtcOpen(SBTC *pBtc, SBTree *pBt, TXN *pTxn);
|
||||||
int tdbBtcClose(SBTC *pBtc);
|
int tdbBtcClose(SBTC *pBtc);
|
||||||
|
@ -185,6 +192,7 @@ int tdbPagerFetchPage(SPager *pPager, SPgno *ppgno, SPage **ppPage, int (*initP
|
||||||
TXN *pTxn);
|
TXN *pTxn);
|
||||||
void tdbPagerReturnPage(SPager *pPager, SPage *pPage, TXN *pTxn);
|
void tdbPagerReturnPage(SPager *pPager, SPage *pPage, TXN *pTxn);
|
||||||
int tdbPagerAllocPage(SPager *pPager, SPgno *ppgno);
|
int tdbPagerAllocPage(SPager *pPager, SPgno *ppgno);
|
||||||
|
int tdbPagerRestore(SPager *pPager, SBTree *pBt);
|
||||||
|
|
||||||
// tdbPCache.c ====================================
|
// tdbPCache.c ====================================
|
||||||
#define TDB_PCACHE_PAGE \
|
#define TDB_PCACHE_PAGE \
|
||||||
|
|
Loading…
Reference in New Issue