Notary metrics (#383)

* Track the distribution of the number of input states

* Log number of input states and commit duration

...and move the rollback

* Update schema
This commit is contained in:
Thomas Schroeter 2018-01-23 16:24:51 +00:00 committed by GitHub
parent c81e597199
commit a564c9bfd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,7 @@
package net.corda.node.services.transactions package net.corda.node.services.transactions
import com.codahale.metrics.MetricRegistry import com.codahale.metrics.MetricRegistry
import com.google.common.base.Stopwatch
import com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException import com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException
import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource import com.zaxxer.hikari.HikariDataSource
@ -20,6 +21,7 @@ import java.sql.BatchUpdateException
import java.sql.Connection import java.sql.Connection
import java.sql.SQLTransientConnectionException import java.sql.SQLTransientConnectionException
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit
/** /**
* Uniqueness provider backed by a MySQL database. It is intended to be used with a multi-master synchronously replicated * Uniqueness provider backed by a MySQL database. It is intended to be used with a multi-master synchronously replicated
@ -38,7 +40,7 @@ class MySQLUniquenessProvider(
private val createTableStatement = private val createTableStatement =
"CREATE TABLE IF NOT EXISTS committed_states (" + "CREATE TABLE IF NOT EXISTS committed_states (" +
"issue_tx_id BINARY(32) NOT NULL," + "issue_tx_id BINARY(32) NOT NULL," +
"issue_tx_output_id INT NOT NULL," + "issue_tx_output_id INT UNSIGNED NOT NULL," +
"consuming_tx_id BINARY(32) NOT NULL," + "consuming_tx_id BINARY(32) NOT NULL," +
"consuming_tx_input_id INT UNSIGNED NOT NULL," + "consuming_tx_input_id INT UNSIGNED NOT NULL," +
"consuming_party_name TEXT NOT NULL," + "consuming_party_name TEXT NOT NULL," +
@ -63,6 +65,8 @@ class MySQLUniquenessProvider(
private val connectionExceptionCounter = metrics.counter("$metricPrefix.ConnectionException") private val connectionExceptionCounter = metrics.counter("$metricPrefix.ConnectionException")
/** Track double spend attempts. Note that this will also include notarisation retries. */ /** Track double spend attempts. Note that this will also include notarisation retries. */
private val conflictCounter = metrics.counter("$metricPrefix.Conflicts") private val conflictCounter = metrics.counter("$metricPrefix.Conflicts")
/** Track the distribution of the number of input states **/
private val nrInputStates = metrics.histogram("$metricPrefix.NumberOfInputStates")
val dataSource = HikariDataSource(HikariConfig(configuration.dataSource)) val dataSource = HikariDataSource(HikariConfig(configuration.dataSource))
private val connectionRetries = configuration.connectionRetries private val connectionRetries = configuration.connectionRetries
@ -96,15 +100,18 @@ class MySQLUniquenessProvider(
} }
override fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party) { override fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party) {
val timer = commitTimer.time() val s = Stopwatch.createStarted()
try { try {
retryTransaction(CommitAll(states, txId, callerIdentity)) retryTransaction(CommitAll(states, txId, callerIdentity))
nrInputStates.update(states.size)
} catch (e: BatchUpdateException) { } catch (e: BatchUpdateException) {
log.info("Unable to commit input states, finding conflicts", e) log.info("Unable to commit input states, finding conflicts, txId: $txId", e)
conflictCounter.inc() conflictCounter.inc()
retryTransaction(FindConflicts(states)) retryTransaction(FindConflicts(states))
} finally { } finally {
timer.stop() val dt = s.stop().elapsed(TimeUnit.MILLISECONDS)
commitTimer.update(dt, TimeUnit.MILLISECONDS)
log.info("Processed notarisation request, txId: $txId, nrInputStates: ${states.size}, dt: $dt")
} }
} }
@ -114,12 +121,13 @@ class MySQLUniquenessProvider(
try { try {
tx.run(it) tx.run(it)
} catch (e: Exception) { } catch (e: Exception) {
it.rollback()
if (e is MySQLTransactionRollbackException) { if (e is MySQLTransactionRollbackException) {
log.warn("Rollback exception occurred, retrying", e) log.warn("Rollback exception occurred, retrying", e)
rollbackCounter.inc() rollbackCounter.inc()
continue continue
} else { } else {
log.warn("Attempting to rollback", e)
it.rollback()
throw e throw e
} }
} }