[inner-2368] fix: when some nodes have been closed during the ddl execution phase, the front side needs to respond with an error.

(cherry picked from commit 2cfcac2850)
This commit is contained in:
wenyh1
2023-10-08 17:20:08 +08:00
parent 38f7ad9e0f
commit c3631df719
2 changed files with 17 additions and 8 deletions

View File

@@ -62,6 +62,7 @@ public abstract class BaseDDLHandler implements ResponseHandler, ExecutableHandl
protected final ReentrantLock lock = new ReentrantLock();
protected HashMap<RouteResultsetNode, Integer> nodeResponseStatus = Maps.newHashMap();
protected Set<MySQLResponseService> closedConnSet = new HashSet<>(1);
protected AtomicBoolean writeToClientFlag = new AtomicBoolean(false);
protected AtomicBoolean specialHandleFlag = new AtomicBoolean(false); // execute special handling only once
protected volatile String errMsg;
@@ -287,7 +288,7 @@ public abstract class BaseDDLHandler implements ResponseHandler, ExecutableHandl
MySQLResponseService responseService = (MySQLResponseService) service;
final RouteResultsetNode node = (RouteResultsetNode) responseService.getAttachment();
if (checkIsAlreadyClosed(node)) return;
if (checkIsAlreadyClosed(node, responseService)) return;
LOGGER.warn("backend connect {}, conn info:{}", closeReason0, service);
DDLTraceHelper.log(session.getShardingService(), d -> d.infoByNode(node.getName(), stage, DDLTraceHelper.Status.fail, closeReason0));
@@ -326,11 +327,15 @@ public abstract class BaseDDLHandler implements ResponseHandler, ExecutableHandl
}
}
protected boolean checkIsAlreadyClosed(final RouteResultsetNode node) {
protected boolean checkIsAlreadyClosed(final RouteResultsetNode node, final MySQLResponseService mysqlResponseService) {
lock.lock();
try {
if (nodeResponseStatus.get(node) == null || nodeResponseStatus.get(node) == STATUS_CONN_CLOSE) return true;
nodeResponseStatus.put(node, STATUS_CONN_CLOSE);
if (closedConnSet.contains(mysqlResponseService)) {
nodeResponseStatus.put(node, STATUS_CONN_CLOSE);
return true;
} else {
closedConnSet.add(mysqlResponseService);
}
session.getTargetMap().remove(node);
return false;
} finally {
@@ -368,6 +373,7 @@ public abstract class BaseDDLHandler implements ResponseHandler, ExecutableHandl
protected void clearResources() {
nodeResponseStatus.clear();
closedConnSet.clear();
}
protected void handleEndPacket(MySQLPacket packet) {

View File

@@ -112,13 +112,16 @@ public class MultiNodeDdlPrepareHandler extends BaseDDLHandler {
}
@Override
protected boolean checkIsAlreadyClosed(final RouteResultsetNode node) {
protected boolean checkIsAlreadyClosed(final RouteResultsetNode node, final MySQLResponseService mysqlResponseService) {
lock.lock();
try {
if (finishedTest) return true;
if (nodeResponseStatus.get(node) == null || nodeResponseStatus.get(node) == STATUS_CONN_CLOSE) return true;
nodeResponseStatus.put(node, STATUS_CONN_CLOSE);
session.getTargetMap().remove(node);
if (closedConnSet.contains(mysqlResponseService)) {
nodeResponseStatus.put(node, STATUS_CONN_CLOSE);
return true;
} else {
closedConnSet.add(mysqlResponseService);
}
return false;
} finally {
lock.unlock();