Skip to content

Commit

Permalink
Merge pull request #54 from instana/Informix_QueryOptimization
Browse files Browse the repository at this point in the history
Informix query optimization
  • Loading branch information
vivek-22 authored Jul 24, 2024
2 parents 5c56f55 + 7d103f9 commit 32cd3de
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,7 @@ private SemanticAttributes() {
public static final AttributeKey<Long> DB_CACHE_READ_RATIO = AttributeKey.longKey("db.cache.read.ratio");
public static final AttributeKey<Long> DB_CACHE_WRITE_RATIO = AttributeKey.longKey("db.cache.write.ratio");
public static final AttributeKey<Long> DB_LRU_WRITES = AttributeKey.longKey("db.lru.writes");
public static final AttributeKey<String> TOTAL_KB = AttributeKey.stringKey("total_kb");
public static final AttributeKey<String> USED_KB = AttributeKey.stringKey("used_kb");
public static final AttributeKey<String> TABLE_UTILIZATION = AttributeKey.stringKey("table_utilization");
}
27 changes: 13 additions & 14 deletions rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixDc.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,13 @@ public class InformixDc extends AbstractDbDc {
private static final Logger LOGGER = Logger.getLogger(InformixDc.class.getName());
private static final int DEFAULT_ELAPSED_TIME = 900;
private String tableSpaceSizeQuery;
private String tableSpaceUsedQuery;
private String tableSpaceUtilizationQuery;
private String tableSpaceMaxQuery;
private String sequentialScanQuery;
private String sequentialScanTableQuery;
private String sqlElapsedTimeQuery;
private boolean customPollRateEnabled = true;
private ScheduledExecutorService executorService;
private final BasicDataSource dataSource;
private final MetricsDataQueryConfig metricDataQueryConfig;

private final MetricsCollector metricCollector;

Expand All @@ -76,6 +74,8 @@ public InformixDc(Map<String, Object> properties, String dbSystem, String dbDriv
setDbConnUrl();

dataSource = getDataSource();
metricDataQueryConfig = new MetricsDataQueryConfig(tableSpaceSizeQuery,List.class,this.dataSource,SemanticAttributes.TOTAL_KB.getKey(),DB_TABLESPACE_SIZE_KEY,SemanticAttributes.USED_KB.getKey(),SemanticAttributes.TABLE_UTILIZATION.getKey());

if (getServiceInstanceId() == null) {
setServiceInstanceId(getDbAddress() + ":" + getDbPort() + "@" + getDbName());
}
Expand Down Expand Up @@ -103,13 +103,13 @@ private BasicDataSource getDataSource() {
private void registerMetricsMetadata() {
//Metrics via SQL
MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_SIZE_NAME,
new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_SIZE_KEY));
new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL,List.class,DB_TABLESPACE_SIZE_KEY));
MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_USED_NAME,
new MetricDataConfig(tableSpaceUsedQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_USED_KEY));
new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_USED_KEY));
MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_UTILIZATION_NAME,
new MetricDataConfig(tableSpaceUtilizationQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_UTILIZATION_KEY));
new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_UTILIZATION_KEY));
MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_MAX_NAME,
new MetricDataConfig(tableSpaceMaxQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_MAX_KEY));
new MetricDataConfig(tableSpaceSizeQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_MAX_KEY));
MetricsDataConfigRegister.subscribeMetricDataConfig(DB_SQL_ELAPSED_TIME_NAME,
new MetricDataConfig(sqlElapsedTimeQuery, MetricCollectionMode.SQL, List.class, DB_SQL_ELAPSED_TIME_KEY, SemanticAttributes.SQL_TEXT.getKey()));
MetricsDataConfigRegister.subscribeMetricDataConfig(DB_INSTANCE_COUNT_NAME,
Expand Down Expand Up @@ -240,9 +240,6 @@ private void parseCustomAttributes(Map<String, Object> properties) {
sequentialScanQuery = String.format(InformixUtil.DB_SEQ_SCAN_SQL, databaseName, sequentialScanCount);
sequentialScanTableQuery = String.format(InformixUtil.DB_SEQ_SCAN_TABLE_SQL, databaseName, sequentialScanCount);
tableSpaceSizeQuery = String.format(InformixUtil.TABLESPACE_SIZE_SQL, databaseName);
tableSpaceUsedQuery = String.format(InformixUtil.TABLESPACE_USED_SQL, databaseName);
tableSpaceUtilizationQuery = String.format(InformixUtil.TABLESPACE_UTILIZATION_SQL, databaseName);
tableSpaceMaxQuery = String.format(InformixUtil.TABLESPACE_MAX_SQL, databaseName);
sqlElapsedTimeQuery = String.format(InformixUtil.SQL_ELAPSED_TIME_SQL, elapsedTimeFrame, databaseName);
}

Expand Down Expand Up @@ -326,10 +323,12 @@ private void shortPollingInterval() {

@SuppressWarnings("unchecked")
private void longPollingInterval() {
getRawMetric(DB_TABLESPACE_SIZE_NAME).setValue((List<SimpleQueryResult>) metricCollector.collectMetrics(DB_TABLESPACE_SIZE_NAME));
getRawMetric(DB_TABLESPACE_USED_NAME).setValue((List<SimpleQueryResult>) metricCollector.collectMetrics(DB_TABLESPACE_USED_NAME));
getRawMetric(DB_TABLESPACE_UTILIZATION_NAME).setValue((List<SimpleQueryResult>) metricCollector.collectMetrics(DB_TABLESPACE_UTILIZATION_NAME));
getRawMetric(DB_TABLESPACE_MAX_NAME).setValue((List<SimpleQueryResult>) metricCollector.collectMetrics(DB_TABLESPACE_MAX_NAME));
//TODO: A method to execute the query, store it in object, call that object in subsequent lines
metricDataQueryConfig.fetchQueryResults();
getRawMetric(DB_TABLESPACE_SIZE_NAME).setValue((List<SimpleQueryResult>) metricDataQueryConfig.getResults(SemanticAttributes.TOTAL_KB.getKey()));
getRawMetric(DB_TABLESPACE_USED_NAME).setValue((List<SimpleQueryResult>) metricDataQueryConfig.getResults(SemanticAttributes.USED_KB.getKey()));
getRawMetric(DB_TABLESPACE_UTILIZATION_NAME).setValue((List<SimpleQueryResult>) metricDataQueryConfig.getResults(SemanticAttributes.TABLE_UTILIZATION.getKey()));
getRawMetric(DB_TABLESPACE_MAX_NAME).setValue((List<SimpleQueryResult>) metricDataQueryConfig.getResults(SemanticAttributes.TOTAL_KB.getKey()));
getRawMetric(DB_DATABASE_LOG_ENABLED_NAME).setValue((List<SimpleQueryResult>) metricCollector.collectMetrics(DB_DATABASE_LOG_ENABLED_NAME));
getRawMetric(DB_DATABASE_BUFF_LOG_ENABLED_NAME).setValue((List<SimpleQueryResult>) metricCollector.collectMetrics(DB_DATABASE_BUFF_LOG_ENABLED_NAME));
getRawMetric(DB_DATABASE_ANSI_COMPLAINT_NAME).setValue((List<SimpleQueryResult>) metricCollector.collectMetrics(DB_DATABASE_ANSI_COMPLAINT_NAME));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private InformixUtil() {
public static final String TRANSACTION_COUNT_SQL = "SELECT COUNT(1) FROM SYSTRANS;";
public static final String SQL_ELAPSED_TIME_SQL = "SELECT SQL_RUNTIME * 1000 AS ELAPSED_TIME_MILLIS, SQL_ID AS SQL_ID, SQL_STATEMENT AS SQL_TEXT FROM INFORMIX.SYSSQLTRACE WHERE SQL_FINISHTIME >= (DBINFO('UTC_CURRENT') - %s) AND SQL_DATABASE = %s ORDER BY ELAPSED_TIME_MILLIS DESC LIMIT 20;";
//Table Space Queries
public static final String TABLESPACE_SIZE_SQL = "SELECT (PT.NPTOTAL * PT.PAGESIZE) * 1024 AS TOTAL_KB, TABNAME FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;";
public static final String TABLESPACE_SIZE_SQL = "SELECT (PT.NPTOTAL * PT.PAGESIZE) * 1024 AS TOTAL_KB,TABNAME,(PT.NPUSED * PT.PAGESIZE) * 1024 AS USED_KB,CASE WHEN (PT.NPTOTAL > 0) THEN ((PT.NPUSED) / PT.NPTOTAL) * 100 ELSE 0 END AS TABLE_UTILIZATION FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;";
public static final String TABLESPACE_USED_SQL = "SELECT (PT.NPUSED * PT.PAGESIZE) * 1024 AS USED_KB, TABNAME FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;";
public static final String TABLESPACE_UTILIZATION_SQL = "SELECT CASE WHEN (PT.NPTOTAL > 0) THEN ((PT.NPUSED) / PT.NPTOTAL) * 100 ELSE 0 END AS TABLE_UTILIZATION, TABNAME FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;";
public static final String TABLESPACE_MAX_SQL = "SELECT (PT.NPTOTAL * PT.PAGESIZE) * 1024 AS TOTAL_KB, TABNAME FROM SYSMASTER:SYSPTNHDR PT INNER JOIN SYSMASTER:SYSTABNAMES TN ON TN.PARTNUM = PT.PARTNUM WHERE TN.DBSNAME = %s ORDER BY TABNAME DESC LIMIT 20;";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* (c) Copyright IBM Corp. 2024
* (c) Copyright Instana Inc.
*/

package com.instana.dc.rdb.impl.informix.metric.collection;
import static com.instana.dc.rdb.DbDcUtil.getMetricWithSql;
import static com.instana.dc.rdb.DbDcUtil.getSimpleMetricWithSql;
import com.instana.dc.SimpleQueryResult;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.dbcp2.BasicDataSource;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

/**
* This class which holds the meta data of a given metrics
*/
public class MetricsDataQueryConfig {

private static final Logger logger = Logger.getLogger(MetricsDataQueryConfig.class.getName());
private String query;
private final Class<?> returnType;
private String metricKey;
private String scriptName;
private final BasicDataSource dataSource;
private ResultSet rs;
private String[] attr;

private HashMap<String,List<SimpleQueryResult>> results;


public MetricsDataQueryConfig(String query, Class<?> returnType, BasicDataSource dataSource, String... attr) {
this.query = query;
this.returnType = returnType;
this.attr = attr;
this.dataSource = dataSource;
this.results = new HashMap<String,List<SimpleQueryResult>>();
for (int attrIndex = 0;attrIndex<attr.length;attrIndex++) {
this.results.put(this.attr[attrIndex],new ArrayList<>());
}
}

public void fetchQueryResults() {
try (Connection connection = this.dataSource.getConnection()) {

ResultSet rs = executeQuery(connection, this.query);
if (rs.isClosed()) {
logger.severe("getMetricWithSql: ResultSet is closed");
}
while (rs.next()) {
Object obj = rs.getObject(2);
if (obj == null) {
obj = "null";
}
if (obj instanceof String) {
obj = ((String) obj).trim();
}
for(int attrIndex = 0;attrIndex<this.attr.length;attrIndex++) {
if(attrIndex == 1) {
continue;
}
SimpleQueryResult result = new SimpleQueryResult((Number) rs.getObject(attrIndex+1));
result.setAttribute(this.attr[1], obj);
result.setKey(obj.toString());
List<SimpleQueryResult> ls = this.results.get(this.attr[attrIndex]);
ls.add(result);
this.results.put(this.attr[attrIndex],ls);
}
}
}
catch (SQLException exp) {
logger.log(Level.SEVERE, "Unable to execute the sql command, Exception: " + exp);
}
}

public static ResultSet executeQuery(Connection connection, String query) throws SQLException {
Statement statement = connection.createStatement();
return statement.executeQuery(query);
}


public String getMetricKey() {
return metricKey;
}

public String[] getAttr() {
return attr;
}

public String getQuery() {
return query;
}

public Class<?> getReturnType() {
return returnType;
}

public List<SimpleQueryResult> getResults(String key) {
return this.results.get(key);
}
}

0 comments on commit 32cd3de

Please sign in to comment.