Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Informix query optimization #54

Merged
merged 4 commits into from
Jul 24, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Tablespace Query Optimization
vivek mahalingam authored and vivek mahalingam committed Jul 22, 2024
commit cde6bf580d08d0371121e658878c289a388ec02b
Original file line number Diff line number Diff line change
@@ -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");
}
22 changes: 15 additions & 7 deletions rdb/src/main/java/com/instana/dc/rdb/impl/informix/InformixDc.java
Original file line number Diff line number Diff line change
@@ -63,6 +63,7 @@ public class InformixDc extends AbstractDbDc {
private boolean customPollRateEnabled = true;
private ScheduledExecutorService executorService;
private final BasicDataSource dataSource;
private final MetricsDataQueryConfig metricDataQueryConfig;

private final MetricsCollector metricCollector;

@@ -76,6 +77,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());
}
@@ -103,13 +106,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));
MetricsDataConfigRegister.subscribeMetricDataConfig(DB_TABLESPACE_UTILIZATION_NAME,
new MetricDataConfig(tableSpaceUtilizationQuery, MetricCollectionMode.SQL, List.class, DB_TABLESPACE_UTILIZATION_KEY));
new MetricDataConfig(tableSpaceUsedQuery, 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(tableSpaceUsedQuery, 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,
@@ -326,10 +329,15 @@ 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(0));
getRawMetric(DB_TABLESPACE_USED_NAME).setValue((List<SimpleQueryResult>) metricDataQueryConfig.getResults(2));
getRawMetric(DB_TABLESPACE_UTILIZATION_NAME).setValue((List<SimpleQueryResult>) metricDataQueryConfig.getResults(3));
getRawMetric(DB_TABLESPACE_MAX_NAME).setValue((List<SimpleQueryResult>) metricDataQueryConfig.getResults(0));
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));
Original file line number Diff line number Diff line change
@@ -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;";
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* (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.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 List<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 ArrayList<>();
for (int attrIndex = 0;attrIndex<attr.length;attrIndex++) {
this.results.add(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());
this.results.get(attrIndex).add(result);
}
}
}
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(int n) {
return this.results.get(n);
}
}