Lost commit index when a snapshot is captured 21/83421/5
authorTomas Cere <tomas.cere@pantheon.tech>
Tue, 6 Aug 2019 11:46:32 +0000 (13:46 +0200)
committerRobert Varga <nite@hq.sk>
Mon, 16 Sep 2019 00:10:33 +0000 (00:10 +0000)
When we have no journals and a snapshot is recovered and
immediately captured again, if there was no movement in the
datastore we loose the lastIndex and term from the previous snapshot.
We can safely reuse these from the previous snapshot when no
entry is present in the ReplicatedLog.

Change-Id: Iaeb71edc7ec865bec18dbcb436af76e592eea69d
Signed-off-by: Tomas Cere <tomas.cere@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/SnapshotManager.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/SnapshotManagerTest.java

index e6dc8bb..7d9a1bb 100644 (file)
@@ -170,14 +170,19 @@ public class SnapshotManager implements SnapshotState {
 
         List<ReplicatedLogEntry> unAppliedEntries = context.getReplicatedLog().getFrom(lastAppliedIndex + 1);
 
-        long lastLogEntryIndex = lastAppliedIndex;
-        long lastLogEntryTerm = lastAppliedTerm;
-        if (lastLogEntry != null) {
+        final long lastLogEntryIndex;
+        final long lastLogEntryTerm;
+        if (lastLogEntry == null) {
+            // When we don't have journal present, for example two captureSnapshots executed right after another with no
+            // new journal we still want to preserve the index and term in the snapshot.
+            lastAppliedIndex = lastLogEntryIndex = context.getReplicatedLog().getSnapshotIndex();
+            lastAppliedTerm = lastLogEntryTerm = context.getReplicatedLog().getSnapshotTerm();
+
+            log.debug("{}: Capturing Snapshot : lastLogEntry is null. Using snapshot values lastAppliedIndex {} and "
+                    + "lastAppliedTerm {} instead.", persistenceId(), lastAppliedIndex, lastAppliedTerm);
+        } else {
             lastLogEntryIndex = lastLogEntry.getIndex();
             lastLogEntryTerm = lastLogEntry.getTerm();
-        } else {
-            log.debug("{}: Capturing Snapshot : lastLogEntry is null. Using lastAppliedIndex {} and "
-                    + "lastAppliedTerm {} instead.", persistenceId(), lastAppliedIndex, lastAppliedTerm);
         }
 
         return new CaptureSnapshot(lastLogEntryIndex, lastLogEntryTerm, lastAppliedIndex, lastAppliedTerm,
index 14b94d9..88e9a61 100644 (file)
@@ -194,12 +194,12 @@ public class SnapshotManagerTest extends AbstractActorTest {
         CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
 
         // LastIndex and LastTerm are picked up from the lastLogEntry
-        assertEquals(-1L, captureSnapshot.getLastIndex());
-        assertEquals(-1L, captureSnapshot.getLastTerm());
+        assertEquals(0, captureSnapshot.getLastIndex());
+        assertEquals(0, captureSnapshot.getLastTerm());
 
         // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
-        assertEquals(-1L, captureSnapshot.getLastAppliedIndex());
-        assertEquals(-1L, captureSnapshot.getLastAppliedTerm());
+        assertEquals(0, captureSnapshot.getLastAppliedIndex());
+        assertEquals(0, captureSnapshot.getLastAppliedTerm());
 
         //
         assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.