@@ -33,9 +33,9 @@ R5 2 4 4
33
33
If log 5 is committed by R1, and log 3 is not removed, R5 in future could become a new leader and overrides log
34
34
5 on R3.
35
35
36
- ### Caveat: deleting all entries after ` prev_log_id ` get committed log lost
36
+ ### Caveat: deleting all entries after ` prev_log_id ` will get committed log lost
37
37
38
- One of the mistake is to delete all entries after ` prev_log_id ` when a matching ` prev_log_id ` is found, e.g.:
38
+ One of the mistakes is to delete all entries after ` prev_log_id ` when a matching ` prev_log_id ` is found, e.g.:
39
39
```
40
40
fn handle_append_entries(req) {
41
41
if store.has(req.prev_log_id) {
@@ -95,23 +95,39 @@ Similar to append-entry:
95
95
- (1) If the logs contained in the snapshot matches logs that are stored on a
96
96
Follower/Learner, nothing is done.
97
97
98
- - (2) If the logs conflicts with the local logs, local conflicting logs will be
99
- deleted. And effective membership has to be reverted to some previous
100
- non-conflicting one.
98
+ - (2) If the logs conflicts with the local logs, ** ALL ** non-committed logs will be
99
+ deleted, because we do not know which logs conflict.
100
+ And effective membership has to be reverted to some previous non-conflicting one.
101
101
102
102
103
- ### Necessity to delete conflicting logs
103
+ ### Delete conflicting logs
104
104
105
- ** The ` (2) ` mentioned above is not necessary to do to achieve correctness.
106
- It is done only for clarity** .
107
-
108
- If the ` last_applied ` (` snapshot_meta.last_log_id ` ) conflict with the local log at ` last_applied.index ` ,
109
- It does ** NOT** need to delete the conflicting logs.
105
+ If ` snapshot_meta.last_log_id ` conflicts with the local log,
110
106
111
107
Because the node that has conflicting logs won't become a leader:
112
108
If this node can become a leader, according to raft spec, it has to contain all committed logs.
113
109
But the log entry at ` last_applied.index ` is not committed, thus it can never become a leader.
114
110
115
- But deleting conflicting logs make the state cleaner. :)
116
- This way method such as ` get_initial_state() ` does not need to deal with
117
- conditions such as that ` last_log_id ` can be smaller than ` last_applied ` .
111
+ But, it could become a leader when more logs are received.
112
+ At this time, the logs after ` snapshot_meta.last_log_id ` will all be cleaned.
113
+ The logs before or equal ` snapshot_meta.last_log_id ` will not be cleaned.
114
+
115
+ Then there is chance this node becomes leader and uses these log for replication.
116
+
117
+ #### Delete all non-committed
118
+
119
+ It just truncates ** ALL** non-committed logs here,
120
+ because ` snapshot_meta.last_log_id ` is committed, if the local log id conflicts
121
+ with ` snapshot_meta.last_log_id ` , there must be a quorum that contains ` snapshot_meta.last_log_id ` .
122
+ Thus, it is ** safe to remove all logs** on this node.
123
+
124
+ But removing committed logs leads to some trouble with membership management.
125
+ Thus, we just remove logs since ` committed+1 ` .
126
+
127
+ #### Not safe to clean conflicting logs after installing snapshot
128
+
129
+ It's not safe to remove the conflicting logs that are less than ` snap_last_log_id ` after installing
130
+ snapshot.
131
+
132
+ If the node crashes, dirty logs may remain there. These logs may be forwarded to other nodes if this nodes
133
+ becomes a leader.
0 commit comments