This is an automated email from the ASF dual-hosted git repository.
swuferhong pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fluss.git
The following commit(s) were added to refs/heads/main by this push:
new 6d3ba388e [server] Keep flushedLogOffset monotonic to fix row count
after failover (#3427)
6d3ba388e is described below
commit 6d3ba388e6c0f4a9d893a9f6d6ebdf45bfea5e30
Author: Daeuk Choi <[email protected]>
AuthorDate: Mon Jun 8 11:08:30 2026 +0900
[server] Keep flushedLogOffset monotonic to fix row count after failover
(#3427)
* [server] Keep flushedLogOffset monotonic to fix row count after failover
* add a ut test
---
.../java/org/apache/fluss/server/kv/KvTablet.java | 4 ++-
.../org/apache/fluss/server/kv/KvTabletTest.java | 35 ++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git
a/fluss-server/src/main/java/org/apache/fluss/server/kv/KvTablet.java
b/fluss-server/src/main/java/org/apache/fluss/server/kv/KvTablet.java
index f38019399..0683f5e05 100644
--- a/fluss-server/src/main/java/org/apache/fluss/server/kv/KvTablet.java
+++ b/fluss-server/src/main/java/org/apache/fluss/server/kv/KvTablet.java
@@ -687,7 +687,9 @@ public final class KvTablet {
} else {
try {
int rowCountDiff =
kvPreWriteBuffer.flush(exclusiveUpToLogOffset);
- flushedLogOffset = exclusiveUpToLogOffset;
+ if (exclusiveUpToLogOffset > flushedLogOffset) {
+ flushedLogOffset = exclusiveUpToLogOffset;
+ }
if (rowCount != ROW_COUNT_DISABLED) {
// row count is enabled, we update the row
count after flush.
long currentRowCount = rowCount;
diff --git
a/fluss-server/src/test/java/org/apache/fluss/server/kv/KvTabletTest.java
b/fluss-server/src/test/java/org/apache/fluss/server/kv/KvTabletTest.java
index d7ef34701..3425fa75c 100644
--- a/fluss-server/src/test/java/org/apache/fluss/server/kv/KvTabletTest.java
+++ b/fluss-server/src/test/java/org/apache/fluss/server/kv/KvTabletTest.java
@@ -59,6 +59,7 @@ import org.apache.fluss.server.kv.rocksdb.RocksDBStatistics;
import org.apache.fluss.server.kv.rowmerger.RowMerger;
import org.apache.fluss.server.kv.scan.OpenScanResult;
import org.apache.fluss.server.kv.scan.ScannerContext;
+import org.apache.fluss.server.kv.snapshot.TabletState;
import org.apache.fluss.server.log.FetchIsolation;
import org.apache.fluss.server.log.LogAppendInfo;
import org.apache.fluss.server.log.LogTablet;
@@ -1861,6 +1862,40 @@ class KvTabletTest {
kvTablet.close();
}
+ @Test
+ void testFlushDoesNotRegressFlushedLogOffset() throws Exception {
+ initLogTabletAndKvTablet(DATA1_SCHEMA_PK, new HashMap<>());
+
+ List<KvRecord> inserts = new ArrayList<>();
+ for (int i = 1; i <= 5; i++) {
+ inserts.add(kvRecordFactory.ofRecord("key" + i, new Object[] {i,
"val" + i}));
+ }
+ kvTablet.putAsLeader(kvRecordBatchFactory.ofRecords(inserts), null);
+
+ List<KvRecord> deletes = new ArrayList<>();
+ for (int i = 1; i <= 2; i++) {
+ deletes.add(kvRecordFactory.ofRecord("key" + i, null));
+ }
+ kvTablet.putAsLeader(kvRecordBatchFactory.ofRecords(deletes), null);
+
+ long highOffset = logTablet.localLogEndOffset();
+ kvTablet.flush(highOffset, NOPErrorHandler.INSTANCE);
+ TabletState stateAfterHighFlush = kvTablet.getTabletState();
+
assertThat(stateAfterHighFlush.getFlushedLogOffset()).isEqualTo(highOffset);
+ assertThat(stateAfterHighFlush.getRowCount()).isEqualTo(3L);
+ assertThat(kvTablet.getRowCount()).isEqualTo(3);
+
+ long lowOffset = highOffset - 2;
+ kvTablet.flush(lowOffset, NOPErrorHandler.INSTANCE);
+ TabletState stateAfterLowFlush = kvTablet.getTabletState();
+
+
assertThat(stateAfterLowFlush.getFlushedLogOffset()).isEqualTo(highOffset);
+ assertThat(stateAfterLowFlush.getRowCount()).isEqualTo(3L);
+ assertThat(kvTablet.getRowCount()).isEqualTo(3);
+
+ kvTablet.close();
+ }
+
@Test
void testOpenScan_emptyBucket_returnsNullContext() throws Exception {
initLogTabletAndKvTablet(DATA1_SCHEMA_PK, new HashMap<>());