From 6fdca7b55774a088d08a5fdd2652b2d5a8de4c6a Mon Sep 17 00:00:00 2001 From: w41ter Date: Mon, 9 Feb 2026 16:06:59 +0800 Subject: [PATCH 1/3] [feat](fe) add recovery_journal_id to truncate bdbje logs It only works for metadata_failure_recovery mode --- bin/start_fe.sh | 12 ++- .../main/java/org/apache/doris/DorisFE.java | 12 +++ .../org/apache/doris/common/FeConstants.java | 1 + .../doris/journal/bdbje/BDBEnvironment.java | 72 +++++++++++++++ .../doris/journal/bdbje/BDBJEJournal.java | 75 ++++++++++++++++ .../journal/bdbje/BDBEnvironmentTest.java | 66 ++++++++++++++ .../doris/journal/bdbje/BDBJEJournalTest.java | 87 +++++++++++++++++++ 7 files changed, 322 insertions(+), 3 deletions(-) diff --git a/bin/start_fe.sh b/bin/start_fe.sh index 39970defd6d885..2c7445f0fd7dee 100755 --- a/bin/start_fe.sh +++ b/bin/start_fe.sh @@ -33,6 +33,7 @@ OPTS="$(getopt \ -l 'image:' \ -l 'version' \ -l 'metadata_failure_recovery' \ + -l 'recovery_journal_id:' \ -l 'console' \ -l 'cluster_snapshot:' \ -- "$@")" @@ -46,6 +47,7 @@ IMAGE_PATH='' IMAGE_TOOL='' OPT_VERSION='' METADATA_FAILURE_RECOVERY='' +RECOVERY_JOURNAL_ID='' CLUSTER_SNAPSHOT='' while true; do case "$1" in @@ -65,6 +67,10 @@ while true; do METADATA_FAILURE_RECOVERY="-r" shift ;; + --recovery_journal_id) + RECOVERY_JOURNAL_ID="--recovery_journal_id $2" + shift 2 + ;; --helper) HELPER="$2" shift 2 @@ -418,12 +424,12 @@ if [[ "${IMAGE_TOOL}" -eq 1 ]]; then echo "Internal error, USE IMAGE_TOOL like: ./start_fe.sh --image image_path" fi elif [[ "${RUN_DAEMON}" -eq 1 ]]; then - nohup ${LIMIT:+${LIMIT}} "${JAVA}" ${final_java_opt:+${final_java_opt}} -XX:-OmitStackTraceInFastThrow -XX:OnOutOfMemoryError="kill -9 %p" ${coverage_opt:+${coverage_opt}} org.apache.doris.DorisFE ${HELPER:+${HELPER}} "${METADATA_FAILURE_RECOVERY}" "${CLUSTER_SNAPSHOT}" "$@" >>"${STDOUT_LOGGER}" 2>&1 >"${STDOUT_LOGGER}" 2>&1 >"${STDOUT_LOGGER}" 2>&1 >"${STDOUT_LOGGER}" 2>&1 dbNames = getDatabaseNames(); + if (dbNames == null || dbNames.isEmpty()) { + return; + } + + Long minJournalId = dbNames.get(0); + Long targetDbName = null; + for (Long dbName : dbNames) { + if (dbName <= truncateToJournalId) { + targetDbName = dbName; + } else { + break; + } + } + + if (targetDbName == null) { + throw new IllegalArgumentException("truncate journal id " + truncateToJournalId + + " is smaller than min journal id " + minJournalId); + } + + for (Long dbName : dbNames) { + if (dbName > truncateToJournalId) { + removeDatabase(dbName.toString()); + } + } + + long deletedCount = truncateTailInDb(targetDbName.toString(), truncateToJournalId); + LOG.info("truncate journals greater than {} finished, targetDb {}, deleted {} keys in target db", + truncateToJournalId, targetDbName, deletedCount); + } finally { + lock.writeLock().unlock(); + } + } + + private long truncateTailInDb(String dbName, long truncateToJournalId) { + Database db = openDatabase(dbName); + if (db == null) { + throw new IllegalStateException("failed to open target database " + dbName + " for truncate"); + } + + long deletedCount = 0; + TupleBinding idBinding = TupleBinding.getPrimitiveBinding(Long.class); + Cursor cursor = null; + try { + cursor = db.openCursor(null, null); + DatabaseEntry key = new DatabaseEntry(); + DatabaseEntry value = new DatabaseEntry(); + while (cursor.getNext(key, value, LockMode.READ_COMMITTED) == OperationStatus.SUCCESS) { + long journalId = idBinding.entryToObject(key); + if (journalId > truncateToJournalId) { + cursor.delete(); + deletedCount++; + } + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return deletedCount; + } + // get journal db names and sort the names public List getDatabaseNames() { // The operation before may set the current thread as interrupted. diff --git a/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBJEJournal.java b/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBJEJournal.java index 46c4c5f5517222..f4234cc462a172 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBJEJournal.java +++ b/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBJEJournal.java @@ -74,6 +74,7 @@ public class BDBJEJournal implements Journal { // CHECKSTYLE IGNORE THIS LINE: B public static final Logger LOG = LogManager.getLogger(BDBJEJournal.class); private static final int OUTPUT_BUFFER_INIT_SIZE = 128; private static final int RETRY_TIME = 3; + private static final long RECOVERY_JOURNAL_ID_UNSET = -1L; private String environmentPath = null; private String selfNodeName; @@ -519,6 +520,8 @@ public synchronized void open() { LOG.error("catch an exception when setup bdb environment. will exit.", e); System.exit(-1); } + + truncateRecoveryJournalsIfNeeded(metadataFailureRecovery); } // Open a new journal database or get last existing one as current journal @@ -593,6 +596,78 @@ private void reSetupBdbEnvironment(InsufficientLogException insufficientLogEx) { NetUtils.getHostPortInAccessibleFormat(helperNode.getHost(), helperNode.getPort())); } + private void truncateRecoveryJournalsIfNeeded(boolean metadataFailureRecovery) { + if (!metadataFailureRecovery) { + return; + } + + long recoveryJournalId = getRecoveryJournalIdOrUnset(); + if (recoveryJournalId == RECOVERY_JOURNAL_ID_UNSET) { + return; + } + + long maxJournalId = getMaxJournalIdWithoutCheck(); + if (maxJournalId < 0) { + String msg = String.format("invalid metadata recovery truncate target %d, no journals in bdb", + recoveryJournalId); + LOG.error(msg); + LogUtils.stderr(msg); + System.exit(-1); + } + + if (recoveryJournalId >= maxJournalId) { + String msg = String.format("metadata recovery truncate target %d >= max journal id %d, no-op", + recoveryJournalId, maxJournalId); + LOG.info(msg); + LogUtils.stdout(msg); + return; + } + + long minJournalId = getMinJournalId(); + if (minJournalId < 0 || recoveryJournalId < minJournalId) { + String msg = String.format("invalid metadata recovery truncate target %d, min journal id is %d", + recoveryJournalId, minJournalId); + LOG.error(msg); + LogUtils.stderr(msg); + System.exit(-1); + } + + try { + bdbEnvironment.truncateJournalsGreaterThan(recoveryJournalId); + } catch (Exception e) { + String msg = String.format("failed to truncate journals greater than %d in metadata recovery mode", + recoveryJournalId); + LOG.error(msg, e); + LogUtils.stderr(msg + ", reason: " + e.getMessage()); + System.exit(-1); + } + String msg = String.format("metadata recovery truncate finished, kept journals <= %d", recoveryJournalId); + LOG.info(msg); + LogUtils.stdout(msg); + } + + private long getRecoveryJournalIdOrUnset() { + String journalIdStr = System.getProperty(FeConstants.RECOVERY_JOURNAL_ID_KEY); + if (journalIdStr == null || journalIdStr.trim().isEmpty()) { + return RECOVERY_JOURNAL_ID_UNSET; + } + + String trimmedJournalId = journalIdStr.trim(); + try { + long journalId = Long.parseLong(trimmedJournalId); + if (journalId < 0) { + throw new NumberFormatException("recovery_journal_id must not be negative"); + } + return journalId; + } catch (NumberFormatException e) { + String msg = String.format("invalid recovery_journal_id: %s", trimmedJournalId); + LOG.error(msg, e); + LogUtils.stderr(msg); + System.exit(-1); + } + return RECOVERY_JOURNAL_ID_UNSET; + } + @Override public long getJournalNum() { return currentJournalDB.count(); diff --git a/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBEnvironmentTest.java b/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBEnvironmentTest.java index 68f01981a9aa43..d3836e145a202f 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBEnvironmentTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBEnvironmentTest.java @@ -26,6 +26,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.sleepycat.bind.tuple.TupleBinding; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseEntry; import com.sleepycat.je.Durability; @@ -124,6 +125,13 @@ private byte[] randomBytes() { return byteArray; } + private static DatabaseEntry longToEntry(long value) { + DatabaseEntry key = new DatabaseEntry(); + TupleBinding idBinding = TupleBinding.getPrimitiveBinding(Long.class); + idBinding.objectToEntry(value, key); + return key; + } + // @Test @RepeatedTest(1) public void testSetup() throws Exception { @@ -283,6 +291,64 @@ public void testOpenReplicatedEnvironmentTwice() throws Exception { bdbEnvironment.close(); } + @RepeatedTest(1) + public void testTruncateJournalsGreaterThan() throws Exception { + int port = findValidPort(); + String selfNodeName = Env.genFeNodeName("127.0.0.1", port, false); + String selfNodeHostPort = "127.0.0.1:" + port; + + File homeFile = new File(createTmpDir()); + BDBEnvironment bdbEnvironment = new BDBEnvironment(true, false); + bdbEnvironment.setup(homeFile, selfNodeName, selfNodeHostPort, selfNodeHostPort); + + Database db1 = bdbEnvironment.openDatabase("1"); + Database db11 = bdbEnvironment.openDatabase("11"); + Database db21 = bdbEnvironment.openDatabase("21"); + for (long i = 1; i <= 10; i++) { + Assertions.assertEquals(OperationStatus.SUCCESS, db1.put(null, longToEntry(i), new DatabaseEntry(randomBytes()))); + } + for (long i = 11; i <= 20; i++) { + Assertions.assertEquals(OperationStatus.SUCCESS, db11.put(null, longToEntry(i), new DatabaseEntry(randomBytes()))); + } + for (long i = 21; i <= 30; i++) { + Assertions.assertEquals(OperationStatus.SUCCESS, db21.put(null, longToEntry(i), new DatabaseEntry(randomBytes()))); + } + + bdbEnvironment.truncateJournalsGreaterThan(17); + + List dbNames = bdbEnvironment.getDatabaseNames(); + Assertions.assertEquals(2, dbNames.size()); + Assertions.assertEquals(1L, dbNames.get(0)); + Assertions.assertEquals(11L, dbNames.get(1)); + + Database db11AfterTruncate = bdbEnvironment.openDatabase("11"); + Assertions.assertEquals(7, db11AfterTruncate.count()); + Assertions.assertEquals(OperationStatus.NOTFOUND, + db11AfterTruncate.get(null, longToEntry(18), new DatabaseEntry(), LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, + db11AfterTruncate.get(null, longToEntry(17), new DatabaseEntry(), LockMode.READ_COMMITTED)); + bdbEnvironment.close(); + } + + @RepeatedTest(1) + public void testTruncateJournalsGreaterThanInvalidBound() throws Exception { + int port = findValidPort(); + String selfNodeName = Env.genFeNodeName("127.0.0.1", port, false); + String selfNodeHostPort = "127.0.0.1:" + port; + + File homeFile = new File(createTmpDir()); + BDBEnvironment bdbEnvironment = new BDBEnvironment(true, false); + bdbEnvironment.setup(homeFile, selfNodeName, selfNodeHostPort, selfNodeHostPort); + + Database db1 = bdbEnvironment.openDatabase("1"); + Assertions.assertEquals(OperationStatus.SUCCESS, db1.put(null, longToEntry(1), new DatabaseEntry(randomBytes()))); + + IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, + () -> bdbEnvironment.truncateJournalsGreaterThan(0)); + Assertions.assertTrue(exception.getMessage().contains("smaller than min journal id")); + bdbEnvironment.close(); + } + /** * Test build a BDBEnvironment cluster (1 master + 2 follower + 1 observer) * @throws Exception diff --git a/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBJEJournalTest.java b/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBJEJournalTest.java index 3b2c404e8e7941..bb263a426dffc1 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBJEJournalTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBJEJournalTest.java @@ -18,6 +18,7 @@ package org.apache.doris.journal.bdbje; import org.apache.doris.catalog.Env; +import org.apache.doris.common.FeConstants; import org.apache.doris.common.Pair; import org.apache.doris.common.io.Text; import org.apache.doris.common.io.Writable; @@ -226,6 +227,92 @@ public long getReplayedJournalId() { journal.close(); } + @RepeatedTest(1) + public void testRecoveryJournalIdNoEffectWithoutMetadataRecovery() throws Exception { + int port = findValidPort(); + Preconditions.checkArgument(((port > 0) && (port < 65535))); + String nodeName = Env.genFeNodeName("127.0.0.1", port, false); + long replayedJournalId = 0; + File tmpDir = createTmpDir(); + new MockUp() { + HostInfo selfNode = new HostInfo("127.0.0.1", port); + @Mock + public String getBdbDir() { + return tmpDir.getAbsolutePath(); + } + + @Mock + public HostInfo getSelfNode() { + return this.selfNode; + } + + @Mock + public HostInfo getHelperNode() { + return this.selfNode; + } + + @Mock + public boolean isElectable() { + return true; + } + + @Mock + public long getReplayedJournalId() { + return replayedJournalId; + } + }; + + String oldRecovery = System.getProperty(FeConstants.RECOVERY_JOURNAL_ID_KEY); + String oldMetadataRecovery = System.getProperty(FeConstants.METADATA_FAILURE_RECOVERY_KEY); + BDBJEJournal journal = new BDBJEJournal(nodeName); + try { + System.clearProperty(FeConstants.METADATA_FAILURE_RECOVERY_KEY); + System.setProperty(FeConstants.RECOVERY_JOURNAL_ID_KEY, "5"); + + journal.open(); + for (int i = 0; i < 10; i++) { + if (journal.getBDBEnvironment().getReplicatedEnvironment().getState() + .equals(ReplicatedEnvironment.State.MASTER)) { + break; + } + Thread.sleep(1000); + } + Assertions.assertEquals(ReplicatedEnvironment.State.MASTER, + journal.getBDBEnvironment().getReplicatedEnvironment().getState()); + for (int i = 0; i < 10; i++) { + journal.write(OperationType.OP_TIMESTAMP, new Timestamp()); + } + Assertions.assertEquals(10, journal.getMaxJournalId()); + journal.close(); + + journal.open(); + for (int i = 0; i < 10; i++) { + if (journal.getBDBEnvironment().getReplicatedEnvironment().getState() + .equals(ReplicatedEnvironment.State.MASTER)) { + break; + } + Thread.sleep(1000); + } + Assertions.assertEquals(ReplicatedEnvironment.State.MASTER, + journal.getBDBEnvironment().getReplicatedEnvironment().getState()); + Assertions.assertEquals(10, journal.getMaxJournalId()); + } finally { + if (journal.getBDBEnvironment() != null) { + journal.close(); + } + if (oldRecovery == null) { + System.clearProperty(FeConstants.RECOVERY_JOURNAL_ID_KEY); + } else { + System.setProperty(FeConstants.RECOVERY_JOURNAL_ID_KEY, oldRecovery); + } + if (oldMetadataRecovery == null) { + System.clearProperty(FeConstants.METADATA_FAILURE_RECOVERY_KEY); + } else { + System.setProperty(FeConstants.METADATA_FAILURE_RECOVERY_KEY, oldMetadataRecovery); + } + } + } + @RepeatedTest(1) public void testJournalBatch() throws Exception { int port = findValidPort(); From 52096211b3b16f5b8285a5c8284622a0bfd2abb6 Mon Sep 17 00:00:00 2001 From: w41ter Date: Fri, 13 Feb 2026 08:58:45 +0000 Subject: [PATCH 2/3] fixup --- .../journal/bdbje/BDBEnvironmentTest.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBEnvironmentTest.java b/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBEnvironmentTest.java index d3836e145a202f..b93766b3c9da7a 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBEnvironmentTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/journal/bdbje/BDBEnvironmentTest.java @@ -153,7 +153,7 @@ public void testSetup() throws Exception { Assertions.assertEquals(OperationStatus.SUCCESS, db.put(null, key, value)); DatabaseEntry readValue = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, db.get(null, key, readValue, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, db.get(null, key, readValue, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue.getData())); // Remove database @@ -174,7 +174,7 @@ public void testSetup() throws Exception { Database epochDb = bdbEnvironment.getEpochDB(); Assertions.assertEquals(OperationStatus.SUCCESS, epochDb.put(null, key, value)); DatabaseEntry readValue2 = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, epochDb.get(null, key, readValue2, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, epochDb.get(null, key, readValue2, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue2.getData())); new MockUp() { @@ -244,7 +244,7 @@ public void testMetadataRecovery() throws Exception { Assertions.assertEquals(OperationStatus.SUCCESS, db.put(null, key, value)); DatabaseEntry readValue = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, db.get(null, key, readValue, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, db.get(null, key, readValue, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue.getData())); bdbEnvironment.close(); @@ -254,7 +254,7 @@ public void testMetadataRecovery() throws Exception { Database db2 = bdbEnvironment2.openDatabase(dbName); DatabaseEntry readValue2 = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, db2.get(null, key, readValue2, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, db2.get(null, key, readValue2, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue2.getData())); bdbEnvironment2.close(); } @@ -278,7 +278,7 @@ public void testOpenReplicatedEnvironmentTwice() throws Exception { Assertions.assertEquals(OperationStatus.SUCCESS, db.put(null, key, value)); DatabaseEntry readValue = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, db.get(null, key, readValue, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, db.get(null, key, readValue, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue.getData())); bdbEnvironment.close(); @@ -286,7 +286,7 @@ public void testOpenReplicatedEnvironmentTwice() throws Exception { bdbEnvironment.openReplicatedEnvironment(homeFile); Database db2 = bdbEnvironment.openDatabase(dbName); DatabaseEntry readValue2 = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, db2.get(null, key, readValue2, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, db2.get(null, key, readValue2, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue2.getData())); bdbEnvironment.close(); } @@ -324,9 +324,9 @@ public void testTruncateJournalsGreaterThan() throws Exception { Database db11AfterTruncate = bdbEnvironment.openDatabase("11"); Assertions.assertEquals(7, db11AfterTruncate.count()); Assertions.assertEquals(OperationStatus.NOTFOUND, - db11AfterTruncate.get(null, longToEntry(18), new DatabaseEntry(), LockMode.READ_COMMITTED)); + db11AfterTruncate.get(null, longToEntry(18), new DatabaseEntry(), LockMode.DEFAULT)); Assertions.assertEquals(OperationStatus.SUCCESS, - db11AfterTruncate.get(null, longToEntry(17), new DatabaseEntry(), LockMode.READ_COMMITTED)); + db11AfterTruncate.get(null, longToEntry(17), new DatabaseEntry(), LockMode.DEFAULT)); bdbEnvironment.close(); } @@ -405,14 +405,14 @@ public void testCluster() throws Exception { Assertions.assertEquals(1, followerEnvironment.getDatabaseNames().size()); Database followerDb = followerEnvironment.openDatabase(dbName); DatabaseEntry readValue = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, followerDb.get(null, key, readValue, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, followerDb.get(null, key, readValue, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue.getData())); } Assertions.assertEquals(1, observerEnvironment.getDatabaseNames().size()); Database observerDb = observerEnvironment.openDatabase(dbName); DatabaseEntry readValue = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, observerDb.get(null, key, readValue, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, observerDb.get(null, key, readValue, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue.getData())); observerEnvironment.close(); @@ -519,7 +519,7 @@ public void testRollbackException() throws Exception { Assertions.assertEquals(1, entryPair.first.getDatabaseNames().size()); Database followerDb = entryPair.first.openDatabase(beginDbName); DatabaseEntry readValue = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, followerDb.get(null, key, readValue, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, followerDb.get(null, key, readValue, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue.getData())); followerDb.close(); } @@ -688,7 +688,7 @@ public void testReadTxnIsNotMatched() throws Exception { Assertions.assertEquals(1, entryPair.first.getDatabaseNames().size()); Database followerDb = entryPair.first.openDatabase(beginDbName); DatabaseEntry readValue = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, followerDb.get(null, key, readValue, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, followerDb.get(null, key, readValue, LockMode.DEFAULT)); Assertions.assertEquals(new String(value.getData()), new String(readValue.getData())); } @@ -737,6 +737,6 @@ public void testReadTxnIsNotMatched() throws Exception { key = new DatabaseEntry(new byte[]{1, 2, 3}); DatabaseEntry readValue = new DatabaseEntry(); - Assertions.assertEquals(OperationStatus.SUCCESS, masterDb.get(null, key, readValue, LockMode.READ_COMMITTED)); + Assertions.assertEquals(OperationStatus.SUCCESS, masterDb.get(null, key, readValue, LockMode.DEFAULT)); } } From 6c5eb0a4a328f70e2cb516b4cada457ee80e5d8f Mon Sep 17 00:00:00 2001 From: w41ter Date: Fri, 13 Feb 2026 09:09:20 +0000 Subject: [PATCH 3/3] fixu --- .../java/org/apache/doris/journal/bdbje/BDBEnvironment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBEnvironment.java b/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBEnvironment.java index e94889ecbf0c63..c49efa09151d9d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBEnvironment.java +++ b/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBEnvironment.java @@ -391,7 +391,7 @@ private long truncateTailInDb(String dbName, long truncateToJournalId) { cursor = db.openCursor(null, null); DatabaseEntry key = new DatabaseEntry(); DatabaseEntry value = new DatabaseEntry(); - while (cursor.getNext(key, value, LockMode.READ_COMMITTED) == OperationStatus.SUCCESS) { + while (cursor.getNext(key, value, LockMode.DEFAULT) == OperationStatus.SUCCESS) { long journalId = idBinding.entryToObject(key); if (journalId > truncateToJournalId) { cursor.delete();