Skip to content

Commit 2e350a5

Browse files
committed
Fix for Bug#29329326, PLEASE AVOID SHOW PROCESSLIST IF POSSIBLE.
1 parent a8aed8b commit 2e350a5

File tree

5 files changed

+77
-26
lines changed

5 files changed

+77
-26
lines changed

CHANGES

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
Version 8.0.16
55

6+
- Fix for Bug#29329326, PLEASE AVOID SHOW PROCESSLIST IF POSSIBLE.
7+
68
- WL#12460, DevAPI: Support new session reset functionality.
79

810
- WL#12459, DevAPI: Support connection-attributes.

src/main/core-api/java/com/mysql/cj/protocol/SocketMetadata.java

+20-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program is free software; you can redistribute it and/or modify it under
55
* the terms of the GNU General Public License, version 2.0, as published by the
@@ -51,38 +51,36 @@ default boolean isLocallyConnected(Session sess, String processHost) {
5151
int endIndex = processHost.lastIndexOf(":");
5252
if (endIndex != -1) {
5353
processHost = processHost.substring(0, endIndex);
54+
}
5455

55-
try {
56+
try {
5657

57-
InetAddress[] whereMysqlThinksIConnectedFrom = InetAddress.getAllByName(processHost);
58+
InetAddress[] whereMysqlThinksIConnectedFrom = InetAddress.getAllByName(processHost);
5859

59-
SocketAddress remoteSocketAddr = sess.getRemoteSocketAddress();
60+
SocketAddress remoteSocketAddr = sess.getRemoteSocketAddress();
6061

61-
if (remoteSocketAddr instanceof InetSocketAddress) {
62-
InetAddress whereIConnectedTo = ((InetSocketAddress) remoteSocketAddr).getAddress();
62+
if (remoteSocketAddr instanceof InetSocketAddress) {
63+
InetAddress whereIConnectedTo = ((InetSocketAddress) remoteSocketAddr).getAddress();
6364

64-
for (InetAddress hostAddr : whereMysqlThinksIConnectedFrom) {
65-
if (hostAddr.equals(whereIConnectedTo)) {
66-
sess.getLog().logDebug(Messages.getString("SocketMetadata.1", new Object[] { hostAddr, whereIConnectedTo }));
67-
return true;
68-
}
69-
sess.getLog().logDebug(Messages.getString("SocketMetadata.2", new Object[] { hostAddr, whereIConnectedTo }));
65+
for (InetAddress hostAddr : whereMysqlThinksIConnectedFrom) {
66+
if (hostAddr.equals(whereIConnectedTo)) {
67+
sess.getLog().logDebug(Messages.getString("SocketMetadata.1", new Object[] { hostAddr, whereIConnectedTo }));
68+
return true;
7069
}
71-
72-
} else {
73-
sess.getLog().logDebug(Messages.getString("SocketMetadata.3", new Object[] { remoteSocketAddr }));
70+
sess.getLog().logDebug(Messages.getString("SocketMetadata.2", new Object[] { hostAddr, whereIConnectedTo }));
7471
}
7572

76-
return false;
77-
} catch (UnknownHostException e) {
78-
sess.getLog().logWarn(Messages.getString("Connection.CantDetectLocalConnect", new Object[] { processHost }), e);
79-
80-
return false;
73+
} else {
74+
sess.getLog().logDebug(Messages.getString("SocketMetadata.3", new Object[] { remoteSocketAddr }));
8175
}
8276

77+
return false;
78+
} catch (UnknownHostException e) {
79+
sess.getLog().logWarn(Messages.getString("Connection.CantDetectLocalConnect", new Object[] { processHost }), e);
80+
81+
return false;
8382
}
84-
sess.getLog().logWarn(Messages.getString("SocketMetadata.4", new Object[] { processHost }));
85-
return false;
83+
8684
}
8785

8886
return false;

src/main/core-impl/java/com/mysql/cj/NativeSession.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,9 @@ public boolean configureClientCharacterSet(boolean dontCheckServerMatch) {
530530

531531
this.characterEncoding.setValue(realJavaEncoding);
532532
} /* not utf-8 */else {
533-
String mysqlCharsetName = connectionCollationSuffix.length() > 0 ? connectionCollationCharset : CharsetMapping
534-
.getMysqlCharsetForJavaEncoding(realJavaEncoding.toUpperCase(Locale.ENGLISH), getServerSession().getServerVersion());
533+
String mysqlCharsetName = connectionCollationSuffix.length() > 0 ? connectionCollationCharset
534+
: CharsetMapping.getMysqlCharsetForJavaEncoding(realJavaEncoding.toUpperCase(Locale.ENGLISH),
535+
getServerSession().getServerVersion());
535536

536537
if (mysqlCharsetName != null) {
537538

@@ -815,6 +816,7 @@ public void loadServerVariables(Object syncMutex, String version) {
815816
queryBuf.append(", @@lower_case_table_names AS lower_case_table_names");
816817
queryBuf.append(", @@max_allowed_packet AS max_allowed_packet");
817818
queryBuf.append(", @@net_write_timeout AS net_write_timeout");
819+
queryBuf.append(", @@performance_schema AS performance_schema");
818820
if (!versionMeetsMinimum(8, 0, 3)) {
819821
queryBuf.append(", @@query_cache_size AS query_cache_size");
820822
queryBuf.append(", @@query_cache_type AS query_cache_type");
@@ -1045,7 +1047,16 @@ private String findProcessHost(long threadId) {
10451047
try {
10461048
String processHost = null;
10471049

1048-
NativePacketPayload resultPacket = sendCommand(this.commandBuilder.buildComQuery(null, "SHOW PROCESSLIST"), false, 0);
1050+
String ps = this.protocol.getServerSession().getServerVariable("performance_schema");
1051+
1052+
NativePacketPayload resultPacket = versionMeetsMinimum(5, 6, 0) // performance_schema.threads in MySQL 5.5 does not contain PROCESSLIST_HOST column
1053+
&& ps != null && ("1".contentEquals(ps) || "ON".contentEquals(ps))
1054+
? sendCommand(this.commandBuilder.buildComQuery(null,
1055+
"select PROCESSLIST_ID, PROCESSLIST_USER, PROCESSLIST_HOST from performance_schema.threads where PROCESSLIST_ID="
1056+
+ threadId),
1057+
false, 0)
1058+
: sendCommand(this.commandBuilder.buildComQuery(null, "SHOW PROCESSLIST"), false, 0);
1059+
10491060
Resultset rs = ((NativeProtocol) this.protocol).readAllResults(-1, false, resultPacket, false, null, new ResultsetFactory(Type.FORWARD_ONLY, null));
10501061

10511062
ValueFactory<Long> lvf = new LongValueFactory(getPropertySet());

src/main/resources/com/mysql/cj/LocalizedErrorMessages.properties

-1
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,6 @@ SocketMetadata.0=Using 'host' value of ''{0}'' to determine locality of connecti
536536
SocketMetadata.1=Locally connected - HostAddress({0}).equals(whereIconnectedTo({1})
537537
SocketMetadata.2=Attempted locally connected check failed - ! HostAddress({0}).equals(whereIconnectedTo({1})
538538
SocketMetadata.3=Remote socket address {0} is not an inet socket address
539-
SocketMetadata.4=No port number present in 'host' from SHOW PROCESSLIST ''{0}'', unable to determine whether locally connected
540539

541540
Statement.0=Connection is closed.
542541
Statement.2=Unsupported character encoding ''{0}''

src/test/java/testsuite/regression/ConnectionRegressionTest.java

+41
Original file line numberDiff line numberDiff line change
@@ -11322,4 +11322,45 @@ public void testBug93007() throws Exception {
1132211322
conn2.close();
1132311323

1132411324
}
11325+
11326+
/**
11327+
* Tests fix for Bug#29329326, PLEASE AVOID SHOW PROCESSLIST IF POSSIBLE.
11328+
*
11329+
* @throws Exception
11330+
*/
11331+
public void testBug29329326() throws Exception {
11332+
Properties p = new Properties();
11333+
p.setProperty(PropertyKey.queryInterceptors.getKeyName(), Bug29329326QueryInterceptor.class.getName());
11334+
11335+
JdbcConnection c = (JdbcConnection) getConnectionWithProps(p);
11336+
Bug29329326QueryInterceptor qi = (Bug29329326QueryInterceptor) c.getQueryInterceptorsInstances().get(0);
11337+
assertTrue("SHOW PROCESSLIST was issued during connection establishing", qi.cnt == 0);
11338+
11339+
((com.mysql.cj.jdbc.ConnectionImpl) c).isServerLocal();
11340+
11341+
String ps = ((MysqlConnection) c).getSession().getServerSession().getServerVariable("performance_schema");
11342+
if (versionMeetsMinimum(5, 6, 0) // performance_schema.threads in MySQL 5.5 does not contain PROCESSLIST_HOST column
11343+
&& ps != null && ("1".contentEquals(ps) || "ON".contentEquals(ps))) {
11344+
assertTrue("SHOW PROCESSLIST was issued by isServerLocal()", qi.cnt == 0);
11345+
} else {
11346+
assertTrue("SHOW PROCESSLIST wasn't issued by isServerLocal()", qi.cnt > 0);
11347+
}
11348+
}
11349+
11350+
/**
11351+
* Counts the number of issued "SHOW PROCESSLIST" statements.
11352+
*/
11353+
public static class Bug29329326QueryInterceptor extends BaseQueryInterceptor {
11354+
int cnt = 0;
11355+
11356+
@Override
11357+
public <M extends Message> M preProcess(M queryPacket) {
11358+
String sql = StringUtils.toString(queryPacket.getByteBuffer(), 1, (queryPacket.getPosition() - 1));
11359+
if (sql.contains("SHOW PROCESSLIST")) {
11360+
this.cnt++;
11361+
}
11362+
return null;
11363+
}
11364+
}
11365+
1132511366
}

0 commit comments

Comments
 (0)