Skip to content

Commit

Permalink
fix(pldebug): fix debugger create new connection attach debuggee sess…
Browse files Browse the repository at this point in the history
…ionId failed (#254)

* fix debugger deach dession failed

* add comment

* format code

* remove static from clone ds
  • Loading branch information
krihy authored Sep 7, 2023
1 parent ee12bf3 commit ae6d69f
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.sql.Connection;
import java.sql.Statement;
import java.util.List;
import java.util.function.Supplier;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
Expand All @@ -31,6 +32,7 @@
import com.oceanbase.odc.core.session.ConnectionSessionConstants;
import com.oceanbase.odc.core.session.ConnectionSessionUtil;
import com.oceanbase.odc.core.shared.constant.DialectType;
import com.oceanbase.odc.core.shared.constant.OdcConstants;
import com.oceanbase.odc.core.shared.exception.OBException;
import com.oceanbase.odc.core.shared.exception.UnexpectedException;
import com.oceanbase.odc.core.shared.model.OdcDBSession;
Expand Down Expand Up @@ -93,58 +95,60 @@ public DBFunction executeFunction(DBFunction dbFunction) {
}
}

protected void acquireNewConnection(ConnectionSession connectionSession, boolean directConnect)
throws Exception {
protected void acquireNewConnection(ConnectionSession connectionSession,
Supplier<SingleConnectionDataSource> dataSourceSupplier) throws Exception {
this.connectionSession = connectionSession;
ConnectionConfig connectionConfig =
(ConnectionConfig) ConnectionSessionUtil.getConnectionConfig(connectionSession);
this.dialectType = connectionConfig.getDialectType();
this.newDataSource = acquireDataSource(connectionSession, directConnect);
this.newDataSource = dataSourceSupplier.get();
this.jdbcOperations = new JdbcTemplate(this.newDataSource);
this.connection = newDataSource.getConnection();
}

private SingleConnectionDataSource acquireDataSource(ConnectionSession connectionSession, boolean directConnect) {

protected SingleConnectionDataSource acquireDataSource(ConnectionSession connectionSession) {
SingleConnectionDataSource dataSource = new SingleConnectionDataSource();
ConnectionConfig config = (ConnectionConfig) ConnectionSessionUtil.getConnectionConfig(connectionSession);
String schema = ConnectionSessionUtil.getCurrentSchema(connectionSession);
String host = config.getHost();
Integer port = config.getPort();
if (directConnect) {
List<OdcDBSession> sessions =
connectionSession.getSyncJdbcExecutor(ConnectionSessionConstants.CONSOLE_DS_KEY)
.query("show full processlist", new OdcDBSessionRowMapper());
if (CollectionUtils.isEmpty(sessions)) {
throw new UnexpectedException("Empty db session list");
}
String directServerIp = null;
for (OdcDBSession odcDbSession : sessions) {
if (StringUtils.isNotBlank(odcDbSession.getSvrIp())) {
directServerIp = odcDbSession.getSvrIp();
break;
}
}
if (StringUtils.isEmpty(directServerIp)) {
throw new UnexpectedException("Empty direct server ip and port from 'show full processlist'");
List<OdcDBSession> sessions =
connectionSession.getSyncJdbcExecutor(ConnectionSessionConstants.CONSOLE_DS_KEY)
.query("show full processlist", new OdcDBSessionRowMapper());
if (CollectionUtils.isEmpty(sessions)) {
throw new UnexpectedException("Empty db session list");
}
String directServerIp = null;
for (OdcDBSession odcDbSession : sessions) {
if (StringUtils.isNotBlank(odcDbSession.getSvrIp())) {
directServerIp = odcDbSession.getSvrIp();
break;
}
}
if (StringUtils.isEmpty(directServerIp)) {
throw new UnexpectedException("Empty direct server ip and port from 'show full processlist'");
}
String host = null;
Integer port = null;
if (directServerIp.contains(":")) {
host = directServerIp.split(":")[0];
port = Integer.parseInt(directServerIp.split(":")[1]);
} else {
host = config.getHost();
port = config.getPort();
}
String url = String.format("jdbc:%s://%s:%d/\"%s\"", OB_JDBC_PROTOCOL, host, port, schema);
dataSource.setUrl(url);
dataSource.setUsername(buildUserName(config, directConnect));
dataSource.setUsername(buildUserName(config));
dataSource.setPassword(config.getPassword());
dataSource.setDriverClassName(OdcConstants.DEFAULT_DRIVER_CLASS_NAME);
return dataSource;
}

private String buildUserName(ConnectionConfig connectionConfig, boolean directConnect) {
private String buildUserName(ConnectionConfig connectionConfig) {
StringBuilder userNameBuilder = new StringBuilder(connectionConfig.getUsername());
if (StringUtils.isNotBlank(connectionConfig.getTenantName())) {
userNameBuilder.append("@").append(connectionConfig.getTenantName());
}
if (!directConnect) {
userNameBuilder.append("#").append(connectionConfig.getClusterName());
}
return userNameBuilder.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public class DebuggeeSession extends AbstractDebugSession {
public DebuggeeSession(ConnectionSession connectionSession, ThreadPoolExecutor debugThreadPoolExecutor,
StartPLDebugReq req) throws Exception {

acquireNewConnection(connectionSession, true);
acquireNewConnection(connectionSession, () -> acquireDataSource(connectionSession));

// OceanBaseConnection can accept null as executor
// 0 for timeout means wait infinitely
connection.setNetworkTimeout(null, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Optional;

import org.apache.commons.lang3.Validate;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;

import com.alibaba.fastjson.JSONObject;
import com.oceanbase.odc.common.util.StringUtils;
Expand Down Expand Up @@ -107,7 +108,9 @@ public DebuggerSession(DebuggeeSession debuggeeSession, StartPLDebugReq req, boo
ddl = req.getAnonymousBlock();
this.syncEnabled = syncEnabled;

acquireNewConnection(debuggeeSession.getConnectionSession(), false);
// Debugger must connect to database host the same as debuggee
acquireNewConnection(debuggeeSession.getConnectionSession(),
() -> cloneDataSource(debuggeeSession.getNewDataSource()));
try (Statement stmt = connection.createStatement()) {
// 设置超时时间, 单位:us
stmt.execute(String.format("set session ob_query_timeout = %s;", DEBUG_TIMEOUT_MS * 1000));
Expand Down Expand Up @@ -176,6 +179,15 @@ public DebuggerSession(DebuggeeSession debuggeeSession, StartPLDebugReq req, boo
}
}

private SingleConnectionDataSource cloneDataSource(SingleConnectionDataSource originDataSource) {
SingleConnectionDataSource debuggerDataSource = new SingleConnectionDataSource();
debuggerDataSource.setUrl(originDataSource.getUrl());
debuggerDataSource.setUsername(originDataSource.getUsername());
debuggerDataSource.setPassword(originDataSource.getPassword());
debuggerDataSource.setDriverClassName(OdcConstants.DEFAULT_DRIVER_CLASS_NAME);
return debuggerDataSource;
}

private void debugBefore() {
List<PLDebugBreakpoint> breakpoints = new ArrayList<>();
PLDebugBreakpoint beginBreakpoint = new PLDebugBreakpoint();
Expand Down

0 comments on commit ae6d69f

Please sign in to comment.