diff --git a/docker/build-run-benchmark-with-docker.sh b/docker/build-run-benchmark-with-docker.sh index 7f90eca44..1bd0e40bc 100755 --- a/docker/build-run-benchmark-with-docker.sh +++ b/docker/build-run-benchmark-with-docker.sh @@ -93,6 +93,7 @@ BUILD_IMAGE=false EXTRA_DOCKER_ARGS="--network=host $EXTRA_DOCKER_ARGS" \ --config "config/sample_${benchmark}_config.xml" --bench "$benchmark" \ --create=false --load=false --execute=true \ --sample 1 --interval-monitor 1000 \ + --monitor-type advanced \ --json-histograms results/histograms.json rc=$? wait # for the interrupt script, if any diff --git a/src/main/java/com/oltpbenchmark/api/collectors/monitoring/MonitorGen.java b/src/main/java/com/oltpbenchmark/api/collectors/monitoring/MonitorGen.java index 7e002634b..57eac6040 100644 --- a/src/main/java/com/oltpbenchmark/api/collectors/monitoring/MonitorGen.java +++ b/src/main/java/com/oltpbenchmark/api/collectors/monitoring/MonitorGen.java @@ -21,6 +21,9 @@ public static Monitor getMonitor( case ADVANCED: { switch (conf.getDatabaseType()) { + case MARIADB: + case MYSQL: + return new MySQLMonitor(monitorInfo, testState, workers, conf); case SQLSERVER: return new SQLServerMonitor(monitorInfo, testState, workers, conf); case POSTGRES: diff --git a/src/main/java/com/oltpbenchmark/api/collectors/monitoring/MySQLMonitor.java b/src/main/java/com/oltpbenchmark/api/collectors/monitoring/MySQLMonitor.java new file mode 100644 index 000000000..295c4eed8 --- /dev/null +++ b/src/main/java/com/oltpbenchmark/api/collectors/monitoring/MySQLMonitor.java @@ -0,0 +1,95 @@ +package com.oltpbenchmark.api.collectors.monitoring; + +import com.oltpbenchmark.BenchmarkState; +import com.oltpbenchmark.WorkloadConfiguration; +import com.oltpbenchmark.api.BenchmarkModule; +import com.oltpbenchmark.api.Worker; +import com.oltpbenchmark.util.MonitorInfo; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Implementation of a monitor specific to PostgreSQL. Uses the 'pg_stat_statements' add-on to + * extract relevant query and system information. + */ +public class MySQLMonitor extends DatabaseMonitor { + + // TODO: add support for per-query metrics using performance_schema + + // TODO: Expand to SHOW ENGINE INNODB STATUS as well? + private final String MYSQL_SYSTEM_METRICS = "SHOW GLOBAL STATUS;"; + + private final List repeatedSystemProperties; + + public MySQLMonitor( + MonitorInfo monitorInfo, + BenchmarkState testState, + List> workers, + WorkloadConfiguration conf) { + super(monitorInfo, testState, workers, conf); + + this.repeatedSystemProperties = + new ArrayList() { + { + add("bytes_received"); + add("bytes_sent"); + add("com_select"); + // ... + // TODO: Add more properties from SHOW STATUS here + } + }; + } + + @Override + protected String getCleanupStmt() { + // FIXME: Currently a no-op. + return "SELECT 1"; + } + + /** + * Extract system events using the extraction query and properties defined above, will fail + * gracefully to not interrupt benchmarking. + */ + private void extractPerformanceMetrics(Instant instant) { + ImmutableRepeatedSystemEvent.Builder repeatedSystemEventBuilder = + ImmutableRepeatedSystemEvent.builder(); + repeatedSystemEventBuilder.instant(instant); + + // Extract OS performance events. + Map propertyValues = new HashMap(); + try (PreparedStatement stmt = conn.prepareStatement(MYSQL_SYSTEM_METRICS)) { + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + // Add property values. + String metric_name = rs.getString(1).trim(); + if (this.repeatedSystemProperties.contains(metric_name)) { + propertyValues.put(metric_name, rs.getString(2)); + } + } + } catch (SQLException sqlError) { + LOG.error("Error when extracting system metrics from MySQL."); + LOG.error(sqlError.getMessage()); + } + repeatedSystemEventBuilder.propertyValues(propertyValues); + this.repeatedSystemEvents.add(repeatedSystemEventBuilder.build()); + } + + @Override + protected void runExtraction() { + Instant time = Instant.now(); + + // TODO: extractQueryMetrics(time); + extractPerformanceMetrics(time); + } + + @Override + protected void writeSystemMetrics() { + this.writeRepeatedSystemEventsToCSV(); + } +}