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
Show file tree
Hide file tree
Changes from all commits
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
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);
}
}