Aaron Schulz has uploaded a new change for review.
https://gerrit.wikimedia.org/r/185342
Change subject: Added query/connection expectation support to
TransactionProfiler
......................................................................
Added query/connection expectation support to TransactionProfiler
* Master connections/writes on read requests will now be logged to get
visibility
into code the reduces performance and site availability.
Change-Id: Ic2ae95c33facbb54e062aef2ce67d6182caa044a
---
M includes/MediaWiki.php
M includes/db/Database.php
M includes/profiler/TransactionProfiler.php
3 files changed, 107 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/42/185342/1
diff --git a/includes/MediaWiki.php b/includes/MediaWiki.php
index d94443b..7789bcf 100644
--- a/includes/MediaWiki.php
+++ b/includes/MediaWiki.php
@@ -485,6 +485,16 @@
$action = $this->getAction();
$wgTitle = $title;
+ // Aside from rollback, master queries should not happen on GET
requests.
+ // Periodic or "in passing" updates on GET should use the job
queue.
+ if ( !$request->wasPosted()
+ && in_array( $action, array( 'view', 'edit', 'history'
) )
+ ) {
+ $trxProfiler =
Profiler::instance()->getTransactionProfiler();
+ $trxProfiler->setExpectation( 'masterConns', 0,
__METHOD__ );
+ $trxProfiler->setExpectation( 'writes', 0, __METHOD__ );
+ }
+
// If the user has forceHTTPS set to true, or if the user
// is in a group requiring HTTPS, or if they have the HTTPS
// preference set, redirect them to HTTPS.
diff --git a/includes/db/Database.php b/includes/db/Database.php
index 054f27a..0e24bc9 100644
--- a/includes/db/Database.php
+++ b/includes/db/Database.php
@@ -817,6 +817,10 @@
if ( $user ) {
$this->open( $server, $user, $password, $dbName );
}
+
+ $isMaster = !is_null( $this->getLBInfo( 'master' ) );
+ $trxProf = Profiler::instance()->getTransactionProfiler();
+ $trxProf->recordConnection( $this->mServer, $this->mDBname,
$isMaster );
}
/**
diff --git a/includes/profiler/TransactionProfiler.php
b/includes/profiler/TransactionProfiler.php
index 886bc5a..57d0474 100644
--- a/includes/profiler/TransactionProfiler.php
+++ b/includes/profiler/TransactionProfiler.php
@@ -40,6 +40,80 @@
/** @var array transaction ID => list of (query name, start time, end
time) */
protected $dbTrxMethodTimes = array();
+ /** @var array */
+ protected $hits = array(
+ 'writes' => 0,
+ 'queries' => 0,
+ 'conns' => 0,
+ 'masterConns' => 0
+ );
+ /** @var array */
+ protected $expect = array(
+ 'writes' => INF,
+ 'queries' => INF,
+ 'conns' => INF,
+ 'masterConns' => INF
+ );
+ /** @var array */
+ protected $expectBy = array();
+
+ /**
+ * Set performance expectations
+ *
+ * With conflicting expect, the most specific ones will be used
+ *
+ * @param string $event (writes,queries,conns,mConns)
+ * @param integer $value Maximum count of the event
+ * @param string $fname Caller
+ * @since 1.25
+ */
+ public function setExpectation( $event, $value, $fname ) {
+ $this->expect[$event] = isset( $this->expect[$event] )
+ ? min( $this->expect[$event], $value )
+ : $value;
+ if ( $this->expect[$event] == $value ) {
+ $this->expectBy[$event] = $fname;
+ }
+ }
+
+ /**
+ * Reset performance expectations and hit counters
+ *
+ * Probably only useful in CLI mode
+ *
+ * @since 1.25
+ */
+ public function resetExpectationsAndCounters() {
+ foreach ( $this->hits as &$val ) {
+ $val = 0;
+ }
+ unset( $val );
+ foreach ( $this->expect as &$val ) {
+ $val = INF;
+ }
+ unset( $val );
+ $this->expectBy = array();
+ }
+
+ /**
+ * Mark a DB as having been connected to with a new handle
+ *
+ * Note that there can be multiple connections to a single DB.
+ *
+ * @param string $server DB server
+ * @param string $db DB name
+ * @param bool $isMaster
+ */
+ public function recordConnection( $server, $db, $isMaster ) {
+ // Report when too many connections happen...
+ if ( $this->hits['conns']++ == $this->expect['conns'] ) {
+ $this->reportExpectationViolated( 'conns', "[connect to
$server ($db)]" );
+ }
+ if ( $isMaster && $this->hits['masterConns']++ ==
$this->expect['masterConns'] ) {
+ $this->reportExpectationViolated( 'masterConns',
"[connect to $server ($db)]" );
+ }
+ }
+
/**
* Mark a DB as in a transaction with one or more writes pending
*
@@ -78,6 +152,14 @@
public function recordQueryCompletion( $query, $sTime, $isWrite = false
) {
$eTime = microtime( true );
$elapsed = ( $eTime - $sTime );
+
+ // Report when too many writes/queries happen...
+ if ( $this->hits['queries']++ == $this->expect['queries'] ) {
+ $this->reportExpectationViolated( 'queries', $query );
+ }
+ if ( $isWrite && $this->hits['writes']++ ==
$this->expect['writes'] ) {
+ $this->reportExpectationViolated( 'writes', $query );
+ }
if ( !$this->dbTrxHoldingLocks ) {
// Short-circuit
@@ -155,4 +237,15 @@
unset( $this->dbTrxHoldingLocks[$name] );
unset( $this->dbTrxMethodTimes[$name] );
}
+
+ /**
+ * @param string $expect
+ * @param string $query
+ */
+ protected function reportExpectationViolated( $expect, $query ) {
+ $n = $this->expect[$expect];
+ $by = $this->expectBy[$expect];
+ wfDebugLog( 'DBPerformance',
+ "Expectation ($expect <= $n) by $by not met:\n$query\n"
. wfBacktrace( true ) );
+ }
}
--
To view, visit https://gerrit.wikimedia.org/r/185342
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic2ae95c33facbb54e062aef2ce67d6182caa044a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits