Skip to content

Commit 76c5cc3

Browse files
committed
(fix) key not deleted in truncatePrefix
1 parent 08b5348 commit 76c5cc3

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

jraft-core/src/main/java/com/alipay/sofa/jraft/storage/impl/RocksDBLogStorage.java

+23-15
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import com.alipay.sofa.jraft.util.BytesUtil;
5757
import com.alipay.sofa.jraft.util.DebugStatistics;
5858
import com.alipay.sofa.jraft.util.Describer;
59+
import com.alipay.sofa.jraft.util.OnlyForTest;
5960
import com.alipay.sofa.jraft.util.Requires;
6061
import com.alipay.sofa.jraft.util.StorageOptionsFactory;
6162
import com.alipay.sofa.jraft.util.Utils;
@@ -435,18 +436,7 @@ public LogEntry getEntry(final long index) {
435436
if (this.hasLoadFirstLogIndex && index < this.firstLogIndex) {
436437
return null;
437438
}
438-
final byte[] keyBytes = getKeyBytes(index);
439-
final byte[] bs = onDataGet(index, getValueFromRocksDB(keyBytes));
440-
if (bs != null) {
441-
final LogEntry entry = this.logEntryDecoder.decode(bs);
442-
if (entry != null) {
443-
return entry;
444-
} else {
445-
LOG.error("Bad log entry format for index={}, the log data is: {}.", index, BytesUtil.toHex(bs));
446-
// invalid data remove? TODO
447-
return null;
448-
}
449-
}
439+
return getEntryFromDB(index);
450440
} catch (final RocksDBException | IOException e) {
451441
LOG.error("Fail to get log entry at index {} in data path: {}.", index, this.path, e);
452442
} finally {
@@ -455,6 +445,23 @@ public LogEntry getEntry(final long index) {
455445
return null;
456446
}
457447

448+
@OnlyForTest
449+
LogEntry getEntryFromDB(final long index) throws IOException, RocksDBException {
450+
final byte[] keyBytes = getKeyBytes(index);
451+
final byte[] bs = onDataGet(index, getValueFromRocksDB(keyBytes));
452+
if (bs != null) {
453+
final LogEntry entry = this.logEntryDecoder.decode(bs);
454+
if (entry != null) {
455+
return entry;
456+
} else {
457+
LOG.error("Bad log entry format for index={}, the log data is: {}.", index, BytesUtil.toHex(bs));
458+
// invalid data remove? TODO
459+
return null;
460+
}
461+
}
462+
return null;
463+
}
464+
458465
protected byte[] getValueFromRocksDB(final byte[] keyBytes) throws RocksDBException {
459466
checkState();
460467
return this.db.get(this.defaultHandle, keyBytes);
@@ -589,11 +596,12 @@ private void truncatePrefixInBackground(final long startIndex, final long firstI
589596
// Note https://github.com/facebook/rocksdb/wiki/Delete-A-Range-Of-Keys
590597
final byte[] startKey = getKeyBytes(startIndex);
591598
final byte[] endKey = getKeyBytes(firstIndexKept);
599+
// deleteFilesInRanges to speedup reclaiming disk space on write-heavy load.
592600
db.deleteFilesInRanges(this.defaultHandle, Arrays.asList(startKey, endKey), false);
593601
db.deleteFilesInRanges(this.confHandle, Arrays.asList(startKey, endKey), false);
594-
// After deleteFilesInrange, some keys in the range may still exist in the database, so we have to compactionRange.
595-
db.compactRange(this.defaultHandle, startKey, endKey);
596-
db.compactRange(this.confHandle, startKey, endKey);
602+
// deleteRange to delete all keys in range.
603+
db.deleteRange(this.defaultHandle, startKey, endKey);
604+
db.deleteRange(this.confHandle, startKey, endKey);
597605
} catch (final RocksDBException | IOException e) {
598606
LOG.error("Fail to truncatePrefix in data path: {}, firstIndexKept={}.", this.path, firstIndexKept, e);
599607
} finally {

jraft-core/src/test/java/com/alipay/sofa/jraft/storage/impl/BaseLogStorageTest.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -164,16 +164,20 @@ public void testReset() {
164164
}
165165

166166
@Test
167-
public void testTruncatePrefix() {
167+
public void testTruncatePrefix() throws Exception {
168168
final List<LogEntry> entries = TestUtils.mockEntries();
169169

170170
assertEquals(10, this.logStorage.appendEntries(entries));
171171
this.logStorage.truncatePrefix(5);
172+
Thread.sleep(1000);
172173
assertEquals(5, this.logStorage.getFirstLogIndex());
173174
assertEquals(9, this.logStorage.getLastLogIndex());
174175
for (int i = 0; i < 10; i++) {
175176
if (i < 5) {
176177
assertNull(this.logStorage.getEntry(i));
178+
if (this.logStorage instanceof RocksDBLogStorage) {
179+
assertNull(((RocksDBLogStorage) this.logStorage).getEntryFromDB(i));
180+
}
177181
} else {
178182
Assert.assertEquals(entries.get(i), this.logStorage.getEntry(i));
179183
}

0 commit comments

Comments
 (0)