diff --git a/src/main/java/com/actiontech/dble/cluster/ClusterLogic.java b/src/main/java/com/actiontech/dble/cluster/ClusterLogic.java index 984b1b6e00..e9f48f2c55 100644 --- a/src/main/java/com/actiontech/dble/cluster/ClusterLogic.java +++ b/src/main/java/com/actiontech/dble/cluster/ClusterLogic.java @@ -35,6 +35,7 @@ import com.actiontech.dble.net.connection.BackendConnection; import com.actiontech.dble.net.connection.FrontendConnection; import com.actiontech.dble.route.RouteResultsetNode; +import com.actiontech.dble.services.manager.response.ReloadContext; import com.actiontech.dble.services.manager.response.ReloadConfig; import com.actiontech.dble.services.manager.response.ShowBinlogStatus; import com.actiontech.dble.services.mysqlsharding.ShardingService; @@ -283,7 +284,7 @@ public static void reloadConfigEvent(String value, String params) throws Excepti return; } try { - boolean result = ReloadConfig.reloadAll(Integer.parseInt(params)); + boolean result = ReloadConfig.reloadAll(Integer.parseInt(params), new ReloadContext()); if (!checkLocalResult(result)) { return; } diff --git a/src/main/java/com/actiontech/dble/config/ConfigInitializer.java b/src/main/java/com/actiontech/dble/config/ConfigInitializer.java index 53d20478d8..c5540fbc4d 100644 --- a/src/main/java/com/actiontech/dble/config/ConfigInitializer.java +++ b/src/main/java/com/actiontech/dble/config/ConfigInitializer.java @@ -26,6 +26,7 @@ import com.actiontech.dble.route.function.AbstractPartitionAlgorithm; import com.actiontech.dble.route.parser.util.Pair; import com.actiontech.dble.route.sequence.handler.IncrSequenceMySQLHandler; +import com.actiontech.dble.services.manager.response.ReloadContext; import com.actiontech.dble.singleton.TraceManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,6 +40,7 @@ public class ConfigInitializer implements ProblemReporter { private static final Logger LOGGER = LoggerFactory.getLogger(ConfigInitializer.class); + private volatile ReloadContext reloadContext; private volatile Map users; private volatile Map schemas; private volatile Map shardingNodes; @@ -198,6 +200,15 @@ public void testConnection() { // check whether dbInstance is connected String dbGroupName; PhysicalDbGroup dbGroup; + if (SystemConfig.getInstance().isSkipTestConOnUpdate()) { + if (reloadContext != null && !reloadContext.getAffectDbInstanceList().isEmpty()) { + boolean useSharding = reloadContext.getAffectDbInstanceList().stream().map(ele -> dbGroups.get(ele.getGroupName())).anyMatch((ele) -> ele != null && !ele.isShardingUseless()); + if (useSharding) { + //not support for sharding db group + reloadContext.getAffectDbInstanceList().clear(); + } + } + } for (Map.Entry entry : this.dbGroups.entrySet()) { dbGroup = entry.getValue(); dbGroupName = entry.getKey(); @@ -210,6 +221,16 @@ public void testConnection() { } for (PhysicalDbInstance ds : dbGroup.getDbInstances(true)) { + if (SystemConfig.getInstance().isSkipTestConOnUpdate()) { + if (reloadContext != null && !reloadContext.getAffectDbInstanceList().isEmpty()) { + String finalDbGroupName = dbGroupName; + boolean find = reloadContext.getAffectDbInstanceList().stream().anyMatch((ele) -> ele.getGroupName().equals(finalDbGroupName) && ele.getInstanceName().equals(ds.getName())); + if (!find) { + //skip test connection on this dbInstance + continue; + } + } + } if (ds.getConfig().isDisabled()) { errorInfos.add(new ErrorInfo("Backend", "WARNING", "dbGroup[" + dbGroupName + "," + ds.getName() + "] is disabled")); LOGGER.info("dbGroup[" + ds.getDbGroupConfig().getName() + "] is disabled,just mark testing failed and skip it"); @@ -344,4 +365,7 @@ public List getErrorInfos() { return errorInfos; } + public void setReloadContext(ReloadContext reloadContext) { + this.reloadContext = reloadContext; + } } diff --git a/src/main/java/com/actiontech/dble/config/model/SystemConfig.java b/src/main/java/com/actiontech/dble/config/model/SystemConfig.java index 1572b8c9b8..f5c975a91f 100644 --- a/src/main/java/com/actiontech/dble/config/model/SystemConfig.java +++ b/src/main/java/com/actiontech/dble/config/model/SystemConfig.java @@ -71,6 +71,7 @@ private SystemConfig() { private int useCostTimeStat = 0; private int maxCostStatSize = 100; private int costSamplePercent = 1; + private boolean skipTestConOnUpdate = false; //connection private String charset = "utf8mb4"; private int maxPacketSize = 4 * 1024 * 1024; @@ -486,6 +487,14 @@ public void setXaSessionCheckPeriod(long xaSessionCheckPeriod) { } } + public boolean isSkipTestConOnUpdate() { + return skipTestConOnUpdate; + } + + public void setSkipTestConOnUpdate(boolean skipTestConOnUpdate) { + this.skipTestConOnUpdate = skipTestConOnUpdate; + } + public long getXaLogCleanPeriod() { return xaLogCleanPeriod; } diff --git a/src/main/java/com/actiontech/dble/services/manager/handler/UpdateHandler.java b/src/main/java/com/actiontech/dble/services/manager/handler/UpdateHandler.java index bbba43b75c..cda8dca362 100644 --- a/src/main/java/com/actiontech/dble/services/manager/handler/UpdateHandler.java +++ b/src/main/java/com/actiontech/dble/services/manager/handler/UpdateHandler.java @@ -18,7 +18,10 @@ import com.actiontech.dble.services.manager.information.ManagerSchemaInfo; import com.actiontech.dble.services.manager.information.ManagerTableUtil; import com.actiontech.dble.services.manager.information.ManagerWritableTable; +import com.actiontech.dble.services.manager.information.tables.DbleDbInstance; import com.actiontech.dble.services.manager.response.ReloadConfig; +import com.actiontech.dble.services.manager.response.ReloadContext; +import com.actiontech.dble.services.manager.response.UniqueDbInstance; import com.actiontech.dble.util.StringUtil; import com.alibaba.druid.sql.ast.expr.SQLNullExpr; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -32,7 +35,9 @@ import java.io.IOException; import java.sql.SQLException; -import java.util.*; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; public final class UpdateHandler { private static final Logger LOGGER = LoggerFactory.getLogger(UpdateHandler.class); @@ -151,7 +156,17 @@ private int updateRows(ManagerService service, ManagerWritableTable managerTable if (!affectPks.isEmpty()) { rowSize = managerTable.updateRows(affectPks, values); if (rowSize != 0) { - ReloadConfig.execute(service, 0, false, new ConfStatus(ConfStatus.Status.MANAGER_UPDATE, managerTable.getTableName())); + + ReloadContext reloadContext = new ReloadContext(); + if (managerTable instanceof DbleDbInstance) { + for (LinkedHashMap affectPk : affectPks) { + String instanceName = affectPk.get("name"); + String dbGroup = affectPk.get("db_group"); + reloadContext.getAffectDbInstanceList().add(new UniqueDbInstance(dbGroup, instanceName)); + } + } + ReloadConfig.execute(service, 0, false, new ConfStatus(ConfStatus.Status.MANAGER_UPDATE, managerTable.getTableName()), reloadContext); + } } return rowSize; diff --git a/src/main/java/com/actiontech/dble/services/manager/response/ReloadConfig.java b/src/main/java/com/actiontech/dble/services/manager/response/ReloadConfig.java index e5add78c24..e82f03a30b 100644 --- a/src/main/java/com/actiontech/dble/services/manager/response/ReloadConfig.java +++ b/src/main/java/com/actiontech/dble/services/manager/response/ReloadConfig.java @@ -71,14 +71,16 @@ public static void execute(ManagerService service, String stmt, int offset) { writeErrorResult(service, e.getMessage() == null ? e.toString() : e.getMessage()); } } - - public static void execute(ManagerService service, final int loadAllMode, boolean returnFlag, ConfStatus confStatus) throws Exception { + execute(service, loadAllMode, returnFlag, confStatus, new ReloadContext()); + } + + public static void execute(ManagerService service, final int loadAllMode, boolean returnFlag, ConfStatus confStatus, ReloadContext reloadContext) throws Exception { try { if (ClusterConfig.getInstance().isClusterEnable()) { - reloadWithCluster(service, loadAllMode, returnFlag, confStatus); + reloadWithCluster(service, loadAllMode, returnFlag, confStatus, reloadContext); } else { - reloadWithoutCluster(service, loadAllMode, returnFlag, confStatus); + reloadWithoutCluster(service, loadAllMode, returnFlag, confStatus, reloadContext); } } finally { ReloadManager.reloadFinish(); @@ -86,7 +88,7 @@ public static void execute(ManagerService service, final int loadAllMode, boolea } - private static void reloadWithCluster(ManagerService service, int loadAllMode, boolean returnFlag, ConfStatus confStatus) throws Exception { + private static void reloadWithCluster(ManagerService service, int loadAllMode, boolean returnFlag, ConfStatus confStatus, ReloadContext reloadContext) throws Exception { TraceManager.TraceObject traceObject = TraceManager.serviceTrace(service, "reload-with-cluster"); try { DistributeLock distributeLock = ClusterHelper.createDistributeLock(ClusterPathUtil.getConfChangeLockPath(), SystemConfig.getInstance().getInstanceName()); @@ -105,7 +107,7 @@ private static void reloadWithCluster(ManagerService service, int loadAllMode, b lock.writeLock().lock(); try { //step 2 reload the local config file - if (!reloadAll(loadAllMode)) { + if (!reloadAll(loadAllMode, reloadContext)) { writeSpecialError(service, "Reload interruputed by others,config should be reload"); return; } @@ -146,7 +148,7 @@ private static void reloadWithCluster(ManagerService service, int loadAllMode, b } - private static void reloadWithoutCluster(ManagerService service, final int loadAllMode, boolean returnFlag, ConfStatus confStatus) throws Exception { + private static void reloadWithoutCluster(ManagerService service, final int loadAllMode, boolean returnFlag, ConfStatus confStatus, ReloadContext reloadContext) throws Exception { TraceManager.TraceObject traceObject = TraceManager.serviceTrace(service, "reload-in-local"); final ReentrantReadWriteLock lock = DbleServer.getInstance().getConfig().getLock(); lock.writeLock().lock(); @@ -155,7 +157,7 @@ private static void reloadWithoutCluster(ManagerService service, final int loadA writeErrorResult(service, "Reload status error ,other client or cluster may in reload"); return; } - boolean reloadFlag = reloadAll(loadAllMode); + boolean reloadFlag = reloadAll(loadAllMode, reloadContext); if (reloadFlag && returnFlag) { writeOKResult(service); } else if (!reloadFlag) { @@ -203,7 +205,7 @@ private static void writeErrorResult(ManagerService c, String errorMsg) { c.writeErrMessage(ErrorCode.ER_YES, sb); } - public static boolean reloadAll(final int loadAllMode) throws Exception { + public static boolean reloadAll(final int loadAllMode, ReloadContext reloadContext) throws Exception { TraceManager.TraceObject traceObject = TraceManager.threadTrace("self-reload"); try { /* @@ -215,6 +217,7 @@ public static boolean reloadAll(final int loadAllMode) throws Exception { ConfigInitializer loader; try { loader = new ConfigInitializer(false); + loader.setReloadContext(reloadContext); } catch (Exception e) { throw new Exception(e); } diff --git a/src/main/java/com/actiontech/dble/services/manager/response/ReloadContext.java b/src/main/java/com/actiontech/dble/services/manager/response/ReloadContext.java new file mode 100644 index 0000000000..0de824ccd0 --- /dev/null +++ b/src/main/java/com/actiontech/dble/services/manager/response/ReloadContext.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016-2023 ActionTech. + * based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT. + * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher. + */ + +package com.actiontech.dble.services.manager.response; + +import java.util.ArrayList; +import java.util.List; + +public class ReloadContext { + List affectDbInstanceList = new ArrayList<>(); + + public List getAffectDbInstanceList() { + return affectDbInstanceList; + } +} diff --git a/src/main/java/com/actiontech/dble/services/manager/response/UniqueDbInstance.java b/src/main/java/com/actiontech/dble/services/manager/response/UniqueDbInstance.java new file mode 100644 index 0000000000..174378b2a4 --- /dev/null +++ b/src/main/java/com/actiontech/dble/services/manager/response/UniqueDbInstance.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016-2023 ActionTech. + * based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT. + * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher. + */ + +package com.actiontech.dble.services.manager.response; + +public class UniqueDbInstance { + String groupName; + String instanceName; + + public UniqueDbInstance(String groupName, String instanceName) { + this.groupName = groupName; + this.instanceName = instanceName; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getInstanceName() { + return instanceName; + } + + public void setInstanceName(String instanceName) { + this.instanceName = instanceName; + } +}