diff --git a/raft/raft.go b/raft/raft.go index 52b4192c8..66048c789 100644 --- a/raft/raft.go +++ b/raft/raft.go @@ -565,6 +565,7 @@ func (r *raft) advance(rd Ready) { if !r.appendEntry(ent) { panic("refused un-refusable auto-leaving ConfChangeV2") } + r.bcastAppend() r.pendingConfIndex = r.raftLog.lastIndex() r.logger.Infof("initiating automatic transition out of joint configuration %s", r.prs.Config) } diff --git a/raft/testdata/confchange_v2_add_double_auto.txt b/raft/testdata/confchange_v2_add_double_auto.txt index 2419083f0..0979bdd6a 100644 --- a/raft/testdata/confchange_v2_add_double_auto.txt +++ b/raft/testdata/confchange_v2_add_double_auto.txt @@ -282,6 +282,9 @@ stabilize 1 Ready MustSync=true: Entries: 1/9 EntryConfChangeV2 + Messages: + 1->2 MsgApp Term:1 Log:1/8 Commit:6 Entries:[1/9 EntryConfChangeV2] + 1->3 MsgApp Term:1 Log:1/8 Commit:6 Entries:[1/9 EntryConfChangeV2] # n2 and n3 also switch to the joint config, and ack the transition out of it. stabilize 2 3 @@ -290,22 +293,26 @@ stabilize 2 3 1->2 MsgApp Term:1 Log:1/6 Commit:5 Entries:[1/7 EntryNormal "foo"] 1->2 MsgApp Term:1 Log:1/7 Commit:5 Entries:[1/8 EntryNormal "bar"] 1->2 MsgApp Term:1 Log:1/8 Commit:6 + 1->2 MsgApp Term:1 Log:1/8 Commit:6 Entries:[1/9 EntryConfChangeV2] > 3 receiving messages 1->3 MsgApp Term:1 Log:1/6 Commit:5 Entries:[1/7 EntryNormal "foo"] 1->3 MsgApp Term:1 Log:1/7 Commit:5 Entries:[1/8 EntryNormal "bar"] 1->3 MsgApp Term:1 Log:1/8 Commit:6 + 1->3 MsgApp Term:1 Log:1/8 Commit:6 Entries:[1/9 EntryConfChangeV2] > 2 handling Ready Ready MustSync=true: HardState Term:1 Commit:6 Entries: 1/7 EntryNormal "foo" 1/8 EntryNormal "bar" + 1/9 EntryConfChangeV2 CommittedEntries: 1/6 EntryConfChangeV2 r2 r3 Messages: 2->1 MsgAppResp Term:1 Log:0/7 2->1 MsgAppResp Term:1 Log:0/8 2->1 MsgAppResp Term:1 Log:0/8 + 2->1 MsgAppResp Term:1 Log:0/9 INFO 2 switched to configuration voters=(1)&&(1 2 3) autoleave > 3 handling Ready Ready MustSync=true: @@ -313,12 +320,14 @@ stabilize 2 3 Entries: 1/7 EntryNormal "foo" 1/8 EntryNormal "bar" + 1/9 EntryConfChangeV2 CommittedEntries: 1/6 EntryConfChangeV2 r2 r3 Messages: 3->1 MsgAppResp Term:1 Log:0/7 3->1 MsgAppResp Term:1 Log:0/8 3->1 MsgAppResp Term:1 Log:0/8 + 3->1 MsgAppResp Term:1 Log:0/9 INFO 3 switched to configuration voters=(1)&&(1 2 3) autoleave # n2 and n3 also leave the joint config and the dust settles. We see at the very @@ -330,84 +339,68 @@ stabilize 2->1 MsgAppResp Term:1 Log:0/7 2->1 MsgAppResp Term:1 Log:0/8 2->1 MsgAppResp Term:1 Log:0/8 + 2->1 MsgAppResp Term:1 Log:0/9 3->1 MsgAppResp Term:1 Log:0/7 3->1 MsgAppResp Term:1 Log:0/8 3->1 MsgAppResp Term:1 Log:0/8 -> 1 handling Ready - Ready MustSync=false: - HardState Term:1 Vote:1 Commit:8 - CommittedEntries: - 1/7 EntryNormal "foo" - 1/8 EntryNormal "bar" - Messages: - 1->2 MsgApp Term:1 Log:1/8 Commit:7 Entries:[1/9 EntryConfChangeV2] - 1->3 MsgApp Term:1 Log:1/8 Commit:7 Entries:[1/9 EntryConfChangeV2] - 1->2 MsgApp Term:1 Log:1/9 Commit:8 - 1->3 MsgApp Term:1 Log:1/9 Commit:8 -> 2 receiving messages - 1->2 MsgApp Term:1 Log:1/8 Commit:7 Entries:[1/9 EntryConfChangeV2] - 1->2 MsgApp Term:1 Log:1/9 Commit:8 -> 3 receiving messages - 1->3 MsgApp Term:1 Log:1/8 Commit:7 Entries:[1/9 EntryConfChangeV2] - 1->3 MsgApp Term:1 Log:1/9 Commit:8 -> 2 handling Ready - Ready MustSync=true: - HardState Term:1 Commit:8 - Entries: - 1/9 EntryConfChangeV2 - CommittedEntries: - 1/7 EntryNormal "foo" - 1/8 EntryNormal "bar" - Messages: - 2->1 MsgAppResp Term:1 Log:0/9 - 2->1 MsgAppResp Term:1 Log:0/9 -> 3 handling Ready - Ready MustSync=true: - HardState Term:1 Commit:8 - Entries: - 1/9 EntryConfChangeV2 - CommittedEntries: - 1/7 EntryNormal "foo" - 1/8 EntryNormal "bar" - Messages: - 3->1 MsgAppResp Term:1 Log:0/9 - 3->1 MsgAppResp Term:1 Log:0/9 -> 1 receiving messages - 2->1 MsgAppResp Term:1 Log:0/9 - 2->1 MsgAppResp Term:1 Log:0/9 - 3->1 MsgAppResp Term:1 Log:0/9 3->1 MsgAppResp Term:1 Log:0/9 > 1 handling Ready Ready MustSync=false: HardState Term:1 Vote:1 Commit:9 CommittedEntries: + 1/7 EntryNormal "foo" + 1/8 EntryNormal "bar" 1/9 EntryConfChangeV2 Messages: + 1->2 MsgApp Term:1 Log:1/9 Commit:7 + 1->3 MsgApp Term:1 Log:1/9 Commit:7 + 1->2 MsgApp Term:1 Log:1/9 Commit:8 + 1->3 MsgApp Term:1 Log:1/9 Commit:8 1->2 MsgApp Term:1 Log:1/9 Commit:9 1->3 MsgApp Term:1 Log:1/9 Commit:9 INFO 1 switched to configuration voters=(1) > 2 receiving messages + 1->2 MsgApp Term:1 Log:1/9 Commit:7 + 1->2 MsgApp Term:1 Log:1/9 Commit:8 1->2 MsgApp Term:1 Log:1/9 Commit:9 > 3 receiving messages + 1->3 MsgApp Term:1 Log:1/9 Commit:7 + 1->3 MsgApp Term:1 Log:1/9 Commit:8 1->3 MsgApp Term:1 Log:1/9 Commit:9 > 2 handling Ready Ready MustSync=false: HardState Term:1 Commit:9 CommittedEntries: + 1/7 EntryNormal "foo" + 1/8 EntryNormal "bar" 1/9 EntryConfChangeV2 Messages: 2->1 MsgAppResp Term:1 Log:0/9 + 2->1 MsgAppResp Term:1 Log:0/9 + 2->1 MsgAppResp Term:1 Log:0/9 INFO 2 switched to configuration voters=(1) > 3 handling Ready Ready MustSync=false: HardState Term:1 Commit:9 CommittedEntries: + 1/7 EntryNormal "foo" + 1/8 EntryNormal "bar" 1/9 EntryConfChangeV2 Messages: 3->1 MsgAppResp Term:1 Log:0/9 + 3->1 MsgAppResp Term:1 Log:0/9 + 3->1 MsgAppResp Term:1 Log:0/9 INFO 3 switched to configuration voters=(1) > 1 receiving messages + 2->1 MsgAppResp Term:1 Log:0/9 + raft: cannot step as peer not found + 2->1 MsgAppResp Term:1 Log:0/9 + raft: cannot step as peer not found 2->1 MsgAppResp Term:1 Log:0/9 raft: cannot step as peer not found 3->1 MsgAppResp Term:1 Log:0/9 raft: cannot step as peer not found + 3->1 MsgAppResp Term:1 Log:0/9 + raft: cannot step as peer not found + 3->1 MsgAppResp Term:1 Log:0/9 + raft: cannot step as peer not found