This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 99b38ddca74 [improve](env) Ensure next majority is met before drop an 
alive follower (#28101)
99b38ddca74 is described below

commit 99b38ddca74f1cf7f50292db3f7dc924d546a700
Author: walter <[email protected]>
AuthorDate: Sat Dec 9 01:41:38 2023 +0800

    [improve](env) Ensure next majority is met before drop an alive follower 
(#28101)
    
    Here is an example:
    
    ```
    mysql> ALTER SYSTEM DROP FOLLOWER "127.0.0.1:19017";
    ERROR 1105 (HY000): errCode = 2, detailMessage = Unable to drop this alive
    follower, because the quorum requirements are not met after this command
    execution. Current num alive followers 2, num followers 3, majority after
    execution 2
    ```
---
 .../main/java/org/apache/doris/catalog/Env.java    | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index b1ecd46956f..b498ccb6a67 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -2768,6 +2768,10 @@ public class Env {
                 throw new DdlException(role.toString() + " does not exist[" + 
NetUtils
                         .getHostPortInAccessibleFormat(host, port) + "]");
             }
+            if (role == FrontendNodeType.FOLLOWER && fe.isAlive()) {
+                // Try drop an alive follower, check the quorum safety.
+                ensureSafeToDropAliveFollower();
+            }
 
             int targetFollowerCount = getFollowerCount() - 1;
             if (fe.getRole() == FrontendNodeType.FOLLOWER || fe.getRole() == 
FrontendNodeType.REPLICA) {
@@ -2796,6 +2800,30 @@ public class Env {
         helperNodes.removeIf(node -> node.getHost().equals(host) && 
node.getPort() == port);
     }
 
+    private void ensureSafeToDropAliveFollower() throws DdlException {
+        int numFollower = 0;
+        int numAliveFollower = 0;
+        for (Frontend fe : frontends.values()) {
+            if (fe.getRole() == FrontendNodeType.FOLLOWER) {
+                numFollower += 1;
+                if (fe.isAlive()) {
+                    numAliveFollower += 1;
+                }
+            }
+        }
+
+        int nextMajority = ((numFollower - 1) / 2) + 1;
+        if (nextMajority + 1 <= numAliveFollower) {
+            return;
+        }
+
+        LOG.warn("Drop an alive follower is not safety. Current alive 
followers {}, followers {}, next majority: {}",
+                numAliveFollower, numFollower, nextMajority);
+        throw new DdlException("Unable to drop this alive follower, because 
the quorum requirements "
+                + "are not met after this command execution. Current num alive 
followers "
+                + numAliveFollower + ", num followers " + numFollower + ", 
majority after execution " + nextMajority);
+    }
+
     public Frontend checkFeExist(String host, int port) {
         for (Frontend fe : frontends.values()) {
             if (fe.getEditLogPort() != port) {


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

Reply via email to