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 3b89d3712..e9b62db91 100644 --- a/src/main/java/com/actiontech/dble/config/model/SystemConfig.java +++ b/src/main/java/com/actiontech/dble/config/model/SystemConfig.java @@ -214,6 +214,26 @@ public final class SystemConfig { private String gmsslOcaPem = null; private boolean supportSSL = false; + private int enableAsyncRelease = 1; + //unit: ms + private long releaseTimeout = 10L; + + public int getEnableAsyncRelease() { + return enableAsyncRelease; + } + + public void setEnableAsyncRelease(int enableAsyncRelease) { + this.enableAsyncRelease = enableAsyncRelease; + } + + public long getReleaseTimeout() { + return releaseTimeout; + } + + public void setReleaseTimeout(long releaseTimeout) { + this.releaseTimeout = releaseTimeout; + } + public String getServerCertificateKeyStoreUrl() { return serverCertificateKeyStoreUrl; } @@ -1676,6 +1696,8 @@ public final class SystemConfig { ", enableRoutePenetration=" + enableRoutePenetration + ", routePenetrationRules='" + routePenetrationRules + '\'' + ", groupConcatMaxLen='" + groupConcatMaxLen + + ", releaseTimeout=" + releaseTimeout + + ", enableAsyncRelease=" + enableAsyncRelease + "]"; } diff --git a/src/main/java/com/actiontech/dble/net/handler/BackEndRecycleRunnable.java b/src/main/java/com/actiontech/dble/net/handler/BackEndRecycleRunnable.java index 172ce820b..c4b7b2c93 100644 --- a/src/main/java/com/actiontech/dble/net/handler/BackEndRecycleRunnable.java +++ b/src/main/java/com/actiontech/dble/net/handler/BackEndRecycleRunnable.java @@ -5,6 +5,7 @@ package com.actiontech.dble.net.handler; +import com.actiontech.dble.config.model.SystemConfig; import com.actiontech.dble.net.connection.BackendConnection; import com.actiontech.dble.services.mysqlsharding.MySQLResponseService; @@ -26,33 +27,34 @@ public class BackEndRecycleRunnable implements Runnable, BackEndCleaner { service.setRecycler(this); } - @Override public void run() { BackendConnection conn = service.getConnection(); if (conn.isClosed()) { return; } - + boolean awaitTimeout = false; try { lock.lock(); try { if (service.isRowDataFlowing()) { - if (!condRelease.await(10, TimeUnit.MILLISECONDS)) { - if (!conn.isClosed()) { - conn.businessClose("recycle time out"); - } - } else { - service.release(); + if (!condRelease.await(SystemConfig.getInstance().getReleaseTimeout(), TimeUnit.MILLISECONDS)) { + awaitTimeout = true; } - } else { - service.release(); } } catch (Exception e) { service.getConnection().businessClose("recycle exception"); } finally { lock.unlock(); } + if (conn.isClosed()) { + return; + } + if (awaitTimeout) { + conn.businessClose("recycle time out"); + } else { + service.release(); + } } catch (Throwable e) { service.getConnection().businessClose("recycle exception"); } @@ -60,13 +62,14 @@ public class BackEndRecycleRunnable implements Runnable, BackEndCleaner { public void signal() { - if (lock.tryLock()) { - try { - condRelease.signal(); - } finally { - lock.unlock(); - } + lock.lock(); + try { + service.setRowDataFlowing(false); + condRelease.signal(); + } finally { + lock.unlock(); } + } } diff --git a/src/main/java/com/actiontech/dble/net/response/DefaultResponseHandler.java b/src/main/java/com/actiontech/dble/net/response/DefaultResponseHandler.java index 21fabbbb1..25b112459 100644 --- a/src/main/java/com/actiontech/dble/net/response/DefaultResponseHandler.java +++ b/src/main/java/com/actiontech/dble/net/response/DefaultResponseHandler.java @@ -73,8 +73,7 @@ public class DefaultResponseHandler implements ProtocolResponseHandler { if (service.getSession() != null) { service.getSession().startExecuteBackend(); } - service.setRowDataFlowing(false); - service.signal(); + service.releaseSignal(); status = INITIAL; } diff --git a/src/main/java/com/actiontech/dble/net/response/LoadDataResponseHandler.java b/src/main/java/com/actiontech/dble/net/response/LoadDataResponseHandler.java index a48e7bd03..8e779e51b 100644 --- a/src/main/java/com/actiontech/dble/net/response/LoadDataResponseHandler.java +++ b/src/main/java/com/actiontech/dble/net/response/LoadDataResponseHandler.java @@ -44,8 +44,7 @@ public class LoadDataResponseHandler extends CustomDataResponseHandler { @Override protected void beforeError() { - service.setRowDataFlowing(false); - service.signal(); + service.releaseSignal(); status = INITIAL; } diff --git a/src/main/java/com/actiontech/dble/services/BackendService.java b/src/main/java/com/actiontech/dble/services/BackendService.java index 31a1322bc..d7a891421 100644 --- a/src/main/java/com/actiontech/dble/services/BackendService.java +++ b/src/main/java/com/actiontech/dble/services/BackendService.java @@ -300,17 +300,14 @@ public abstract class BackendService extends AbstractService { public void backendSpecialCleanUp() { isExecuting = false; - isRowDataFlowing = false; - this.signal(); + this.releaseSignal(); } - public void signal() { - if (connection.isClosed()) { - return; - } - + public void releaseSignal() { + isRowDataFlowing = false; if (recycler != null) { recycler.signal(); + recycler = null; } } diff --git a/src/main/java/com/actiontech/dble/services/mysqlsharding/MySQLResponseService.java b/src/main/java/com/actiontech/dble/services/mysqlsharding/MySQLResponseService.java index c069b5bd8..3e02548c4 100644 --- a/src/main/java/com/actiontech/dble/services/mysqlsharding/MySQLResponseService.java +++ b/src/main/java/com/actiontech/dble/services/mysqlsharding/MySQLResponseService.java @@ -228,6 +228,9 @@ public class MySQLResponseService extends BackendService { protocolResponseHandler = defaultResponseHandler; } synAndDoExecuteMultiNode(synSQL, rrn, service.getCharset()); + } catch (Exception e) { + LOGGER.info("route error {},{},{}", rrn, this, service); + throw e; } finally { TraceManager.finishSpan(this, traceObject); } @@ -351,8 +354,14 @@ public class MySQLResponseService extends BackendService { if (logResponse.compareAndSet(false, true)) { session.setBackendResponseEndTime(this); } - DbleServer.getInstance().getComplexQueryExecutor().execute(new BackEndRecycleRunnable(this)); - return false; + if (SystemConfig.getInstance().getEnableAsyncRelease() == 1) { + DbleServer.getInstance().getComplexQueryExecutor().execute(new BackEndRecycleRunnable(this)); + return false; + } else { + new BackEndRecycleRunnable(this).run(); + return false; + } + } complexQuery = false; attachment = null; diff --git a/src/main/java/com/actiontech/dble/singleton/SystemParams.java b/src/main/java/com/actiontech/dble/singleton/SystemParams.java index 483cdaaa5..75d7aeb79 100644 --- a/src/main/java/com/actiontech/dble/singleton/SystemParams.java +++ b/src/main/java/com/actiontech/dble/singleton/SystemParams.java @@ -149,6 +149,10 @@ public final class SystemParams { readOnlyParams.add(new ParamInfo("gmsslRcaPem", SystemConfig.getInstance().getGmsslRcaPem() + "", "Root certificate of GMSSL")); readOnlyParams.add(new ParamInfo("gmsslOcaPem", SystemConfig.getInstance().getGmsslOcaPem() + "", "Secondary certificate of GMSSL")); readOnlyParams.add(new ParamInfo("groupConcatMaxLen", sysConfig.getGroupConcatMaxLen() + "", "The maximum permitted result length in bytes for the GROUP_CONCAT() function. The default is 1024.")); + readOnlyParams.add(new ParamInfo("enableAsyncRelease", sysConfig.getEnableAsyncRelease() + "", "Whether enable async release . default value is 1(off).")); + readOnlyParams.add(new ParamInfo("releaseTimeout", sysConfig.getReleaseTimeout() + "", "time wait for release ,unit is ms, default value is 10 ms")); + + } public List getVolatileParams() { diff --git a/src/main/resources/bootstrap_template.cnf b/src/main/resources/bootstrap_template.cnf index f0933e432..14b1c9efa 100644 --- a/src/main/resources/bootstrap_template.cnf +++ b/src/main/resources/bootstrap_template.cnf @@ -212,3 +212,6 @@ #-DgmsslRcaPem= #-DgmsslOcaPem= #-DsupportSSL= + +-DenableAsyncRelease=1 +-DreleaseTimeout=10