下面列出了java.sql.DriverPropertyInfo#com.mysql.cj.conf.HostInfo 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Creates a new physical connection for the given {@link HostInfo} and updates required internal mappings and statistics for that connection.
*
* @param hostInfo
* The host info instance.
* @return
* The new Connection instance.
*/
@Override
public synchronized ConnectionImpl createConnectionForHost(HostInfo hostInfo) throws SQLException {
ConnectionImpl conn = super.createConnectionForHost(hostInfo);
this.liveConnections.put(hostInfo.getHostPortPair(), conn);
this.connectionsToHostsMap.put(conn, hostInfo.getHostPortPair());
this.totalPhysicalConnections++;
for (QueryInterceptor stmtInterceptor : conn.getQueryInterceptorsInstances()) {
if (stmtInterceptor instanceof LoadBalancedAutoCommitInterceptor) {
((LoadBalancedAutoCommitInterceptor) stmtInterceptor).resumeCounters();
break;
}
}
return conn;
}
public synchronized void promoteSlaveToMaster(String hostPortPair) throws SQLException {
HostInfo host = getSlaveHost(hostPortPair);
if (host == null) {
return;
}
this.masterHosts.add(host);
removeSlave(hostPortPair);
if (this.masterConnection != null) {
this.masterConnection.addHost(hostPortPair);
}
// Switch back to the masters connection if this connection was running in fail-safe mode.
if (!this.readOnly && !isMasterConnection()) {
switchToMasterConnection();
}
}
public MysqlxSession(HostInfo hostInfo, PropertySet propSet) {
super(hostInfo, propSet);
// create protocol instance
this.host = hostInfo.getHost();
if (this.host == null || StringUtils.isEmptyOrWhitespaceOnly(this.host)) {
this.host = "localhost";
}
this.port = hostInfo.getPort();
if (this.port < 0) {
this.port = 33060;
}
this.protocol = XProtocol.getInstance(this.host, this.port, propSet);
this.messageBuilder = this.protocol.getMessageBuilder();
this.protocol.connect(hostInfo.getUser(), hostInfo.getPassword(), hostInfo.getDatabase());
}
/**
* Creates {@link Session} by given URL.
*
* @param url
* the session URL.
* @return a {@link Session} instance.
*/
public Session getSession(String url) {
CJCommunicationsException latestException = null;
ConnectionUrl connUrl = parseUrl(url);
for (HostInfo hi : connUrl.getHostsList()) {
try {
return new SessionImpl(hi);
} catch (CJCommunicationsException e) {
latestException = e;
}
}
if (latestException != null) {
throw latestException;
}
return null;
}
public CoreSession(HostInfo hostInfo, PropertySet propSet) {
this.connectionCreationTimeMillis = System.currentTimeMillis();
this.hostInfo = hostInfo;
this.propertySet = propSet;
this.gatherPerfMetrics = getPropertySet().getBooleanReadableProperty(PropertyDefinitions.PNAME_gatherPerfMetrics);
this.characterEncoding = getPropertySet().getModifiableProperty(PropertyDefinitions.PNAME_characterEncoding);
this.useOldUTF8Behavior = getPropertySet().getBooleanReadableProperty(PropertyDefinitions.PNAME_useOldUTF8Behavior);
this.disconnectOnExpiredPasswords = getPropertySet().getBooleanReadableProperty(PropertyDefinitions.PNAME_disconnectOnExpiredPasswords);
this.cacheServerConfiguration = getPropertySet().getBooleanReadableProperty(PropertyDefinitions.PNAME_cacheServerConfiguration);
this.autoReconnect = getPropertySet().<Boolean> getModifiableProperty(PropertyDefinitions.PNAME_autoReconnect);
this.autoReconnectForPools = getPropertySet().getBooleanReadableProperty(PropertyDefinitions.PNAME_autoReconnectForPools);
this.maintainTimeStats = getPropertySet().getBooleanReadableProperty(PropertyDefinitions.PNAME_maintainTimeStats);
this.log = LogFactory.getLogger(getPropertySet().getStringReadableProperty(PropertyDefinitions.PNAME_logger).getStringValue(),
Log.LOGGER_INSTANCE_NAME);
if (getPropertySet().getBooleanReadableProperty(PropertyDefinitions.PNAME_profileSQL).getValue()
|| getPropertySet().getBooleanReadableProperty(PropertyDefinitions.PNAME_useUsageAdvisor).getValue()) {
ProfilerEventHandlerFactory.getInstance(this);
}
}
/**
* Creates a new physical connection for the given {@link HostInfo} and updates required internal mappings and statistics for that connection.
*
* @param hostInfo
* The host info instance.
* @return
* The new Connection instance.
* @throws SQLException
* if an error occurs
*/
@Override
public synchronized ConnectionImpl createConnectionForHost(HostInfo hostInfo) throws SQLException {
ConnectionImpl conn = super.createConnectionForHost(hostInfo);
this.liveConnections.put(hostInfo.getHostPortPair(), conn);
this.connectionsToHostsMap.put(conn, hostInfo.getHostPortPair());
this.totalPhysicalConnections++;
for (QueryInterceptor stmtInterceptor : conn.getQueryInterceptorsInstances()) {
if (stmtInterceptor instanceof LoadBalancedAutoCommitInterceptor) {
((LoadBalancedAutoCommitInterceptor) stmtInterceptor).resumeCounters();
break;
}
}
return conn;
}
public synchronized void promoteSlaveToMaster(String hostPortPair) throws SQLException {
HostInfo host = getSlaveHost(hostPortPair);
if (host == null) {
return;
}
this.masterHosts.add(host);
removeSlave(hostPortPair);
if (this.masterConnection != null) {
this.masterConnection.addHost(hostPortPair);
}
// Switch back to the masters connection if this connection was running in fail-safe mode.
if (!this.readOnly && !isMasterConnection()) {
switchToMasterConnection();
}
}
public XProtocol(HostInfo hostInfo, PropertySet propertySet) {
String host = hostInfo.getHost();
if (host == null || StringUtils.isEmptyOrWhitespaceOnly(host)) {
host = "localhost";
}
int port = hostInfo.getPort();
if (port < 0) {
port = 33060;
}
this.defaultSchemaName = hostInfo.getDatabase();
// Override common connectTimeout with xdevapi.connect-timeout to provide unified logic in StandardSocketFactory
RuntimeProperty<Integer> connectTimeout = propertySet.getIntegerProperty(PropertyKey.connectTimeout);
RuntimeProperty<Integer> xdevapiConnectTimeout = propertySet.getIntegerProperty(PropertyKey.xdevapiConnectTimeout);
if (xdevapiConnectTimeout.isExplicitlySet() || !connectTimeout.isExplicitlySet()) {
connectTimeout.setValue(xdevapiConnectTimeout.getValue());
}
SocketConnection socketConn = propertySet.getBooleanProperty(PropertyKey.xdevapiUseAsyncProtocol).getValue() ? new XAsyncSocketConnection()
: new NativeSocketConnection();
socketConn.connect(host, port, propertySet, null, null, 0);
init(null, socketConn, propertySet, null);
}
public CoreSession(HostInfo hostInfo, PropertySet propSet) {
this.connectionCreationTimeMillis = System.currentTimeMillis();
this.hostInfo = hostInfo;
this.propertySet = propSet;
this.gatherPerfMetrics = getPropertySet().getBooleanProperty(PropertyKey.gatherPerfMetrics);
this.characterEncoding = getPropertySet().getStringProperty(PropertyKey.characterEncoding);
this.disconnectOnExpiredPasswords = getPropertySet().getBooleanProperty(PropertyKey.disconnectOnExpiredPasswords);
this.cacheServerConfiguration = getPropertySet().getBooleanProperty(PropertyKey.cacheServerConfiguration);
this.autoReconnect = getPropertySet().getBooleanProperty(PropertyKey.autoReconnect);
this.autoReconnectForPools = getPropertySet().getBooleanProperty(PropertyKey.autoReconnectForPools);
this.maintainTimeStats = getPropertySet().getBooleanProperty(PropertyKey.maintainTimeStats);
this.log = LogFactory.getLogger(getPropertySet().getStringProperty(PropertyKey.logger).getStringValue(), Log.LOGGER_INSTANCE_NAME);
if (getPropertySet().getBooleanProperty(PropertyKey.profileSQL).getValue()
|| getPropertySet().getBooleanProperty(PropertyKey.useUsageAdvisor).getValue()) {
ProfilerEventHandlerFactory.getInstance(this);
}
}
/**
* Tests default values.
*/
@Test
public void testDefaultValues() {
Map<String, Integer> connStr = new HashMap<>();
connStr.put("jdbc:mysql:", 3306);
connStr.put("jdbc:mysql://,", 3306);
connStr.put("jdbc:mysql:loadbalance://,", 3306);
connStr.put("jdbc:mysql:replication://,", 3306);
connStr.put("mysqlx:", 33060);
for (String cs : connStr.keySet()) {
ConnectionUrl connUrl = ConnectionUrl.getConnectionUrlInstance(cs, null);
for (HostInfo hi : connUrl.getHostsList()) {
assertEquals(cs + "#databaseUrl", cs, hi.getDatabaseUrl());
assertEquals(cs + "#host", "localhost", hi.getHost());
assertEquals(cs + "#port", connStr.get(cs).intValue(), hi.getPort());
assertEquals(cs + "#hostPortPair", "localhost:" + connStr.get(cs), hi.getHostPortPair());
assertEquals(cs + "#user", "", hi.getUser());
assertEquals(cs + "#password", "", hi.getPassword());
assertEquals(cs + "#database", "", hi.getDatabase());
}
}
}
/**
* Tests fix for BUG#28150662, CONNECTOR/J 8 MALFORMED DATABASE URL EXCEPTION WHIT CORRECT URL STRING.
*/
@Test
public void testBug28150662() {
List<String> connStr = new ArrayList<>();
connStr.add(
"jdbc:mysql://localhost:3306/db1?connectionCollation=utf8mb4_unicode_ci&user=user1&sessionVariables=sql_mode='IGNORE_SPACE,ANSI',FOREIGN_KEY_CHECKS=0");
connStr.add(
"jdbc:mysql://localhost:3306/db1?connectionCollation=utf8mb4_unicode_ci&sessionVariables=sql_mode='IGNORE_SPACE,ANSI',FOREIGN_KEY_CHECKS=0&user=user1");
connStr.add(
"jdbc:mysql://address=(host=localhost)(port=3306)(connectionCollation=utf8mb4_unicode_ci)(sessionVariables=sql_mode='IGNORE_SPACE,ANSI',FOREIGN_KEY_CHECKS=0)(user=user1)/db1");
connStr.add(
"jdbc:mysql://(host=localhost,port=3306,connectionCollation=utf8mb4_unicode_ci,sessionVariables=sql_mode='IGNORE_SPACE%2CANSI'%2CFOREIGN_KEY_CHECKS=0,user=user1)/db1");
for (String cs : connStr) {
ConnectionUrl url = ConnectionUrl.getConnectionUrlInstance(cs, null);
HostInfo hi = url.getMainHost();
assertEquals("utf8mb4_unicode_ci", hi.getHostProperties().get("connectionCollation"));
assertEquals("user1", hi.getUser());
assertEquals("sql_mode='IGNORE_SPACE,ANSI',FOREIGN_KEY_CHECKS=0", hi.getHostProperties().get("sessionVariables"));
}
}
/**
* Initializes the hosts lists and makes a "clean" local copy of the given connection properties so that it can be later used to create standard
* connections.
*
* @param connUrl
* The connection URL that initialized this multi-host connection.
* @param hosts
* The list of hosts for this multi-host connection.
* @return
* The number of hosts found in the hosts list.
*/
int initializeHostsSpecs(ConnectionUrl connUrl, List<HostInfo> hosts) {
this.connectionUrl = connUrl;
Properties props = connUrl.getConnectionArgumentsAsProperties();
this.autoReconnect = "true".equalsIgnoreCase(props.getProperty(PropertyDefinitions.PNAME_autoReconnect))
|| "true".equalsIgnoreCase(props.getProperty(PropertyDefinitions.PNAME_autoReconnectForPools));
this.hostsList = new ArrayList<>(hosts);
int numHosts = this.hostsList.size();
return numHosts;
}
/**
* Removes a host from the host list.
*
* @param hostPortPair
* The host to be removed.
* @throws SQLException
*/
public synchronized void removeHost(String hostPortPair) throws SQLException {
if (this.connectionGroup != null) {
if (this.connectionGroup.getInitialHosts().size() == 1 && this.connectionGroup.getInitialHosts().contains(hostPortPair)) {
throw SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.0"), null);
}
}
this.hostsToRemove.add(hostPortPair);
this.connectionsToHostsMap.remove(this.liveConnections.remove(hostPortPair));
if (this.hostsToListIndexMap.remove(hostPortPair) != null) {
long[] newResponseTimes = new long[this.responseTimes.length - 1];
int newIdx = 0;
for (HostInfo hostInfo : this.hostsList) {
String host = hostInfo.getHostPortPair();
if (!this.hostsToRemove.contains(host)) {
Integer idx = this.hostsToListIndexMap.get(host);
if (idx != null && idx < this.responseTimes.length) {
newResponseTimes[newIdx] = this.responseTimes[idx];
}
this.hostsToListIndexMap.put(host, newIdx++);
}
}
this.responseTimes = newResponseTimes;
}
if (hostPortPair.equals(this.currentConnection.getHostPortPair())) {
invalidateConnection(this.currentConnection);
pickNewConnection();
}
}
public synchronized void removeMasterHost(String hostPortPair, boolean waitUntilNotInUse, boolean isNowSlave) throws SQLException {
HostInfo host = getMasterHost(hostPortPair);
if (host == null) {
return;
}
if (isNowSlave) {
this.slaveHosts.add(host);
resetReadFromMasterWhenNoSlaves();
}
this.masterHosts.remove(host);
// The master connection may have been implicitly closed by a previous op., don't let it stop us.
if (this.masterConnection == null || this.masterConnection.isClosed()) {
this.masterConnection = null;
return;
}
if (waitUntilNotInUse) {
this.masterConnection.removeHostWhenNotInUse(hostPortPair);
} else {
this.masterConnection.removeHost(hostPortPair);
}
// Close the connection if that was the last master.
if (this.masterHosts.isEmpty()) {
this.masterConnection.close();
this.masterConnection = null;
// Default behavior, no need to check this.readFromMasterWhenNoSlaves.
switchToSlavesConnectionIfNecessary();
}
}
public synchronized void removeSlave(String hostPortPair, boolean closeGently) throws SQLException {
HostInfo host = getSlaveHost(hostPortPair);
if (host == null) {
return;
}
this.slaveHosts.remove(host);
resetReadFromMasterWhenNoSlaves();
if (this.slavesConnection == null || this.slavesConnection.isClosed()) {
this.slavesConnection = null;
return;
}
if (closeGently) {
this.slavesConnection.removeHostWhenNotInUse(hostPortPair);
} else {
this.slavesConnection.removeHost(hostPortPair);
}
// Close the connection if that was the last slave.
if (this.slaveHosts.isEmpty()) {
this.slavesConnection.close();
this.slavesConnection = null;
// Default behavior, no need to check this.readFromMasterWhenNoSlaves.
switchToMasterConnection();
if (isMasterConnection()) {
this.currentConnection.setReadOnly(this.readOnly); // Maintain.
}
}
}
public void connect(HostInfo hi, String user, String password, String database, int loginTimeout, TransactionEventHandler transactionManager)
throws IOException {
this.hostInfo = hi;
// reset max-rows to default value
this.setSessionMaxRows(-1);
// TODO do we need different types of physical connections?
SocketConnection socketConnection = new NativeSocketConnection();
socketConnection.connect(this.hostInfo.getHost(), this.hostInfo.getPort(), this.propertySet, getExceptionInterceptor(), this.log, loginTimeout);
// we use physical connection to create a -> protocol
// this configuration places no knowledge of protocol or session on physical connection.
// physical connection is responsible *only* for I/O streams
if (this.protocol == null) {
this.protocol = NativeProtocol.getInstance(this, socketConnection, this.propertySet, this.log, transactionManager);
} else {
this.protocol.init(this, socketConnection, this.propertySet, transactionManager);
}
// use protocol to create a -> session
// protocol is responsible for building a session and authenticating (using AuthenticationProvider) internally
this.protocol.connect(user, password, database);
// error messages are returned according to character_set_results which, at this point, is set from the response packet
this.protocol.getServerSession().setErrorMessageEncoding(this.protocol.getAuthenticationProvider().getEncodingForHandshake());
this.isClosed = false;
}
public SessionImpl(HostInfo hostInfo) {
PropertySet pset = new DefaultPropertySet();
pset.initializeProperties(hostInfo.exposeAsProperties());
this.session = new MysqlxSession(hostInfo, pset);
this.defaultSchemaName = hostInfo.getDatabase();
this.xbuilder = (XMessageBuilder) this.session.<XMessage> getMessageBuilder();
}
/**
* Initializes the hosts lists and makes a "clean" local copy of the given connection properties so that it can be later used to create standard
* connections.
*
* @param connUrl
* The connection URL that initialized this multi-host connection.
* @param hosts
* The list of hosts for this multi-host connection.
* @return
* The number of hosts found in the hosts list.
*/
int initializeHostsSpecs(ConnectionUrl connUrl, List<HostInfo> hosts) {
this.connectionUrl = connUrl;
Properties props = connUrl.getConnectionArgumentsAsProperties();
this.autoReconnect = "true".equalsIgnoreCase(props.getProperty(PropertyKey.autoReconnect.getKeyName()))
|| "true".equalsIgnoreCase(props.getProperty(PropertyKey.autoReconnectForPools.getKeyName()));
this.hostsList = new ArrayList<>(hosts);
int numHosts = this.hostsList.size();
return numHosts;
}
/**
* Removes a host from the host list.
*
* @param hostPortPair
* The host to be removed.
* @throws SQLException
* if an error occurs
*/
public synchronized void removeHost(String hostPortPair) throws SQLException {
if (this.connectionGroup != null) {
if (this.connectionGroup.getInitialHosts().size() == 1 && this.connectionGroup.getInitialHosts().contains(hostPortPair)) {
throw SQLError.createSQLException(Messages.getString("LoadBalancedConnectionProxy.0"), null);
}
}
this.hostsToRemove.add(hostPortPair);
this.connectionsToHostsMap.remove(this.liveConnections.remove(hostPortPair));
if (this.hostsToListIndexMap.remove(hostPortPair) != null) {
long[] newResponseTimes = new long[this.responseTimes.length - 1];
int newIdx = 0;
for (HostInfo hostInfo : this.hostsList) {
String host = hostInfo.getHostPortPair();
if (!this.hostsToRemove.contains(host)) {
Integer idx = this.hostsToListIndexMap.get(host);
if (idx != null && idx < this.responseTimes.length) {
newResponseTimes[newIdx] = this.responseTimes[idx];
}
this.hostsToListIndexMap.put(host, newIdx++);
}
}
this.responseTimes = newResponseTimes;
}
if (hostPortPair.equals(this.currentConnection.getHostPortPair())) {
invalidateConnection(this.currentConnection);
pickNewConnection();
}
}
public synchronized void removeMasterHost(String hostPortPair, boolean waitUntilNotInUse, boolean isNowSlave) throws SQLException {
HostInfo host = getMasterHost(hostPortPair);
if (host == null) {
return;
}
if (isNowSlave) {
this.slaveHosts.add(host);
resetReadFromMasterWhenNoSlaves();
}
this.masterHosts.remove(host);
// The master connection may have been implicitly closed by a previous op., don't let it stop us.
if (this.masterConnection == null || this.masterConnection.isClosed()) {
this.masterConnection = null;
return;
}
if (waitUntilNotInUse) {
this.masterConnection.removeHostWhenNotInUse(hostPortPair);
} else {
this.masterConnection.removeHost(hostPortPair);
}
// Close the connection if that was the last master.
if (this.masterHosts.isEmpty()) {
this.masterConnection.close();
this.masterConnection = null;
// Default behavior, no need to check this.readFromMasterWhenNoSlaves.
switchToSlavesConnectionIfNecessary();
}
}
public synchronized void removeSlave(String hostPortPair, boolean closeGently) throws SQLException {
HostInfo host = getSlaveHost(hostPortPair);
if (host == null) {
return;
}
this.slaveHosts.remove(host);
resetReadFromMasterWhenNoSlaves();
if (this.slavesConnection == null || this.slavesConnection.isClosed()) {
this.slavesConnection = null;
return;
}
if (closeGently) {
this.slavesConnection.removeHostWhenNotInUse(hostPortPair);
} else {
this.slavesConnection.removeHost(hostPortPair);
}
// Close the connection if that was the last slave.
if (this.slaveHosts.isEmpty()) {
this.slavesConnection.close();
this.slavesConnection = null;
// Default behavior, no need to check this.readFromMasterWhenNoSlaves.
switchToMasterConnection();
if (isMasterConnection()) {
this.currentConnection.setReadOnly(this.readOnly); // Maintain.
}
}
}
/**
* Constructor.
*
* @param hostInfo
* {@link HostInfo} instance
*/
public SessionImpl(HostInfo hostInfo) {
PropertySet pset = new DefaultPropertySet();
pset.initializeProperties(hostInfo.exposeAsProperties());
this.session = new MysqlxSession(hostInfo, pset);
this.defaultSchemaName = hostInfo.getDatabase();
this.xbuilder = (XMessageBuilder) this.session.<XMessage> getMessageBuilder();
}
/**
* Creates {@link Session} by given URL.
*
* @param connUrl
* the session {@link ConnectionUrl}.
* @return a {@link Session} instance.
*/
protected Session getSession(ConnectionUrl connUrl) {
CJCommunicationsException latestException = null;
for (HostInfo hi : connUrl.getHostsList()) {
try {
return new SessionImpl(hi);
} catch (CJCommunicationsException e) {
latestException = e;
}
}
if (latestException != null) {
throw latestException;
}
return null;
}
public void connect(HostInfo hi, String user, String password, String database, int loginTimeout, TransactionEventHandler transactionManager)
throws IOException {
this.hostInfo = hi;
// reset max-rows to default value
this.setSessionMaxRows(-1);
// TODO do we need different types of physical connections?
SocketConnection socketConnection = new NativeSocketConnection();
socketConnection.connect(this.hostInfo.getHost(), this.hostInfo.getPort(), this.propertySet, getExceptionInterceptor(), this.log, loginTimeout);
// we use physical connection to create a -> protocol
// this configuration places no knowledge of protocol or session on physical connection.
// physical connection is responsible *only* for I/O streams
if (this.protocol == null) {
this.protocol = NativeProtocol.getInstance(this, socketConnection, this.propertySet, this.log, transactionManager);
} else {
this.protocol.init(this, socketConnection, this.propertySet, transactionManager);
}
// use protocol to create a -> session
// protocol is responsible for building a session and authenticating (using AuthenticationProvider) internally
this.protocol.connect(user, password, database);
// error messages are returned according to character_set_results which, at this point, is set from the response packet
this.protocol.getServerSession().setErrorMessageEncoding(this.protocol.getAuthenticationProvider().getEncodingForHandshake());
this.isClosed = false;
}
protected Connection getUnreliableMultiHostConnection(String haMode, String[] hostNames, Properties props, Set<String> downedHosts) throws Exception {
if (downedHosts == null) {
downedHosts = new HashSet<>();
}
props = getHostFreePropertiesFromTestsuiteUrl(props);
props.setProperty(PropertyKey.socketFactory.getKeyName(), "testsuite.UnreliableSocketFactory");
HostInfo defaultHost = mainConnectionUrl.getMainHost();
String db = defaultHost.getDatabase();
String port = String.valueOf(defaultHost.getPort());
String host = defaultHost.getHost();
UnreliableSocketFactory.flushAllStaticData();
StringBuilder hostString = new StringBuilder();
String delimiter = "";
for (String hostName : hostNames) {
UnreliableSocketFactory.mapHost(hostName, host);
hostString.append(delimiter);
delimiter = ",";
hostString.append(hostName + ":" + port);
if (downedHosts.contains(hostName)) {
UnreliableSocketFactory.downHost(hostName);
}
}
if (haMode == null) {
haMode = "";
} else if (haMode.length() > 0) {
haMode += ":";
}
return getConnectionWithProps(ConnectionUrl.Type.FAILOVER_CONNECTION.getScheme() + haMode + "//" + hostString.toString() + "/" + db, props);
}
protected ReplicationConnection getUnreliableReplicationConnection(Set<MockConnectionConfiguration> configs, Properties props) throws Exception {
props = getHostFreePropertiesFromTestsuiteUrl(props);
props.setProperty(PropertyKey.socketFactory.getKeyName(), "testsuite.UnreliableSocketFactory");
HostInfo defaultHost = mainConnectionUrl.getMainHost();
String db = defaultHost.getDatabase();
String port = String.valueOf(defaultHost.getPort());
String host = defaultHost.getHost();
UnreliableSocketFactory.flushAllStaticData();
StringBuilder hostString = new StringBuilder();
String glue = "";
for (MockConnectionConfiguration config : configs) {
UnreliableSocketFactory.mapHost(config.hostName, host);
hostString.append(glue);
glue = ",";
if (config.port == null) {
config.port = (port == null ? "3306" : port);
}
hostString.append(config.getAddress());
if (config.isDowned) {
UnreliableSocketFactory.downHost(config.hostName);
}
}
return (ReplicationConnection) getConnectionWithProps(ConnectionUrl.Type.REPLICATION_CONNECTION.getScheme() + "//" + hostString.toString() + "/" + db,
props);
}
@Override
public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes,
Object ret) {
if (ret instanceof EnhancedInstance) {
final HostInfo hostInfo = (HostInfo) allArguments[0];
ConnectionInfo connectionInfo = URLParser.parser(hostInfo.getDatabaseUrl());
((EnhancedInstance) ret).setSkyWalkingDynamicField(connectionInfo);
}
return ret;
}
private ProcessExecutor createProcessExecutor(File targetDir, DbProperties dbProperties) {
ConnectionUrl connectionUrlInstance = ConnectionUrl.getConnectionUrlInstance(dbProperties.url(), dbProperties.connectionProperties());
LinkedHashMap<String, String> env = new LinkedHashMap<>();
if (isNotBlank(dbProperties.password())) {
env.put("MYSQL_PWD", dbProperties.password());
}
// override with any user specified environment
env.putAll(dbProperties.extraBackupEnv());
ArrayList<String> argv = new ArrayList<>();
argv.add("mysqldump");
String dbName = connectionUrlInstance.getDatabase();
HostInfo mainHost = connectionUrlInstance.getMainHost();
if (mainHost != null) {
argv.add("--host=" + mainHost.getHost());
argv.add("--port=" + mainHost.getPort());
}
if (isNotBlank(dbProperties.user())) {
argv.add("--user=" + dbProperties.user());
}
// append any user specified args for mysqldump
if (isNotBlank(dbProperties.extraBackupCommandArgs())) {
Collections.addAll(argv, Commandline.translateCommandline(dbProperties.extraBackupCommandArgs()));
}
argv.add("--result-file=" + new File(targetDir, "db." + dbName).toString());
argv.add(connectionUrlInstance.getDatabase());
ProcessExecutor processExecutor = new ProcessExecutor();
processExecutor.redirectOutputAlsoTo(Slf4jStream.of(getClass()).asDebug());
processExecutor.redirectErrorAlsoTo(Slf4jStream.of(getClass()).asDebug());
processExecutor.environment(env);
processExecutor.command(argv);
return processExecutor;
}
/**
* Cancels this Statement object if both the DBMS and driver support
* aborting an SQL statement. This method can be used by one thread to
* cancel a statement that is being executed by another thread.
*/
public void cancel() throws SQLException {
if (!this.query.getStatementExecuting().get()) {
return;
}
if (!this.isClosed && this.connection != null) {
JdbcConnection cancelConn = null;
java.sql.Statement cancelStmt = null;
try {
HostInfo hostInfo = this.session.getHostInfo();
String database = hostInfo.getDatabase();
String user = StringUtils.isNullOrEmpty(hostInfo.getUser()) ? "" : hostInfo.getUser();
String password = StringUtils.isNullOrEmpty(hostInfo.getPassword()) ? "" : hostInfo.getPassword();
NativeSession newSession = new NativeSession(this.session.getHostInfo(), this.session.getPropertySet());
newSession.connect(hostInfo, user, password, database, 30000, new TransactionEventHandler() {
@Override
public void transactionCompleted() {
}
public void transactionBegun() {
}
});
newSession.sendCommand(new NativeMessageBuilder().buildComQuery(newSession.getSharedSendPacket(), "KILL QUERY " + this.session.getThreadId()),
false, 0);
setCancelStatus(CancelStatus.CANCELED_BY_USER);
} catch (IOException e) {
throw SQLExceptionsMapping.translateException(e, this.exceptionInterceptor);
} finally {
if (cancelStmt != null) {
cancelStmt.close();
}
if (cancelConn != null) {
cancelConn.close();
}
}
}
}
/**
* Pings live connections.
*/
public synchronized void doPing() throws SQLException {
SQLException se = null;
boolean foundHost = false;
int pingTimeout = this.currentConnection.getPropertySet().getIntegerReadableProperty(PropertyDefinitions.PNAME_loadBalancePingTimeout).getValue();
synchronized (this) {
for (HostInfo hi : this.hostsList) {
String host = hi.getHostPortPair();
ConnectionImpl conn = this.liveConnections.get(host);
if (conn == null) {
continue;
}
try {
if (pingTimeout == 0) {
conn.ping();
} else {
conn.pingInternal(true, pingTimeout);
}
foundHost = true;
} catch (SQLException e) {
// give up if it is the current connection, otherwise NPE faking resultset later.
if (host.equals(this.connectionsToHostsMap.get(this.currentConnection))) {
// clean up underlying connections, since connection pool won't do it
closeAllConnections();
this.isClosed = true;
this.closedReason = "Connection closed because ping of current connection failed.";
throw e;
}
// if the Exception is caused by ping connection lifetime checks, don't add to blacklist
if (e.getMessage().equals(Messages.getString("Connection.exceededConnectionLifetime"))) {
// only set the return Exception if it's null
if (se == null) {
se = e;
}
} else {
// overwrite the return Exception no matter what
se = e;
if (isGlobalBlacklistEnabled()) {
addToGlobalBlacklist(host);
}
}
// take the connection out of the liveConnections Map
this.liveConnections.remove(this.connectionsToHostsMap.get(conn));
}
}
}
// if there were no successful pings
if (!foundHost) {
closeAllConnections();
this.isClosed = true;
this.closedReason = "Connection closed due to inability to ping any active connections.";
// throw the stored Exception, if exists
if (se != null) {
throw se;
}
// or create a new SQLException and throw it, must be no liveConnections
((ConnectionImpl) this.currentConnection).throwConnectionClosedException();
}
}