bitflicker64 commented on code in PR #3376:
URL: https://github.com/apache/hugegraph/pull/3376#discussion_r4326263396


##########
hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/store/RaftKVStore.java:
##########
@@ -329,6 +393,25 @@ private boolean isLeader() {
 
     @Override
     public boolean invoke(KVOperation op, KVStoreClosure response) throws 
PDException {
+        if (this.appliedBefore(op)) {
+            if (response != null) {
+                /*
+                 * Not a replay: this node proposed the entry in this run, and 
the log gave it
+                 * an index the store claims to hold already. The store and 
the log do not
+                 * match (a store restored without its log, or one written on 
the path
+                 * without raft by an older release); refused, since a skipped 
write would
+                 * answer success and write nothing.
+                 */
+                long last = KvTxnApplier.lastIndex(this.store);
+                String message = "Refused raft entry " + op.getIndex() + ": 
the store holds " +
+                                 "TXN index " + last + " already, so the store 
and the raft " +
+                                 "log do not match";
+                log.error(message);
+                
response.setError(Pdpb.Error.newBuilder().setType(Pdpb.ErrorType.UNKNOWN)
+                                            .setMessage(message).build());
+            }
+            return false;

Review Comment:
   Fixed in 8f29ffdd4. The skip is now limited to replays: `RaftEngine` records 
the log's last index
   when the node starts, and `RaftKVStore.appliedBefore` skips only an entry at 
or below it. A newer
   entry the store already claims makes `invoke` throw on every node, caller or 
not, and
   `RaftStateMachine.onApply` turns that into `setErrorAndRollback`: jraft 
stops the state machine,
   a leader steps down, the probes from #3358 report the error, and the node 
logs the entry, the
   stored index and the recovery (remove the data directory, rejoin from a 
snapshot) at error level.
   The earlier closure-error path is gone. Test 
`testStoreAheadOfTheLogFailsTheApply` covers a
   replay, a follower and the proposer path; the API reference says what each 
node does.
   



##########
hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/raft/KVOperation.java:
##########
@@ -49,6 +49,11 @@ public class KVOperation {
     public static final byte CLEAR = 0x07;
     public static final byte PUT_WITH_TTL_UNIT = 0x08;
     public static final byte REMOVE_WITH_TTL = 0x09;
+    /**
+     * Atomic multi-key write, the value holds a serialized kv.TxnEntry: the 
request with its
+     * keys encoded by the proposing node
+     */
+    public static final byte TXN = 0x0A;

Review Comment:
   Fixed in 8f29ffdd4. The leader proposes a TXN only once every other voter 
and learner of the
   configuration has answered its member probe (`GetMemberResponse`, new field 
`maxKvOp`) as a
   release that applies the entry. `TxnPeerGate` keeps that answer for the life 
of the process; a
   peer that never answered, or answered as an older release, blocks the TXN 
with
   `TXN_NOT_PROPOSED` naming it, a confirmed peer that is unreachable later 
does not block, and
   unconfirmed peers are probed again at most every 3 s and at once on a 
configuration change, so a
   node added to the group blocks until it answers. `TxnPeerGateTest` covers 
each rule; the API
   reference and the description's rollout note state them.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to