mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Merge pull request #319 from wenshao/master
StatFilter mergeSql support tddl
This commit is contained in:
@@ -130,6 +130,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
private JdbcDataSourceStat dataSourceStat;
|
||||
|
||||
private boolean useGloalDataSourceStat = false;
|
||||
|
||||
public DruidDataSource(){
|
||||
this(false);
|
||||
}
|
||||
@@ -149,6 +151,22 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
this.setValidationQuery(property);
|
||||
}
|
||||
}
|
||||
{
|
||||
String property = System.getProperty("druid.useGloalDataSourceStat");
|
||||
if ("true".equals(property)) {
|
||||
this.setUseGloalDataSourceStat(true);
|
||||
} else if ("false".equals(property)) {
|
||||
this.setUseGloalDataSourceStat(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUseGloalDataSourceStat() {
|
||||
return useGloalDataSourceStat;
|
||||
}
|
||||
|
||||
public void setUseGloalDataSourceStat(boolean useGloalDataSourceStat) {
|
||||
this.useGloalDataSourceStat = useGloalDataSourceStat;
|
||||
}
|
||||
|
||||
public String getInitStackTrace() {
|
||||
@@ -435,7 +453,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
}
|
||||
|
||||
dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType);
|
||||
if (useGloalDataSourceStat) {
|
||||
dataSourceStat = JdbcDataSourceStat.getGlobal();
|
||||
} else {
|
||||
dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType);
|
||||
}
|
||||
|
||||
connections = new DruidConnectionHolder[maxActive];
|
||||
|
||||
@@ -486,12 +508,14 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
|
||||
private void createAndStartDestroyThread() {
|
||||
destoryConnectionThread = new DestroyConnectionThread("Druid-ConnectionPool-Destory");
|
||||
String threadName = "Druid-ConnectionPool-Destory-" + System.identityHashCode(this);
|
||||
destoryConnectionThread = new DestroyConnectionThread(threadName);
|
||||
destoryConnectionThread.start();
|
||||
}
|
||||
|
||||
protected void createAndStartCreatorThread() {
|
||||
createConnectionThread = new CreateConnectionThread("Druid-ConnectionPool-Create");
|
||||
String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this);
|
||||
createConnectionThread = new CreateConnectionThread(threadName);
|
||||
createConnectionThread.start();
|
||||
}
|
||||
|
||||
|
||||
+28
-1
@@ -17,17 +17,20 @@ package com.alibaba.druid.sql.dialect.mysql.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
|
||||
import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
|
||||
|
||||
public class MySqlParameterizedOutputVisitor extends MySqlOutputVisitor {
|
||||
|
||||
public MySqlParameterizedOutputVisitor() {
|
||||
public MySqlParameterizedOutputVisitor(){
|
||||
this(new StringBuilder());
|
||||
}
|
||||
|
||||
@@ -39,6 +42,30 @@ public class MySqlParameterizedOutputVisitor extends MySqlOutputVisitor {
|
||||
return ParameterizedOutputVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
String name = x.getName();
|
||||
if (x.getParent() instanceof SQLExprTableSource || x.getParent() instanceof SQLPropertyExpr) {
|
||||
int pos = name.lastIndexOf('_');
|
||||
if (pos != -1 && pos != name.length()) {
|
||||
boolean isNumber = true;
|
||||
for (int i = pos + 1; i < name.length(); ++i) {
|
||||
char ch = name.charAt(i);
|
||||
if (ch < '0' || ch > '9') {
|
||||
isNumber = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isNumber) {
|
||||
String realName = name.substring(0, pos);
|
||||
print(realName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
print(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLBinaryOpExpr x) {
|
||||
x = ParameterizedOutputVisitorUtils.merge(x);
|
||||
|
||||
|
||||
@@ -458,8 +458,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr astNode) {
|
||||
print(astNode.getName());
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
print(x.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,18 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
|
||||
|
||||
private final AtomicLong blobOpenCount = new AtomicLong();
|
||||
|
||||
private static JdbcDataSourceStat global = new JdbcDataSourceStat(
|
||||
"global",
|
||||
"global");
|
||||
|
||||
public static JdbcDataSourceStat getGlobal() {
|
||||
return global;
|
||||
}
|
||||
|
||||
public static void setGlobal(JdbcDataSourceStat value) {
|
||||
global = value;
|
||||
}
|
||||
|
||||
public JdbcDataSourceStat(String name, String url){
|
||||
this(name, url, null);
|
||||
}
|
||||
|
||||
@@ -36,17 +36,17 @@ import com.alibaba.druid.proxy.jdbc.DataSourceProxyImpl;
|
||||
|
||||
public final class JdbcStatManager implements JdbcStatManagerMBean {
|
||||
|
||||
private final AtomicLong sqlIdSeed = new AtomicLong(1000);
|
||||
private final AtomicLong sqlIdSeed = new AtomicLong(1000);
|
||||
|
||||
private final static JdbcStatManager instance = new JdbcStatManager();
|
||||
private final static JdbcStatManager instance = new JdbcStatManager();
|
||||
|
||||
private final JdbcConnectionStat connectionStat = new JdbcConnectionStat();
|
||||
private final JdbcResultSetStat resultSetStat = new JdbcResultSetStat();
|
||||
private final JdbcStatementStat statementStat = new JdbcStatementStat();
|
||||
private final JdbcConnectionStat connectionStat = new JdbcConnectionStat();
|
||||
private final JdbcResultSetStat resultSetStat = new JdbcResultSetStat();
|
||||
private final JdbcStatementStat statementStat = new JdbcStatementStat();
|
||||
|
||||
private final AtomicLong resetCount = new AtomicLong();
|
||||
private final AtomicLong resetCount = new AtomicLong();
|
||||
|
||||
public final ThreadLocal<JdbcStatContext> contextLocal = new ThreadLocal<JdbcStatContext>();
|
||||
public final ThreadLocal<JdbcStatContext> contextLocal = new ThreadLocal<JdbcStatContext>();
|
||||
|
||||
private JdbcStatManager(){
|
||||
|
||||
@@ -296,26 +296,52 @@ public final class JdbcStatManager implements JdbcStatManagerMBean {
|
||||
TabularType tabularType = new TabularType("SqlListStatistic", "SqlListStatistic", rowType, indexNames);
|
||||
TabularData data = new TabularDataSupport(tabularType);
|
||||
|
||||
for (DataSourceProxyImpl dataSource : DruidDriver.getProxyDataSources().values()) {
|
||||
Map<String, JdbcSqlStat> statMap = dataSource.getDataSourceStat().getSqlStatMap();
|
||||
JdbcDataSourceStat globalStat = JdbcDataSourceStat.getGlobal();
|
||||
{
|
||||
Map<String, JdbcSqlStat> statMap = globalStat.getSqlStatMap();
|
||||
for (Map.Entry<String, JdbcSqlStat> entry : statMap.entrySet()) {
|
||||
if (entry.getValue().getExecuteCount() == 0 && entry.getValue().getRunningCount() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Map<String, Object> map = entry.getValue().getData();
|
||||
map.put("URL", globalStat.getUrl());
|
||||
data.put(new CompositeDataSupport(JdbcSqlStat.getCompositeType(), map));
|
||||
}
|
||||
}
|
||||
|
||||
for (DataSourceProxyImpl dataSource : DruidDriver.getProxyDataSources().values()) {
|
||||
JdbcDataSourceStat druidDataSourceStat = dataSource.getDataSourceStat();
|
||||
|
||||
if (druidDataSourceStat == globalStat) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, JdbcSqlStat> statMap = druidDataSourceStat.getSqlStatMap();
|
||||
for (Map.Entry<String, JdbcSqlStat> entry : statMap.entrySet()) {
|
||||
if (entry.getValue().getExecuteCount() == 0 && entry.getValue().getRunningCount() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, Object> map = entry.getValue().getData();
|
||||
map.put("URL", dataSource.getUrl());
|
||||
data.put(new CompositeDataSupport(JdbcSqlStat.getCompositeType(), map));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (DruidDataSource dataSource : DruidDataSourceStatManager.getDruidDataSourceInstances()) {
|
||||
Map<String, JdbcSqlStat> statMap = dataSource.getDataSourceStat().getSqlStatMap();
|
||||
JdbcDataSourceStat druidDataSourceStat = dataSource.getDataSourceStat();
|
||||
|
||||
if (druidDataSourceStat == globalStat) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, JdbcSqlStat> statMap = druidDataSourceStat.getSqlStatMap();
|
||||
for (Map.Entry<String, JdbcSqlStat> entry : statMap.entrySet()) {
|
||||
if (entry.getValue().getExecuteCount() == 0 && entry.getValue().getRunningCount() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Map<String, Object> map = entry.getValue().getData();
|
||||
map.put("URL", dataSource.getUrl());
|
||||
data.put(new CompositeDataSupport(JdbcSqlStat.getCompositeType(), map));
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.alibaba.druid.bvt.filter;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.filter.stat.StatFilter;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class ReuseStatFilterTest extends TestCase {
|
||||
|
||||
private DruidDataSource dataSourceA;
|
||||
private DruidDataSource dataSourceB;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
dataSourceA = new DruidDataSource();
|
||||
dataSourceB = new DruidDataSource();
|
||||
|
||||
dataSourceA.setUrl("jdbc:mock:xxx_A");
|
||||
dataSourceB.setUrl("jdbc:mock:xxx_B");
|
||||
|
||||
StatFilter filter = new StatFilter();
|
||||
|
||||
dataSourceA.getProxyFilters().add(filter);
|
||||
dataSourceB.getProxyFilters().add(filter);
|
||||
|
||||
dataSourceA.init();
|
||||
dataSourceB.init();
|
||||
}
|
||||
|
||||
public void test_execute() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
JdbcUtils.close(dataSourceA);
|
||||
JdbcUtils.close(dataSourceB);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.alibaba.druid.bvt.proxy.filter;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.stat.JdbcDataSourceStat;
|
||||
import com.alibaba.druid.stat.JdbcStatManager;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class GlobalStatTest0 extends TestCase {
|
||||
|
||||
private DruidDataSource dataSourceA;
|
||||
private DruidDataSource dataSourceB;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
dataSourceA = new DruidDataSource();
|
||||
dataSourceA.setUrl("jdbc:mock:xx_A");
|
||||
dataSourceA.setFilters("stat");
|
||||
dataSourceA.setUseGloalDataSourceStat(true);
|
||||
|
||||
dataSourceB = new DruidDataSource();
|
||||
dataSourceB.setUrl("jdbc:mock:xx_A");
|
||||
dataSourceB.setFilters("stat");
|
||||
dataSourceB.setUseGloalDataSourceStat(true);
|
||||
}
|
||||
|
||||
public void test_execute() throws Exception {
|
||||
{
|
||||
Connection conn = dataSourceA.getConnection();
|
||||
PreparedStatement stmt = conn.prepareStatement("SELECT 1");
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
|
||||
}
|
||||
rs.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
}
|
||||
{
|
||||
Connection conn = dataSourceB.getConnection();
|
||||
PreparedStatement stmt = conn.prepareStatement("SELECT 1");
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
|
||||
}
|
||||
rs.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
}
|
||||
|
||||
Assert.assertSame(JdbcDataSourceStat.getGlobal(), dataSourceA.getDataSourceStat());
|
||||
Assert.assertSame(JdbcDataSourceStat.getGlobal(), dataSourceB.getDataSourceStat());
|
||||
|
||||
Assert.assertEquals(1, JdbcStatManager.getInstance().getSqlList().size());
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
JdbcUtils.close(dataSourceA);
|
||||
JdbcUtils.close(dataSourceB);
|
||||
}
|
||||
|
||||
}
|
||||
+20
-20
@@ -13,46 +13,46 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.druid.bvt.filter;
|
||||
package com.alibaba.druid.bvt.proxy.filter;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Statement;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.util.Histogram;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class PoolStatFilterTest extends TestCase {
|
||||
public class MergeStatFilterTest_tddl extends TestCase {
|
||||
|
||||
private DruidDataSource dataSource;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
dataSource = new DruidDataSource();
|
||||
|
||||
dataSource.setUrl("jdbc:mock:xxx");
|
||||
dataSource.setFilters("stat");
|
||||
|
||||
dataSource.init();
|
||||
dataSource.setUrl("jdbc:mock:xx");
|
||||
dataSource.setFilters("mergeStat");
|
||||
dataSource.setDbType("mysql");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
JdbcUtils.close(dataSource);
|
||||
dataSource.close();
|
||||
}
|
||||
|
||||
public void test_stat() throws Exception {
|
||||
|
||||
Assert.assertTrue(dataSource.isInited());
|
||||
|
||||
Histogram histogram = dataSource.getDataSourceStat().getConnectionHoldHistogram();
|
||||
|
||||
Assert.assertEquals(0, histogram.getValue(0));
|
||||
public void test_merge() throws Exception {
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
String tableName = "t_" + i;
|
||||
String sql = "select * from " + tableName + " where " + tableName + ".id = " + i;
|
||||
Connection conn = dataSource.getConnection();
|
||||
|
||||
Connection conn = dataSource.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute(sql);
|
||||
stmt.close();
|
||||
|
||||
conn.close();
|
||||
conn.close();
|
||||
}
|
||||
|
||||
Assert.assertEquals(1, dataSource.getDataSourceStat().getSqlStatMap().size());
|
||||
|
||||
Assert.assertEquals(1, histogram.getValue(0));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user