提交 d16ee878 编写于 作者: H Hongze Cheng

finish fs

上级 607961b4
...@@ -25,7 +25,7 @@ extern "C" { ...@@ -25,7 +25,7 @@ extern "C" {
// ================== CURRENT file header info // ================== CURRENT file header info
typedef struct { typedef struct {
uint32_t version; // Current file version uint32_t version; // Current file version
uint32_t len; uint32_t len; // Encode content length (including checksum)
} SFSHeader; } SFSHeader;
// ================== TSDB File System Meta // ================== TSDB File System Meta
...@@ -38,6 +38,7 @@ typedef struct { ...@@ -38,6 +38,7 @@ typedef struct {
// ================== // ==================
typedef struct { typedef struct {
STsdbFSMeta meta; // FS meta STsdbFSMeta meta; // FS meta
SMFile* pmf; // meta file pointer
SMFile mf; // meta file SMFile mf; // meta file
SArray* df; // data file array SArray* df; // data file array
} SFSStatus; } SFSStatus;
...@@ -45,12 +46,10 @@ typedef struct { ...@@ -45,12 +46,10 @@ typedef struct {
typedef struct { typedef struct {
pthread_rwlock_t lock; pthread_rwlock_t lock;
SFSStatus* cstatus; // current stage SFSStatus* cstatus; // current status
SHashObj* metaCache; // meta SHashObj* metaCache; // meta cache
bool intxn; bool intxn;
SFSStatus* nstatus; SFSStatus* nstatus; // new status
SList* metaDelta;
} STsdbFS; } STsdbFS;
#define FS_CURRENT_STATUS(pfs) ((pfs)->cstatus) #define FS_CURRENT_STATUS(pfs) ((pfs)->cstatus)
...@@ -58,12 +57,17 @@ typedef struct { ...@@ -58,12 +57,17 @@ typedef struct {
#define FS_IN_TXN(pfs) (pfs)->intxn #define FS_IN_TXN(pfs) (pfs)->intxn
typedef struct { typedef struct {
int direction;
uint64_t version; // current FS version uint64_t version; // current FS version
int index; STsdbFS* pfs;
int fid; int index; // used to position next fset when version the same
int fid; // used to seek when version is changed
SDFileSet* pSet; SDFileSet* pSet;
} SFSIter; } SFSIter;
#define TSDB_FS_ITER_FORWARD TSDB_ORDER_ASC
#define TSDB_FS_ITER_BACKWARD TSDB_ORDER_DESC
#if 0 #if 0
int tsdbOpenFS(STsdbRepo* pRepo); int tsdbOpenFS(STsdbRepo* pRepo);
void tsdbCloseFS(STsdbRepo* pRepo); void tsdbCloseFS(STsdbRepo* pRepo);
......
...@@ -23,12 +23,14 @@ extern "C" { ...@@ -23,12 +23,14 @@ extern "C" {
#define TSDB_FILE_HEAD_SIZE 512 #define TSDB_FILE_HEAD_SIZE 512
#define TSDB_FILE_DELIMITER 0xF00AFA0F #define TSDB_FILE_DELIMITER 0xF00AFA0F
#define TSDB_FILE_INIT_MAGIC 0xFFFFFFFF #define TSDB_FILE_INIT_MAGIC 0xFFFFFFFF
#define TSDB_IVLD_FID INT_MIN
#define TSDB_FILE_INFO(tf) (&((tf)->info)) #define TSDB_FILE_INFO(tf) (&((tf)->info))
#define TSDB_FILE_F(tf) (&((tf)->f)) #define TSDB_FILE_F(tf) (&((tf)->f))
#define TSDB_FILE_FD(tf) ((tf)->fd) #define TSDB_FILE_FD(tf) ((tf)->fd)
#define TSDB_FILE_FULL_NAME(tf) TFILE_NAME(TSDB_FILE_F(tf)) #define TSDB_FILE_FULL_NAME(tf) TFILE_NAME(TSDB_FILE_F(tf))
#define TSDB_FILE_OPENED(tf) (TSDB_FILE_FD(tf) >= 0) #define TSDB_FILE_OPENED(tf) (TSDB_FILE_FD(tf) >= 0)
#define TSDB_FILE_CLOSED(tf) (!TSDB_FILE_OPENED(tf))
#define TSDB_FILE_SET_CLOSED(f) (TSDB_FILE_FD(f) = -1) #define TSDB_FILE_SET_CLOSED(f) (TSDB_FILE_FD(f) = -1)
#define TSDB_FILE_LEVEL(tf) TFILE_LEVEL(TSDB_FILE_F(tf)) #define TSDB_FILE_LEVEL(tf) TFILE_LEVEL(TSDB_FILE_F(tf))
#define TSDB_FILE_ID(tf) TFILE_ID(TSDB_FILE_F(tf)) #define TSDB_FILE_ID(tf) TFILE_ID(TSDB_FILE_F(tf))
...@@ -61,6 +63,7 @@ void tsdbInitMFile(SMFile* pMFile, SDiskID did, int vid, int ver); ...@@ -61,6 +63,7 @@ void tsdbInitMFile(SMFile* pMFile, SDiskID did, int vid, int ver);
void tsdbInitMFileEx(SMFile* pMFile, SMFile* pOMFile); void tsdbInitMFileEx(SMFile* pMFile, SMFile* pOMFile);
int tsdbEncodeSMFile(void** buf, SMFile* pMFile); int tsdbEncodeSMFile(void** buf, SMFile* pMFile);
void* tsdbDecodeSMFile(void* buf, SMFile* pMFile); void* tsdbDecodeSMFile(void* buf, SMFile* pMFile);
int tsdbApplyMFileChange(const SMFile* from, const SMFile* to);
static FORCE_INLINE int tsdbOpenMFile(SMFile* pMFile, int flags) { static FORCE_INLINE int tsdbOpenMFile(SMFile* pMFile, int flags) {
ASSERT(!TSDB_FILE_OPENED(pMFile)); ASSERT(!TSDB_FILE_OPENED(pMFile));
...@@ -288,6 +291,7 @@ void tsdbInitDFileSet(SDFileSet* pSet, SDiskID did, int vid, int fid, int ver); ...@@ -288,6 +291,7 @@ void tsdbInitDFileSet(SDFileSet* pSet, SDiskID did, int vid, int fid, int ver);
void tsdbInitDFileSetEx(SDFileSet* pSet, SDFileSet* pOSet); void tsdbInitDFileSetEx(SDFileSet* pSet, SDFileSet* pOSet);
int tsdbEncodeDFileSet(void** buf, SDFileSet* pSet); int tsdbEncodeDFileSet(void** buf, SDFileSet* pSet);
void* tsdbDecodeDFileSet(void* buf, SDFileSet* pSet); void* tsdbDecodeDFileSet(void* buf, SDFileSet* pSet);
int tsdbApplyDFileSetChange(const SDFileSet* from, const SDFileSet* to);
static FORCE_INLINE void tsdbCloseDFileSet(SDFileSet* pSet) { static FORCE_INLINE void tsdbCloseDFileSet(SDFileSet* pSet) {
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
*/ */
#include "tsdbint.h" #include "tsdbint.h"
#define TSDB_IVLD_FID INT_MIN
#define TSDB_MAX_SUBBLOCKS 8 #define TSDB_MAX_SUBBLOCKS 8
#define TSDB_KEY_FID(key, days, precision) ((key) / tsMsPerDay[(precision)] / (days)) #define TSDB_KEY_FID(key, days, precision) ((key) / tsMsPerDay[(precision)] / (days))
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include "tsdbint.h" #include "tsdbint.h"
#define TSDB_FS_CURRENT_FNAME "current"
#define TSDB_FS_TEMP_FNAME "current.t"
#define TSDB_MAX_FSETS(keep, days) ((keep) / (days) + 3) #define TSDB_MAX_FSETS(keep, days) ((keep) / (days) + 3)
// ================== CURRENT file header info // ================== CURRENT file header info
...@@ -27,9 +29,9 @@ static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) { ...@@ -27,9 +29,9 @@ static int tsdbEncodeFSHeader(void **buf, SFSHeader *pHeader) {
return tlen; return tlen;
} }
static void *tsdbEncodeFSHeader(void *buf, SFSHeader *pHeader) { static void *tsdbDecodeFSHeader(void *buf, SFSHeader *pHeader) {
buf = taosEncodeFixedU32(buf, &(pHeader->version)); buf = taosDecodeFixedU32(buf, &(pHeader->version));
buf = taosEncodeFixedU32(buf, &(pHeader->len)); buf = taosDecodeFixedU32(buf, &(pHeader->len));
return buf; return buf;
} }
...@@ -76,8 +78,6 @@ static int tsdbDecodeDFileSetArray(void *buf, SArray *pArray) { ...@@ -76,8 +78,6 @@ static int tsdbDecodeDFileSetArray(void *buf, SArray *pArray) {
buf = taosDecodeFixedU64(buf, &nset); buf = taosDecodeFixedU64(buf, &nset);
for (size_t i = 0; i < nset; i++) { for (size_t i = 0; i < nset; i++) {
SDFileSet *pSet = taosArrayGet(pArray, i);
buf = tsdbDecodeDFileSet(buf, &dset); buf = tsdbDecodeDFileSet(buf, &dset);
taosArrayPush(pArray, (void *)(&dset)); taosArrayPush(pArray, (void *)(&dset));
} }
...@@ -85,19 +85,22 @@ static int tsdbDecodeDFileSetArray(void *buf, SArray *pArray) { ...@@ -85,19 +85,22 @@ static int tsdbDecodeDFileSetArray(void *buf, SArray *pArray) {
} }
static int tsdbEncodeFSStatus(void **buf, SFSStatus *pStatus) { static int tsdbEncodeFSStatus(void **buf, SFSStatus *pStatus) {
ASSERT(pStatus->pmf);
int tlen = 0; int tlen = 0;
tlen += tsdbEncodeFSMeta(buf, &(pStatus->meta)); tlen += tsdbEncodeSMFile(buf, &(pStatus->pmf));
tlen += tsdbEncodeSMFile(buf, &(pStatus->mf));
tlen += tsdbEncodeDFileSetArray(buf, pStatus->df); tlen += tsdbEncodeDFileSetArray(buf, pStatus->df);
return tlen; return tlen;
} }
static void *tsdbDecodeFSStatus(void *buf, SFSStatus *pStatus) { static void *tsdbDecodeFSStatus(void *buf, SFSStatus *pStatus) {
buf = taosDecodeFixedU32(buf, pStatus->fsVer); tsdbResetFSStatus(pStatus);
buf = tsdbDecodeFSMeta(buf, &(pStatus->meta));
buf = tsdbDecodeSMFile(buf, &(pStatus->mf)); pStatus->pmf = &(pStatus->mf);
buf = tsdbDecodeSMFile(buf, pStatus->pmf);
buf = tsdbDecodeDFileSetArray(buf, pStatus->df); buf = tsdbDecodeDFileSetArray(buf, pStatus->df);
return buf; return buf;
...@@ -111,7 +114,7 @@ static SFSStatus *tsdbNewFSStatus(int maxFSet) { ...@@ -111,7 +114,7 @@ static SFSStatus *tsdbNewFSStatus(int maxFSet) {
} }
pStatus->df = taosArrayInit(maxFSet, sizeof(SDFileSet)); pStatus->df = taosArrayInit(maxFSet, sizeof(SDFileSet));
if (pStatus->df) { if (pStatus->df == NULL) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
free(pStatus); free(pStatus);
return NULL; return NULL;
...@@ -134,62 +137,79 @@ static void tsdbResetFSStatus(SFSStatus *pStatus) { ...@@ -134,62 +137,79 @@ static void tsdbResetFSStatus(SFSStatus *pStatus) {
return; return;
} }
pStatus->pmf = NULL;
taosArrayClear(pStatus->df); taosArrayClear(pStatus->df);
} }
static void tsdbSetStatusMFile(SFSStatus *pStatus, const SMFile *pMFile) {
ASSERT(pStatus->pmf == NULL && TSDB_FILE_CLOSED(pMFile));
pStatus->pmf = &(pStatus->mf);
*(pStatus->pmf) = *pMFile;
}
static int tsdbAddDFileSetToStatus(SFSStatus *pStatus, const SDFileSet *pSet) {
ASSERT(TSDB_FILE_CLOSED(&(pSet->files[0])));
ASSERT(TSDB_FILE_CLOSED(&(pSet->files[1])));
ASSERT(TSDB_FILE_CLOSED(&(pSet->files[2])));
if (taosArrayPush(pStatus->df, (void *)pStatus) == NULL) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
return -1;
}
return 0;
}
// ================== STsdbFS // ================== STsdbFS
STsdbFS *tsdbNewFS(int maxFSet) { STsdbFS *tsdbNewFS(int keep, int days) {
STsdbFS *pFs = (STsdbFS *)calloc(1, sizeof(*pFs)); int maxFSet = TSDB_MAX_FSETS(keep, days);
if (pFs == NULL) { STsdbFS *pfs;
pfs = (STsdbFS *)calloc(1, sizeof(*pfs));
if (pfs == NULL) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
return NULL; return NULL;
} }
int code = pthread_rwlock_init(&(pFs->lock), NULL); int code = pthread_rwlock_init(&(pfs->lock), NULL);
if (code) { if (code) {
terrno = TAOS_SYSTEM_ERROR(code); terrno = TAOS_SYSTEM_ERROR(code);
free(pFs); free(pfs);
return NULL; return NULL;
} }
pFs->cstatus = tsdbNewFSStatus(maxFSet); pfs->cstatus = tsdbNewFSStatus(maxFSet);
if (pFs->cstatus == NULL) { if (pfs->cstatus == NULL) {
tsdbFreeFS(pFs); tsdbFreeFS(pfs);
return NULL; return NULL;
} }
pFs->metaCache = taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); pfs->metaCache = taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
if (pFs->metaCache == NULL) { if (pfs->metaCache == NULL) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
tsdbFreeFS(pFs); tsdbFreeFS(pfs);
return NULL; return NULL;
} }
pFs->nstatus = tsdbNewFSStatus(maxFSet); pfs->nstatus = tsdbNewFSStatus(maxFSet);
if (pFs->nstatus == NULL) { if (pfs->nstatus == NULL) {
tsdbFreeFS(pFs); tsdbFreeFS(pfs);
return NULL; return NULL;
} }
pFs->metaDelta = tdListNew(sizeof(SKVRecord)); return pfs;
if (pFs->metaDelta == NULL) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
tsdbFreeFS(pFs);
return NULL;
}
return NULL;
} }
void *tsdbFreeFS(STsdbFS *pFs) { void *tsdbFreeFS(STsdbFS *pfs) {
if (pFs) { if (pfs) {
pFs->metaDelta = tdListFree(pFs->metaDelta); pfs->nstatus = tsdbFreeFSStatus(pfs->nstatus);
pFs->nstatus = tsdbFreeFSStatus(pFs->nstatus); taosHashCleanup(pfs->metaCache);
taosHashCleanup(pFs->metaCache); pfs->metaCache = NULL;
pFs->metaCache = NULL; pfs->cstatus = tsdbFreeFSStatus(pfs->cstatus);
pFs->cstatus = tsdbFreeFSStatus(pFs->cstatus); pthread_rwlock_destroy(&(pfs->lock));
pthread_rwlock_destroy(&(pFs->lock));
} }
return NULL; return NULL;
} }
...@@ -203,428 +223,271 @@ void tsdbCloseFS(STsdbFS *pFs) { ...@@ -203,428 +223,271 @@ void tsdbCloseFS(STsdbFS *pFs) {
// TODO // TODO
} }
int tsdbStartTxn(STsdbFS *pFs) { // Start a new transaction to modify the file system
tsdbResetFSStatus(pFs->nstatus); int tsdbStartTxn(STsdbFS *pfs) {
tdListEmpty(pFs->metaDelta); ASSERT(pfs->intxn == false);
return 0;
}
int tsdbEndTxn(STsdbFS *pFs, bool hasError) {
SFSStatus *pTStatus;
if (hasError) {
// TODO
} else {
// TODO 1. Create and open a new file current.t
// TODO 2. write new status to new file and fysnc and close pfs->intxn = true;
tsdbResetFSStatus(pfs->nstatus);
// TODO 3. rename current.t to current
// TODO 4. apply change to file
tsdbWLockFS(pFs);
pTStatus = pFs->cstatus;
pFs->cstatus = pFs->nstatus;
pFs->nstatus = pTStatus;
tsdbUnLockFS(pFs);
// TODO 5: apply meta change to cache
}
return 0; return 0;
} }
// ================== SFSIter int tsdbEndTxn(STsdbFS *pfs) {
void tsdbFSIterInit(STsdbFS *pFs, SFSIter *pIter) { ASSERT(FS_IN_TXN(pfs));
// TODO SFSStatus *pStatus;
}
SDFileSet *tsdbFSIterNext(STsdbFS *pFs) {
// TODO
return NULL;
}
#if 0
int tsdbOpenFS(STsdbRepo *pRepo) {
ASSERT(REPO_FS == NULL);
STsdbCfg *pCfg = TSDB_CFG(pRepo); // Write current file system snapshot
if (tsdbUpdateFS(pfs) < 0) {
// Create fs object tsdbEndTxnWithError(pfs);
REPO_FS(pRepo) = tsdbNewFS(pCfg->keep, pCfg->daysPerFile);
if (REPO_FS(pRepo) == NULL) {
tsdbError("vgId:%d failed to open TSDB FS since %s", REPO_ID(pRepo), tstrerror(terrno));
return -1; return -1;
} }
// Load TSDB file system from disk // Make new
if (tsdbOpenFSImpl(pRepo) < 0) { tsdbWLockFS(pfs);
tsdbError("vgId:%d failed to open TSDB FS since %s", REPO_ID(pRepo), tstrerror(terrno)); pStatus = pfs->cstatus;
tsdbCloseFS(pRepo); pfs->cstatus = pfs->nstatus;
return -1; pfs->nstatus = pStatus;
} tsdbUnLockFS(pfs);
return 0; // Apply actual change to each file and SDFileSet
} tsdbApplyFSChangeOnDisk(pfs);
void tsdbCloseFS(STsdbRepo *pRepo) { pfs->intxn = false;
REPO_FS(pRepo) = tsdbFreeFS(REPO_FS(pRepo));
return 0; return 0;
} }
// Start a new FS transaction int tsdbEndTxnWithError(STsdbFS *pfs) {
int tsdbFSNewTxn(STsdbRepo *pRepo) { // TODO
STsdbFS *pFs = REPO_FS(pRepo); pfs->intxn = false;
if (tsdbCopySnapshot(pFs->curr, pFs->new) < 0) {
return -1;
}
pFs->new->version++;
return 0; return 0;
} }
// End an existing FS transaction void tsdbUpdateMFile(STsdbFS *pfs, const SMFile *pMFile) { tsdbSetStatusMFile(pfs->nstatus, pMFile); }
int tsdbFSEndTxn(STsdbRepo *pRepo, bool hasError) {
STsdbFS *pFs = REPO_FS(pRepo);
if (hasError) { // roll back files int tsdbUpdateDFileSet(STsdbFS *pfs, const SDFileSet *pSet) { return tsdbAddDFileSetToStatus(pfs->nstatus, pSet); }
} else { // apply file change static int tsdbUpdateFS(STsdbFS *pfs) {
if (tsdbSaveFSSnapshot(-1, pFs->new) < 0) { ASSERT(FS_IN_TXN(pfs));
// TODO SFSHeader fsheader;
} void * pBuf = NULL;
void * ptr;
// rename(); char hbuf[TSDB_FILE_HEAD_SIZE] = "\0";
// apply all file changes
int fd = open(TSDB_FS_TEMP_FNAME, O_WRONLY | O_CREAT | O_TRUNC, 0755);
if (fd < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
} }
return 0; fsheader.version = TSDB_FS_VERSION;
} if (pfs->nstatus->pmf == NULL) {
ASSERT(taosArrayGetSize(pfs->nstatus->df) == 0);
fsheader.len = 0;
} else {
fsheader.len = tsdbEncodeFSHeader(NULL, pfs->nstatus) + sizeof(TSCKSUM);
}
int tsdbUpdateMFile(STsdbRepo *pRepo, SMFile *pMFile) { // Encode header part and write
STsdbFS *pFs = REPO_FS(pRepo); ptr = hbuf;
pFs->new->mf = *pMFile; tsdbEncodeFSHeader(&ptr, &fsheader);
return 0; tsdbEncodeFSMeta(&ptr, &(pfs->nstatus->meta));
}
int tsdbUpdateDFileSet(STsdbRepo *pRepo, SDFileSet *pSet) { taosCalcChecksumAppend(0, (uint8_t *)hbuf, TSDB_FILE_HEAD_SIZE);
SFSStatus *pSnapshot = REPO_FS(pRepo)->new;
SDFileSet * pOldSet;
pOldSet = tsdbSearchDFileSet(pSnapshot, pSet->id, TD_GE); if (taosWrite(fd, hbuf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
if (pOldSet == NULL) { terrno = TAOS_SYSTEM_ERROR(errno);
if (taosArrayPush(pSnapshot->df, pSet) == NULL) { close(fd);
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; remove(TSDB_FS_TEMP_FNAME);
return -1; return -1;
} }
} else {
int index = TARRAY_ELEM_IDX(pSnapshot->df, pOldSet);
if (pOldSet->id == pSet->id) { // Encode file status and write to file
taosArraySet(pSnapshot->df, index, pSet); if (fsheader.len > 0) {
} else if (pOldSet->id > pSet->id) { if (tsdbMakeRoom(&(pBuf), fsheader.len) < 0) {
if (taosArrayInsert(pSnapshot->df, index, pSet) == NULL) { close(fd);
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; remove(TSDB_FS_TEMP_FNAME);
return -1; return -1;
} }
} else {
ASSERT(0);
}
}
return 0; ptr = pBuf;
} tsdbEncodeFSStatus(&ptr, pfs->nstatus);
taosCalcChecksumAppend(0, (uint8_t *)pBuf, fsheader.len)
void tsdbRemoveExpiredDFileSet(STsdbRepo *pRepo, int mfid) { if (taosWrite(fd, pBuf, fsheader.len) < fsheader.len) {
SFSStatus *pSnapshot = REPO_FS(pRepo)->new; terrno = TAOS_SYSTEM_ERROR(errno);
while (taosArrayGetSize(pSnapshot->df) > 0) { close(fd);
SDFileSet *pSet = (SDFileSet *)taosArrayGet(pSnapshot->df, 0); remove(TSDB_FS_TEMP_FNAME);
if (pSet->id < mfid) { taosTZfree(pBuf);
taosArrayRemove(pSnapshot->df, 0); return -1;
} }
} }
}
SDFileSet tsdbMoveDFileSet(SDFileSet *pOldSet, int to) { // fsync, close and rename
// TODO if (fsync(fd) < 0) {
} terrno = TAOS_SYSTEM_ERROR(errno);
close(fd);
int tsdbInitFSIter(STsdbRepo *pRepo, SFSIter *pIter) { remove(TSDB_FS_TEMP_FNAME);
// TODO taosTZfree(pBuf);
return 0; return -1;
} }
SDFileSet *tsdbFSIterNext(SFSIter *pIter) { (void)close(fd);
// TODO (void)rename(TSDB_FS_TEMP_FNAME, TSDB_FS_CURRENT_FNAME);
return NULL; taosTZfree(pBuf);
}
static int tsdbSaveFSSnapshot(int fd, SFSStatus *pSnapshot) {
// TODO
return 0; return 0;
} }
static int tsdbLoadFSSnapshot(SFSStatus *pSnapshot) { static void tsdbApplyFSChangeOnDisk(SFSStatus *pFrom, SFSStatus *pTo) {
// TODO int ifrom = 0;
return 0; int ito = 0;
} size_t sizeFrom, sizeTo;
SDFileSet *pSetFrom;
SDFileSet *pSetTo;
static int tsdbOpenFSImpl(STsdbRepo *pRepo) { sizeFrom = taosArrayGetSize(pFrom->df);
char manifest[TSDB_FILENAME_LEN] = "\0"; sizeTo = taosArrayGetSize(pTo->df);
// TODO: use API here // Apply meta file change
sprintf(manifest, "%s/manifest", pRepo->rootDir); tsdbApplyMFileChange(pFrom->pmf, pTo->pmf);
if (access(manifest, F_OK) == 0) { // Apply SDFileSet change
// manifest file exist, just load if (ifrom >= sizeFrom) {
// TODO pSetFrom = NULL;
} else { } else {
// manifest file not exists, scan all the files and construct pSetFrom = taosArrayGet(pFrom->df, ifrom);
// TODO
}
return 0;
}
static int tsdbEncodeFSMeta(void **buf, STsdbFSMeta *pMeta) {
int tlen = 0;
tlen += taosEncodeVariantI64(buf, pMeta->fsversion);
tlen += taosEncodeVariantI64(buf, pMeta->version);
tlen += taosEncodeVariantI64(buf, pMeta->totalPoints);
tlen += taosEncodeVariantI64(buf, pMeta->totalStorage);
return tlen;
}
static void *tsdbDecodeFSMeta(void *buf, STsdbFSMeta *pMeta) {
buf = taosDecodeVariantI64(buf, &(pMeta->fsversion));
buf = taosDecodeVariantI64(buf, &(pMeta->version));
buf = taosDecodeVariantI64(buf, &(pMeta->totalPoints));
buf = taosDecodeVariantI64(buf, &(pMeta->totalStorage));
return buf;
}
static int tsdbEncodeFSSnapshot(void **buf, SFSStatus *pSnapshot) {
int tlen = 0;
int64_t size = 0;
// Encode meta file
tlen += tsdbEncodeMFile(buf, &(pSnapshot->mf));
// Encode data files
size = taosArrayGetSize(pSnapshot->df);
tlen += taosEncodeVariantI64(buf, size);
for (size_t index = 0; index < size; index++) {
SDFile *pFile = taosArrayGet(pSnapshot->df, index);
tlen += tsdbEncodeDFInfo(buf, &pFile);
} }
if (ito >= sizeTo) {
return tlen; pSetTo = NULL;
} } else {
pSetTo = taosArrayGet(pTo->df, ito);
static void *tsdbDecodeFSSnapshot(void *buf, SFSStatus *pSnapshot) {
int64_t size = 0;
SDFile df;
// Decode meta file
buf = tsdbDecodeMFile(buf, &(pSnapshot->mf));
// Decode data files
buf = taosDecodeVariantI64(buf, &size);
for (size_t index = 0; index < size; index++) {
buf = tsdbDecodeDFInfo(buf, &df);
taosArrayPush(pSnapshot->df, (void *)(&df));
} }
return buf; while (true) {
} if ((pSetTo == NULL) && (pSetFrom == NULL)) break;
static SFSStatus *tsdbNewSnapshot(int32_t nfiles) { if (pSetTo == NULL || (pSetFrom && pSetFrom->fid < pSetTo->fid)) {
SFSStatus *pSnapshot; tsdbApplyDFileSetChange(pSetFrom, NULL);
pSnapshot = (SFSStatus *)calloc(1, sizeof(pSnapshot)); ifrom++;
if (pSnapshot == NULL) { if (ifrom >= sizeFrom) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; pSetFrom = NULL;
return NULL; } else {
pSetFrom = taosArrayGet(pFrom->df, ifrom);
}
} else if (pSetFrom == NULL || pSetFrom->fid > pSetTo->fid) {
// Do nothing
if (pSetFrom) {
ito++;
if (ito >= sizeTo) {
pSetTo = NULL;
} else {
pSetTo = taosArrayGet(pTo->df, ito);
} }
pSnapshot->df = taosArrayInit(nfiles, sizeof(SDFileSet));
if (pSnapshot->df == NULL) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
free(pSnapshot);
return NULL;
} }
} else {
tsdbApplyDFileSetChange(pSetFrom, pSetTo);
return pSnapshot; ifrom++;
} if (ifrom >= sizeFrom) {
pSetFrom = NULL;
static SFSStatus *tsdbFreeSnapshot(SFSStatus *pSnapshot) { } else {
if (pSnapshot) { pSetFrom = taosArrayGet(pFrom->df, ifrom);
taosArrayDestroy(pSnapshot->df);
free(pSnapshot);
} }
return NULL; ito++;
} if (ito >= sizeTo) {
pSetTo = NULL;
static STsdbFS *tsdbNewFS(int32_t keep, int32_t days) { } else {
STsdbFS *pFs; pSetTo = taosArrayGet(pTo->df, ito);
int code;
int32_t nfiles;
pFs = (STsdbFS *)calloc(1, sizeof(*pFs));
if (pFs == NULL) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
return NULL;
} }
code = pthread_rwlock_init(&(pFs->lock));
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(code);
free(pFs);
return NULL;
} }
nfiles = TSDB_MAX_DFILES(keep, days);
if (((pFs->curr = tsdbNewSnapshot(nfiles)) == NULL) || ((pFs->new = tsdbNewSnapshot(nfiles)) == NULL)) {
tsdbFreeFS(pFs);
return NULL;
} }
return pFs;
} }
static STsdbFS *tsdbFreeFS(STsdbFS *pFs) { // ================== SFSIter
if (pFs) { // ASSUMPTIONS: the FS Should be read locked when calling these functions
pFs->new = tsdbFreeSnapshot(pFs->new); void tsdbFSIterInit(SFSIter *pIter, STsdbFS *pfs, int direction) {
pFs->curr = tsdbFreeSnapshot(pFs->curr); pIter->pfs = pfs;
pthread_rwlock_destroy(&(pFs->lock)); pIter->direction = direction;
free(pFs);
}
return NULL;
}
static int tsdbCopySnapshot(SFSStatus *src, SFSStatus *dst) { size_t size = taosArrayGetSize(pfs->cstatus->df);
dst->meta = src->meta;
dst->mf = src->meta;
taosArrayCopy(dst->df, src->df);
return 0;
}
static int tsdbCompFSetId(const void *key1, const void *key2) { pIter->version = pfs->cstatus->meta.version;
int id = *(int *)key1;
SDFileSet *pSet = (SDFileSet *)key2;
if (id < pSet->id) { if (size == 0) {
return -1; pIter->index = -1;
} else if (id == pSet->id) { pIter->fid = TSDB_IVLD_FID;
return 0; } else {
if (direction == TSDB_FS_ITER_FORWARD) {
pIter->index = 0;
} else { } else {
return 1; pIter->index = size - 1;
} }
}
static SDFileSet *tsdbSearchDFileSet(SFSStatus *pSnapshot, int fid, int flags) { pIter->fid = ((SDFileSet *)taosArrayGet(pfs->cstatus->df, pIter->index))->fid;
void *ptr = taosArraySearch(pSnapshot->df, (void *)(&fid), tsdbCompFSetId, flags); }
return (ptr == NULL) ? NULL : ((SDFileSet *)ptr);
} }
static int tsdbMakeFSChange(STsdbRepo *pRepo) { void tsdbFSIterSeek(SFSIter *pIter, int fid) {
tsdbMakeFSMFileChange(pRepo); STsdbFS *pfs = pIter->pfs;
tsdbMakeFSDFileChange(pRepo); size_t size = taosArrayGetSize(pfs->cstatus->df);
return 0;
}
static int tsdbMakeFSMFileChange(STsdbRepo *pRepo) { int flags;
STsdbFS *pFs = REPO_FS(pRepo); if (pIter->direction == TSDB_FS_ITER_FORWARD) {
SMFile * pDstMFile = &(pFs->curr->mf); flags = TD_GE;
SMFile * pSrcMFile = &(pFs->new->mf);
if (tfsIsSameFile(&(pDstMFile->f), &(pSrcMFile->f))) { // the same file
if (pDstMFile->info != pSrcMFile->info) {
if (pDstMFile->info.size > pDstMFile->info.size) {
// Commit succeed, do nothing
} else if (pDstMFile->info.size < pDstMFile->info.size) {
// Commit failed, back
// TODO
} else { } else {
ASSERT(0); flags = TD_LE;
}
} }
void *ptr = taosbsearch(&fid, pfs->cstatus->df->pData, size, sizeof(SDFileSet), , flags);
if (ptr == NULL) {
pIter->index = -1;
pIter->fid = TSDB_IVLD_FID;
} else { } else {
tfsremove(&(pSrcMFile->f)); pIter->index = TARRAY_ELEM_IDX(pfs->cstatus->df, ptr);
pIter->fid = ((SDFileSet *)ptr)->fid;
} }
return 0;
} }
static int tsdbMakeFSDFileChange(STsdbRepo *pRepo) { SDFileSet *tsdbFSIterNext(SFSIter *pIter) {
STsdbFS * pFs = REPO_FS(pRepo); STsdbFS * pfs = pIter->pfs;
int cidx = 0; SDFileSet *pSet;
int nidx = 0;
SDFileSet *pCSet = NULL;
SDFileSet *pNSet = NULL;
if (cidx < taosArrayGetSize(pFs->curr->df)) { if (pIter->index < 0) {
pCSet = taosArrayGet(pFs->curr->df, cidx); ASSERT(pIter->fid == TSDB_IVLD_FID);
} else { return NULL;
pCSet = NULL;
} }
if (nidx < taosArrayGetSize(pFs->new->df)) { ASSERT(pIter->fid != TSDB_IVLD_FID);
pNSet = taosArrayGet(pFs->new->df, nidx);
} else { if (pIter->version != pfs->cstatus->meta.version) {
pNSet = NULL; tsdbFSIterSeek(pIter, pIter->fid);
} }
while (true) { if (pIter->index < 0) {
if (pCSet == NULL && pNSet == NULL) break; return NULL;
}
if (pCSet == NULL || (pNSet != NULL && pCSet->id > pNSet->id)) { pSet = (SDFileSet *)taosArrayGet(pfs->cstatus->df, pIter->index);
tsdbRemoveDFileSet(pNSet); ASSERT(pSet->fid == pIter->fid);
nidx++; if (pIter->direction == TSDB_FS_ITER_FORWARD) {
if (nidx < taosArrayGetSize(pFs->new->df)) { pIter->index++;
pNSet = taosArrayGet(pFs->new->df, nidx); if (pIter->index >= taosArrayGetSize(pfs->cstatus->df)) {
} else { pIter->index = -1;
pNSet = NULL;
} }
} else if (pNSet == NULL || (pCSet != NULL && pCSet->id < pNSet->id)) {
cidx++;
if (cidx < taosArrayGetSize(pFs->curr->df)) {
pCSet = taosArrayGet(pFs->curr->df, cidx);
} else { } else {
pCSet = NULL; pIter->index--;
}
} else {
// TODO: apply dfileset change
nidx++;
if (nidx < taosArrayGetSize(pFs->new->df)) {
pNSet = taosArrayGet(pFs->new->df, nidx);
} else {
pNSet = NULL;
} }
cidx++; if (pIter->index > 0) {
if (cidx < taosArrayGetSize(pFs->curr->df)) { pIter->fid = ((SDFileSet *)taosArrayGet(pfs->cstatus->df, pIter->index))->fid;
pCSet = taosArrayGet(pFs->curr->df, cidx);
} else { } else {
pCSet = NULL; pIter->fid = TSDB_IVLD_FID;
}
}
} }
return 0; return pSet;
} }
\ No newline at end of file
#endif
\ No newline at end of file
...@@ -58,6 +58,48 @@ void *tsdbDecodeSMFile(void *buf, SMFile *pMFile) { ...@@ -58,6 +58,48 @@ void *tsdbDecodeSMFile(void *buf, SMFile *pMFile) {
return buf; return buf;
} }
int tsdbApplyMFileChange(SMFile *from, SMFile *to) {
ASSERT(from != NULL || to != NULL);
if (from != NULL) {
if (to == NULL) {
tsdbRemoveMFile(from);
} else {
if (tfsIsSameFile(TSDB_FILE_F(from), TSDB_FILE_F(to))) {
if (from->info.size > to->info.size) {
tsdbRollbackMFile(to);
}
} else {
tsdbRemoveMFile(from);
}
}
}
return 0;
}
static int tsdbRollBackMFile(const SMFile *pMFile) {
SMFile mf = *pMFile;
if (tsdbOpenMFile(&mf, O_WRONLY) < 0) {
return -1;
}
if (taosFtruncate(TSDB_FILE_FD(&mf), pMFile->info.size) < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
tsdbCloseMFile(&mf);
return -1;
}
if (tsdbUpdateMFileHeader(&mf) < 0) {
tsdbCloseMFile(&mf);
return -1;
}
tsdbCloseMFile(&mf);
return 0;
}
int tsdbCreateMFile(SMFile *pMFile) { int tsdbCreateMFile(SMFile *pMFile) {
ASSERT(pMFile->info.size == 0 && pMFile->info.magic == TSDB_FILE_INIT_MAGIC); ASSERT(pMFile->info.size == 0 && pMFile->info.magic == TSDB_FILE_INIT_MAGIC);
...@@ -220,6 +262,48 @@ static void *tsdbDecodeDFInfo(void *buf, SDFInfo *pInfo) { ...@@ -220,6 +262,48 @@ static void *tsdbDecodeDFInfo(void *buf, SDFInfo *pInfo) {
return buf; return buf;
} }
static int tsdbApplyDFileChange(SDFile *from, SDFile *to) {
ASSERT(from != NULL || to != NULL);
if (from != NULL) {
if (to == NULL) {
tsdbRemoveDFile(from);
} else {
if (tfsIsSameFile(TSDB_FILE_F(from), TSDB_FILE_F(to))) {
if (from->info.size > to->info.size) {
tsdbRollbackDFile(to);
}
} else {
tsdbRemoveDFile(from);
}
}
}
return 0;
}
static int tsdbRollBackDFile(const SDFile *pDFile) {
SDFile df = *pDFile;
if (tsdbOpenDFile(&df, O_WRONLY) < 0) {
return -1;
}
if (taosFtruncate(TSDB_FILE_FD(&df), pDFile->info.size) < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
tsdbCloseDFile(&df);
return -1;
}
if (tsdbUpdateDFileHeader(&df) < 0) {
tsdbCloseDFile(&df);
return -1;
}
tsdbCloseDFile(&df);
return 0;
}
// ============== Operations on SDFileSet // ============== Operations on SDFileSet
void tsdbInitDFileSet(SDFileSet *pSet, SDiskID did, int vid, int fid, uint32_t ver) { void tsdbInitDFileSet(SDFileSet *pSet, SDiskID did, int vid, int fid, uint32_t ver) {
pSet->fid = fid; pSet->fid = fid;
...@@ -254,6 +338,16 @@ void *tsdbDecodeDFileSet(void *buf, SDFileSet *pSet) { ...@@ -254,6 +338,16 @@ void *tsdbDecodeDFileSet(void *buf, SDFileSet *pSet) {
return buf; return buf;
} }
int tsdbApplyDFileSetChange(const SDFileSet *from, const SDFileSet *to) {
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
if (tsdbApplyDFileChange(TSDB_DFILE_IN_SET(from, ftype), TSDB_DFILE_IN_SET(to, ftype)) < 0) {
return -1;
}
}
return 0;
}
int tsdbCreateDFileSet(SDFileSet *pSet) { int tsdbCreateDFileSet(SDFileSet *pSet) {
for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) {
if (tsdbCreateDFile(TSDB_DFILE_IN_SET(pSet, ftype)) < 0) { if (tsdbCreateDFile(TSDB_DFILE_IN_SET(pSet, ftype)) < 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册