diff --git a/src/main/java/com/oltpbenchmark/DBWorkload.java b/src/main/java/com/oltpbenchmark/DBWorkload.java index 7427f2c64..97b82b567 100644 --- a/src/main/java/com/oltpbenchmark/DBWorkload.java +++ b/src/main/java/com/oltpbenchmark/DBWorkload.java @@ -782,6 +782,8 @@ private static void writeHistograms(Results r) { sb.append(StringUtil.bold("Unknown Status Transactions:")).append("\n").append(r.getUnknown()).append("\n\n"); + sb.append(StringUtil.bold("Zero Rows Transactions:")).append("\n").append(r.getZeroRows()).append("\n\n"); + if (!r.getAbortMessages().isEmpty()) { sb.append("\n\n").append(StringUtil.bold("User Aborts:")).append("\n").append(r.getAbortMessages()); } @@ -845,12 +847,6 @@ private static void writeOutputs(Results r, List activeTXTypes, rw.writeSamples(ps); } - String summaryFileName = baseFileName + ".summary.json"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, summaryFileName))) { - LOG.info("Output summary data into file: {}", summaryFileName); - rw.writeSummary(ps); - } - String paramsFileName = baseFileName + ".params.json"; try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, paramsFileName))) { LOG.info("Output DBMS parameters into file: {}", paramsFileName); @@ -865,7 +861,14 @@ private static void writeOutputs(Results r, List activeTXTypes, } } + String summaryFileName = baseFileName + ".summary.json"; + if (name.equalsIgnoreCase("featurebench")) { + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, summaryFileName))) { + LOG.info("Output summary data into file: {}", summaryFileName); + rw.writeSummaryFeaturebench(ps); + } + String configFileName = baseFileName + ".config.yaml"; try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, configFileName))) { LOG.info("Output benchmark config into file: {}", configFileName); @@ -893,6 +896,11 @@ private static void writeOutputs(Results r, List activeTXTypes, } } else { + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, summaryFileName))) { + LOG.info("Output summary data into file: {}", summaryFileName); + rw.writeSummary(ps); + } + String configFileName = baseFileName + ".config.xml"; try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, configFileName))) { LOG.info("Output benchmark config into file: {}", configFileName); diff --git a/src/main/java/com/oltpbenchmark/Results.java b/src/main/java/com/oltpbenchmark/Results.java index 913ae22b7..c3757b181 100644 --- a/src/main/java/com/oltpbenchmark/Results.java +++ b/src/main/java/com/oltpbenchmark/Results.java @@ -39,6 +39,7 @@ public final class Results { private final Histogram retry = new Histogram<>(false); private final Histogram error = new Histogram<>(false); private final Histogram retryDifferent = new Histogram<>(false); + private final Histogram zeroRows = new Histogram<>(true); private final Map> abortMessages = new HashMap<>(); private final FeaturebenchAdditionalResults featurebenchAdditionalResults = new FeaturebenchAdditionalResults(); @@ -84,6 +85,10 @@ public Histogram getRetryDifferent() { return retryDifferent; } + public Histogram getZeroRows() { + return zeroRows; + } + public FeaturebenchAdditionalResults getFeaturebenchAdditionalResults() { return featurebenchAdditionalResults; } @@ -96,6 +101,10 @@ public double requestsPerSecondThroughput() { return (double) measuredRequests / (double) nanoseconds * 1e9; } + public double requestsPerSecondThroughputFeaturebench() { + return (double) (success.getSampleCount() + zeroRows.getSampleCount()) / (double) nanoseconds * 1e9; + } + public double requestsPerSecondGoodput() { return (double) success.getSampleCount() / (double) nanoseconds * 1e9; } diff --git a/src/main/java/com/oltpbenchmark/ThreadBench.java b/src/main/java/com/oltpbenchmark/ThreadBench.java index 299257ad2..568902fec 100644 --- a/src/main/java/com/oltpbenchmark/ThreadBench.java +++ b/src/main/java/com/oltpbenchmark/ThreadBench.java @@ -328,6 +328,7 @@ private Results runRateLimitedMultiPhase() { results.getAbort().putAll(txnTypes, 0); results.getError().putAll(txnTypes, 0); results.getRetryDifferent().putAll(txnTypes, 0); + results.getZeroRows().putAll(txnTypes, 0); for (Worker w : workers) { results.getUnknown().putHistogram(w.getTransactionUnknownHistogram()); @@ -336,6 +337,7 @@ private Results runRateLimitedMultiPhase() { results.getAbort().putHistogram(w.getTransactionAbortHistogram()); results.getError().putHistogram(w.getTransactionErrorHistogram()); results.getRetryDifferent().putHistogram(w.getTransactionRetryDifferentHistogram()); + results.getZeroRows().putHistogram(w.getTransactionZeroRowsHistogram()); results.getFeaturebenchAdditionalResults().setJsonResultsList(w.featurebenchAdditionalResults.getJsonResultsList()); } diff --git a/src/main/java/com/oltpbenchmark/api/Worker.java b/src/main/java/com/oltpbenchmark/api/Worker.java index 13d72e73b..b1e09d5b5 100644 --- a/src/main/java/com/oltpbenchmark/api/Worker.java +++ b/src/main/java/com/oltpbenchmark/api/Worker.java @@ -56,10 +56,12 @@ public abstract class Worker implements Runnable { private final Histogram txnAbort = new Histogram<>(); private final Histogram txnRetry = new Histogram<>(); private final Histogram txnErrors = new Histogram<>(); + private final Histogram txnZeroRows = new Histogram<>(); private final Histogram txtRetryDifferent = new Histogram<>(); protected Connection conn = null; private WorkloadState workloadState; private LatencyRecord latencies; + boolean isFeaturebenchWorkload = false; private boolean seenDone = false; public final FeaturebenchAdditionalResults featurebenchAdditionalResults = new FeaturebenchAdditionalResults(); @@ -71,9 +73,11 @@ public Worker(T benchmark, int id) { this.currStatement = null; this.transactionTypes = this.configuration.getTransTypes(); boolean autoCommitVal = false; + if (this.benchmark.getBenchmarkName().equalsIgnoreCase("featurebench") && this.benchmark.getWorkloadConfiguration().getXmlConfig().containsKey("microbenchmark/properties/setAutoCommit")) { autoCommitVal = this.benchmark.getWorkloadConfiguration().getXmlConfig().getBoolean("microbenchmark/properties/setAutoCommit"); + this.isFeaturebenchWorkload = true; } if (!this.configuration.getNewConnectionPerTxn()) { try { @@ -171,6 +175,9 @@ public final Histogram getTransactionRetryDifferentHistogram() return (this.txtRetryDifferent); } + public final Histogram getTransactionZeroRowsHistogram() { + return (this.txnZeroRows); + } /** * Stop executing the current statement. */ @@ -280,7 +287,7 @@ public final void run() { long start = System.nanoTime(); - doWork(configuration.getDatabaseType(), transactionType); + TransactionStatus transactionStatus = doWork(configuration.getDatabaseType(), transactionType); long end = System.nanoTime(); @@ -305,8 +312,15 @@ public final void run() { break; } if (preState == MEASURE && postPhase.getId() == prePhase.getId()) { - latencies.addLatency(transactionType.getId(), start, end, this.id, prePhase.getId()); - intervalRequests.incrementAndGet(); + if (this.isFeaturebenchWorkload) { + if (transactionStatus == TransactionStatus.SUCCESS || transactionStatus == TransactionStatus.ZERO_ROWS) { + latencies.addLatency(transactionType.getId(), start, end, this.id, prePhase.getId()); + intervalRequests.incrementAndGet(); + } + } else { + latencies.addLatency(transactionType.getId(), start, end, this.id, prePhase.getId()); + intervalRequests.incrementAndGet(); + } } if (prePhase.isLatencyRun()) { workloadState.startColdQuery(); @@ -386,8 +400,8 @@ private TransactionType getTransactionType(SubmittedProcedure pieceOfWork, Phase * @param databaseType TODO * @param transactionType TODO */ - protected final void doWork(DatabaseType databaseType, TransactionType transactionType) { - + protected final TransactionStatus doWork(DatabaseType databaseType, TransactionType transactionType) { + TransactionStatus status = TransactionStatus.UNKNOWN; try { int retryCount = 0; int maxRetryCount = configuration.getMaxRetries(); @@ -399,8 +413,7 @@ protected final void doWork(DatabaseType databaseType, TransactionType transacti } while (retryCount < maxRetryCount && this.workloadState.getGlobalState() != State.DONE) { - - TransactionStatus status = TransactionStatus.UNKNOWN; + status = TransactionStatus.UNKNOWN; if (this.conn == null) { try { @@ -482,6 +495,7 @@ protected final void doWork(DatabaseType databaseType, TransactionType transacti case RETRY -> this.txnRetry.put(transactionType); case RETRY_DIFFERENT -> this.txtRetryDifferent.put(transactionType); case ERROR -> this.txnErrors.put(transactionType); + case ZERO_ROWS -> this.txnZeroRows.put(transactionType); } } @@ -492,7 +506,7 @@ protected final void doWork(DatabaseType databaseType, TransactionType transacti throw new RuntimeException(msg, ex); } - + return status; } private boolean isRetryable(SQLException ex) { @@ -516,6 +530,7 @@ private boolean isRetryable(SQLException ex) { // MySQL ER_LOCK_WAIT_TIMEOUT return true; } else if(errorCode > 0 && !sqlState.isEmpty()) { + // Added by Yugabyte to retry on all errors return true; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/featurebench/FeatureBenchWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/featurebench/FeatureBenchWorker.java index a847b2c44..caec8d075 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/featurebench/FeatureBenchWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/featurebench/FeatureBenchWorker.java @@ -246,28 +246,19 @@ protected TransactionStatus executeWork(Connection conn, TransactionType txnType List baseUtils = query.getBaseUtils(); int count = query.getCount(); for (int i = 0; i < count; i++) { - for (int j = 0; j < baseUtils.size(); j++) { + for (int j = 0; j < baseUtils.size(); j++) stmt.setObject(j + 1, baseUtils.get(j).get()); - } if (query.isSelectQuery()) { ResultSet rs = stmt.executeQuery(); int countSet = 0; - while (rs.next()) { - countSet++; - } - if (countSet == 0) { - isRetry = true; - } + while (rs.next()) countSet++; + if (countSet == 0) return TransactionStatus.ZERO_ROWS; } else { int updatedRows = stmt.executeUpdate(); - if (updatedRows == 0) { - isRetry = true; - } + if (updatedRows == 0) return TransactionStatus.ZERO_ROWS; } } } - if (isRetry) - return TransactionStatus.RETRY; } catch (ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException | diff --git a/src/main/java/com/oltpbenchmark/types/TransactionStatus.java b/src/main/java/com/oltpbenchmark/types/TransactionStatus.java index df3745f00..d6ef1d6ab 100644 --- a/src/main/java/com/oltpbenchmark/types/TransactionStatus.java +++ b/src/main/java/com/oltpbenchmark/types/TransactionStatus.java @@ -49,5 +49,10 @@ public enum TransactionStatus { /** * Transaction encountered an error and was not retried */ - ERROR + ERROR, + + /** + * Query returned ZERO_ROWS + */ + ZERO_ROWS } diff --git a/src/main/java/com/oltpbenchmark/util/ResultWriter.java b/src/main/java/com/oltpbenchmark/util/ResultWriter.java index 8209327da..04e42dda5 100644 --- a/src/main/java/com/oltpbenchmark/util/ResultWriter.java +++ b/src/main/java/com/oltpbenchmark/util/ResultWriter.java @@ -124,6 +124,23 @@ public void writeSummary(PrintStream os) { os.println(JSONUtil.format(JSONUtil.toJSONString(summaryMap))); } + public void writeSummaryFeaturebench(PrintStream os) { + Map summaryMap = new TreeMap<>(); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + Date now = new Date(); + summaryMap.put("Current Timestamp (milliseconds)", now.getTime()); + summaryMap.put("DBMS Type", dbType); + summaryMap.put("DBMS Version", collector.collectVersion()); + summaryMap.put("Benchmark Type", benchType); + summaryMap.put("Latency Distribution", results.getDistributionStatistics().toMap()); + summaryMap.put("Throughput (requests/second)", results.requestsPerSecondThroughputFeaturebench()); + summaryMap.put("Goodput (requests/second)", results.requestsPerSecondGoodput()); + for (String field : BENCHMARK_KEY_FIELD) { + summaryMap.put(field, expConf.getString(field)); + } + os.println(JSONUtil.format(JSONUtil.toJSONString(summaryMap))); + } + public void writeResults(int windowSizeSeconds, PrintStream out) { writeResults(windowSizeSeconds, out, TransactionType.INVALID); } @@ -245,7 +262,7 @@ public Map writeDetailedSummary(PrintStream os) { summaryMap.put("DBMS Version", collector.collectVersion()); summaryMap.put("Benchmark Type", benchType); summaryMap.put("Latency Distribution", results.getDistributionStatistics().toMap()); - summaryMap.put("Throughput (requests/second)", results.requestsPerSecondThroughput()); + summaryMap.put("Throughput (requests/second)", results.requestsPerSecondThroughputFeaturebench()); summaryMap.put("Goodput (requests/second)", results.requestsPerSecondGoodput()); for (String field : BENCHMARK_KEY_FIELD) { summaryMap.put(field, expConf.getString(field)); @@ -253,6 +270,13 @@ public Map writeDetailedSummary(PrintStream os) { Map detailedSummaryMap = new TreeMap<>(); Map metadata = new TreeMap<>(); metadata.put("yaml_version", expConf.getString("yaml_version", "v1.0")); + metadata.put("Completed Transactions", results.getSuccess().getSampleCount()); + metadata.put("Aborted Transactions", results.getAbort().getSampleCount()); + metadata.put("Rejected Transactions (Server Retry)", results.getRetry().getSampleCount()); + metadata.put("Rejected Transactions (Retry Different)", results.getRetryDifferent().getSampleCount()); + metadata.put("Unexpected SQL Errors", results.getError().getSampleCount()); + metadata.put("Unknown Status Transactions", results.getUnknown().getSampleCount()); + metadata.put("Zero Rows Returned", results.getZeroRows().getSampleCount()); detailedSummaryMap.put("metadata", metadata); detailedSummaryMap.put("Summary", summaryMap); detailedSummaryMap.put("queries", results.getFeaturebenchAdditionalResults().getJsonResultsList());