From 6a7ba0f5f5d34e85f0e408a5ead2f87e1ff28974 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 31 Oct 2023 09:29:24 +0800 Subject: [PATCH] fix(tsdb): handle the case where stt not exists, possibly exists while the stt-trigger is 1. --- source/dnode/vnode/src/tsdb/tsdbRead2.c | 53 +++++++++++++++++-------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead2.c b/source/dnode/vnode/src/tsdb/tsdbRead2.c index 12fe32df4c..abbc5b4715 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead2.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead2.c @@ -1196,9 +1196,25 @@ static bool overlapWithNeighborBlock2(SFileDataBlockInfo* pBlock, SBrinRecord* p } } -static bool bufferDataInFileBlockGap(int32_t order, TSDBKEY keyInBuf, SFileDataBlockInfo* pBlock, int64_t keyInStt) { +static int64_t getBoarderKeyInFiles(SFileDataBlockInfo* pBlock, SLastBlockReader* pLastBlockReader, int32_t order) { + bool ascScan = ASCENDING_TRAVERSE(order); + bool bHasDataInLastBlock = hasDataInLastBlock(pLastBlockReader); + + int64_t key = 0; + if (bHasDataInLastBlock) { + int64_t keyInStt = getCurrentKeyInLastBlock(pLastBlockReader); + key = ascScan ? MIN(pBlock->record.firstKey, keyInStt) : MAX(pBlock->record.lastKey, keyInStt); + } else { + key = ascScan ? pBlock->record.firstKey : pBlock->record.lastKey; + } + + return key; +} + +static bool bufferDataInFileBlockGap(TSDBKEY keyInBuf, SFileDataBlockInfo* pBlock, + SLastBlockReader* pLastBlockReader, int32_t order) { bool ascScan = ASCENDING_TRAVERSE(order); - int64_t key = ascScan? MIN(pBlock->record.firstKey, keyInStt):MAX(pBlock->record.lastKey, keyInStt); + int64_t key = getBoarderKeyInFiles(pBlock, pLastBlockReader, order); return (ascScan && (keyInBuf.ts != TSKEY_INITIAL_VAL && keyInBuf.ts < key)) || (!ascScan && (keyInBuf.ts != TSKEY_INITIAL_VAL && keyInBuf.ts > key)); @@ -2663,6 +2679,15 @@ static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) { } } +static bool notOverlapWithSttFiles(SFileDataBlockInfo* pBlockInfo, SLastBlockReader* pLastBlockReader, bool asc) { + if(!hasDataInLastBlock(pLastBlockReader)) { + return true; + } else { + int64_t keyInStt = getCurrentKeyInLastBlock(pLastBlockReader); + return (asc && pBlockInfo->record.lastKey < keyInStt) || (!asc && pBlockInfo->record.firstKey > keyInStt); + } +} + static int32_t doBuildDataBlock(STsdbReader* pReader) { int32_t code = TSDB_CODE_SUCCESS; @@ -2690,10 +2715,6 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) { initLastBlockReader(pLastBlockReader, pScanInfo, pReader); TSDBKEY keyInBuf = getCurrentKeyInBuf(pScanInfo, pReader); - bool bHasDataInLastBlock = hasDataInLastBlock(pLastBlockReader); - ASSERT(bHasDataInLastBlock); - - int64_t tsLast = getCurrentKeyInLastBlock(pLastBlockReader); if (fileBlockShouldLoad(pReader, pBlockInfo, pScanInfo, keyInBuf, pLastBlockReader)) { code = doLoadFileBlockData(pReader, pBlockIter, &pStatus->fileBlockData, pScanInfo->uid); if (code != TSDB_CODE_SUCCESS) { @@ -2702,14 +2723,13 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) { // build composed data block code = buildComposedDataBlock(pReader); - } else if (bufferDataInFileBlockGap(pReader->info.order, keyInBuf, pBlockInfo, tsLast)) { - // data in memory that are earlier than current file block + } else if (bufferDataInFileBlockGap(keyInBuf, pBlockInfo, pLastBlockReader, pReader->info.order)) { + // data in memory that are earlier than current file block and stt blocks // rows in buffer should be less than the file block in asc, greater than file block in desc - int64_t endKey = asc? MIN(pBlockInfo->record.firstKey, tsLast):MAX(pBlockInfo->record.lastKey, tsLast); + int64_t endKey = getBoarderKeyInFiles(pBlockInfo, pLastBlockReader, pReader->info.order); code = buildDataBlockFromBuf(pReader, pScanInfo, endKey); } else { - if (!bHasDataInLastBlock || - ((asc && pBlockInfo->record.lastKey < tsLast) || (!asc && pBlockInfo->record.firstKey > tsLast))) { + if (notOverlapWithSttFiles(pBlockInfo, pLastBlockReader, asc)) { // whole block is required, return it directly SDataBlockInfo* pInfo = &pReader->resBlockInfo.pResBlock->info; pInfo->rows = pBlockInfo->record.numRow; @@ -2720,7 +2740,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) { setBlockAllDumped(&pStatus->fBlockDumpInfo, pBlockInfo->record.lastKey, pReader->info.order); // update the last key for the corresponding table - pScanInfo->lastKey = ASCENDING_TRAVERSE(pReader->info.order) ? pInfo->window.ekey : pInfo->window.skey; + pScanInfo->lastKey = asc ? pInfo->window.ekey : pInfo->window.skey; tsdbDebug("%p uid:%" PRIu64 " clean file block retrieved from file, global index:%d, " "table index:%d, rows:%d, brange:%" PRId64 "-%" PRId64 ", %s", @@ -2747,10 +2767,11 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) { } // data in stt now overlaps with current active file data block, need to composed with file data block. - int64_t keyInStt = getCurrentKeyInLastBlock(pLastBlockReader); - if ((keyInStt >= pBlockInfo->record.firstKey && asc) || (keyInStt <= pBlockInfo->record.lastKey && (!asc))) { - tsdbDebug("%p keyInStt:%" PRId64 ", overlap with file block, brange:%" PRId64 "-%" PRId64 " %s", pReader, - keyInStt, pBlockInfo->record.firstKey, pBlockInfo->record.lastKey, pReader->idStr); + int64_t lastKeyInStt = getCurrentKeyInLastBlock(pLastBlockReader); + if ((lastKeyInStt >= pBlockInfo->record.firstKey && asc) || + (lastKeyInStt <= pBlockInfo->record.lastKey && (!asc))) { + tsdbDebug("%p lastKeyInStt:%" PRId64 ", overlap with file block, brange:%" PRId64 "-%" PRId64 " %s", pReader, + lastKeyInStt, pBlockInfo->record.firstKey, pBlockInfo->record.lastKey, pReader->idStr); break; } }