From 9277bb5f7986cb291a1c5e55da3b4b46b24642e0 Mon Sep 17 00:00:00 2001 From: wangyj1203 <128687001+wangyj1203@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:13:47 +0800 Subject: [PATCH 1/4] fix scan bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nextSlot+1后,scan到的slot可能是比nextSlot大,导致迭代到的第一个key可能是新slot的第一个key,该key的dbId大概率是0,导致其他dbId的数据只能scan到一个slot的数据 --- src/tendisplus/commands/scan.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tendisplus/commands/scan.cpp b/src/tendisplus/commands/scan.cpp index d5877431..560cc162 100644 --- a/src/tendisplus/commands/scan.cpp +++ b/src/tendisplus/commands/scan.cpp @@ -791,11 +791,11 @@ class ScanCommand : public Command { auto kvstoreSlots = getKvstoreSlots(kvstoreId, kvstoreCount, slots); auto cursor = txn->createDataCursor(); cursor->seek(lastScanRecordKey.encode()); + auto seekSlotId = lastScanRecordKey.getChunkId(); while (result.size() < count && *scanTimes < scanMaxTimes) { // get cursor current record and iterate next cursor auto expRecord = cursor->next(); - (*scanTimes)++; // ERR_EXHAUST means this kv-store has been iterated over if (expRecord.status().code() == ErrorCodes::ERR_EXHAUST) { @@ -828,7 +828,8 @@ class ScanCommand : public Command { auto recordSlotId = record.getRecordKey().getChunkId(); auto recordDbId = record.getRecordKey().getDbId(); auto recordType = record.getRecordKey().getRecordType(); - if (!kvstoreSlots.test(recordSlotId) || recordDbId != dbId || + auto isRecordValidSlotId = kvstoreSlots.test(recordSlotId); + if (!isRecordValidSlotId || recordDbId != dbId || recordType != RecordType::RT_DATA_META) { // seq: this key in DBID db's position // means, recordDbId == dbId && recordType == RT_DATA_META @@ -841,18 +842,23 @@ class ScanCommand : public Command { // recordType == RecordType::RT_DATA_META) { // (*seq)++; // } - auto nextSlot = getNextSlot(slots, recordSlotId); + int32_t nextSlot = recordSlotId; + if (!isRecordValidSlotId || recordSlotId == seekSlotId) { + nextSlot = getNextSlot(slots, recordSlotId); + } // nextSlot == -1 means this kv-store has been iterated over if (nextSlot == -1) { break; } // construct new record key to seek - auto nextRecordKey = genRecordKey(nextSlot, dbId, ""); + seekSlotId = nextSlot; + auto nextRecordKey = genRecordKey(seekSlotId, dbId, ""); cursor->seek(nextRecordKey.encode()); continue; } + (*scanTimes)++; /** * check if this record has expired * expired key shouldn't increase scanTimes, From b23af56ba934353127c8cbc957db33f64af074e3 Mon Sep 17 00:00:00 2001 From: wangyj1203 <128687001+wangyj1203@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:59:19 +0800 Subject: [PATCH 2/4] Update scan.cpp --- src/tendisplus/commands/scan.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tendisplus/commands/scan.cpp b/src/tendisplus/commands/scan.cpp index 560cc162..a3315d07 100644 --- a/src/tendisplus/commands/scan.cpp +++ b/src/tendisplus/commands/scan.cpp @@ -843,7 +843,8 @@ class ScanCommand : public Command { // (*seq)++; // } int32_t nextSlot = recordSlotId; - if (!isRecordValidSlotId || recordSlotId == seekSlotId) { + if (!isRecordValidSlotId || recordSlotId == seekSlotId || + rt2Char(recordType) > rt2Char(RecordType::RT_DATA_META)) { nextSlot = getNextSlot(slots, recordSlotId); } // nextSlot == -1 means this kv-store has been iterated over From 8e2b522331f424253a6d66bd73a95e8f84ea8b67 Mon Sep 17 00:00:00 2001 From: wangyj1203 <128687001+wangyj1203@users.noreply.github.com> Date: Wed, 28 Jan 2026 16:30:15 +0800 Subject: [PATCH 3/4] Update scan.cpp --- src/tendisplus/commands/scan.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tendisplus/commands/scan.cpp b/src/tendisplus/commands/scan.cpp index a3315d07..e8331ab1 100644 --- a/src/tendisplus/commands/scan.cpp +++ b/src/tendisplus/commands/scan.cpp @@ -844,7 +844,8 @@ class ScanCommand : public Command { // } int32_t nextSlot = recordSlotId; if (!isRecordValidSlotId || recordSlotId == seekSlotId || - rt2Char(recordType) > rt2Char(RecordType::RT_DATA_META)) { + rt2Char(recordType) > rt2Char(RecordType::RT_DATA_META) || + recordDbId > dbId) { nextSlot = getNextSlot(slots, recordSlotId); } // nextSlot == -1 means this kv-store has been iterated over From c98c1c911b4595e3e9963988a4cb13db9ec1f8cf Mon Sep 17 00:00:00 2001 From: wangyj1203 <128687001+wangyj1203@users.noreply.github.com> Date: Tue, 3 Feb 2026 18:27:20 +0800 Subject: [PATCH 4/4] Fix the code style in scan command --- src/tendisplus/commands/scan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tendisplus/commands/scan.cpp b/src/tendisplus/commands/scan.cpp index e8331ab1..762dd7df 100644 --- a/src/tendisplus/commands/scan.cpp +++ b/src/tendisplus/commands/scan.cpp @@ -843,7 +843,7 @@ class ScanCommand : public Command { // (*seq)++; // } int32_t nextSlot = recordSlotId; - if (!isRecordValidSlotId || recordSlotId == seekSlotId || + if (!isRecordValidSlotId || recordSlotId == seekSlotId || rt2Char(recordType) > rt2Char(RecordType::RT_DATA_META) || recordDbId > dbId) { nextSlot = getNextSlot(slots, recordSlotId);