140 if ( !isset( $this->expect[$event] ) ) {
144 if ( $limit <= $this->expect[$event][self::FLD_LIMIT] ) {
146 $this->expect[$event] = [
147 self::FLD_LIMIT => $limit,
148 self::FLD_FNAME => $fname
271 ?
string $serverName =
null
273 $eTime = microtime(
true );
274 $elapsed = ( $eTime - $sTime );
276 if ( $isWrite && $this->isAboveThreshold( $rowCount,
'maxAffected' ) ) {
277 $this->reportExpectationViolated(
'maxAffected', $query, $rowCount, $trxId, $serverName );
278 } elseif ( !$isWrite && $this->isAboveThreshold( $rowCount,
'readQueryRows' ) ) {
279 $this->reportExpectationViolated(
'readQueryRows', $query, $rowCount, $trxId, $serverName );
283 if ( $this->pingAndCheckThreshold(
'queries' ) ) {
284 $this->reportExpectationViolated(
'queries', $query, $this->hits[
'queries'], $trxId, $serverName );
286 if ( $isWrite && $this->pingAndCheckThreshold(
'writes' ) ) {
287 $this->reportExpectationViolated(
'writes', $query, $this->hits[
'writes'], $trxId, $serverName );
290 if ( !$isWrite && $this->isAboveThreshold( $elapsed,
'readQueryTime' ) ) {
291 $this->reportExpectationViolated(
'readQueryTime', $query, $elapsed, $trxId, $serverName );
293 if ( $isWrite && $this->isAboveThreshold( $elapsed,
'writeQueryTime' ) ) {
294 $this->reportExpectationViolated(
'writeQueryTime', $query, $elapsed, $trxId, $serverName );
297 if ( !$this->dbTrxHoldingLocks ) {
300 } elseif ( !$isWrite && $elapsed < self::EVENT_THRESHOLD_SEC ) {
305 foreach ( $this->dbTrxHoldingLocks as $name => $info ) {
306 $lastQuery = end( $this->dbTrxMethodTimes[$name] );
309 $lastEnd = $lastQuery[2];
310 if ( $sTime >= $lastEnd ) {
311 if ( ( $sTime - $lastEnd ) > self::EVENT_THRESHOLD_SEC ) {
313 $this->dbTrxMethodTimes[$name][] = [
'...delay...', $lastEnd, $sTime ];
315 $this->dbTrxMethodTimes[$name][] = [ $query, $sTime, $eTime ];
319 if ( $sTime >= $info[
'start'] ) {
320 $this->dbTrxMethodTimes[$name][] = [ $query, $sTime, $eTime ];
347 $name =
"{$db} {$server} TRX#$id";
348 if ( !isset( $this->dbTrxMethodTimes[$name] ) ) {
349 $this->logger->warning(
"Detected no transaction for '$name' - out of sync." );
356 if ( $this->isAboveThreshold( $writeTime,
'writeQueryTime' ) ) {
357 $this->reportExpectationViolated(
359 "[transaction writes to {$db} at {$server}]",
366 if ( $this->isAboveThreshold( $affected,
'maxAffected' ) ) {
367 $this->reportExpectationViolated(
369 "[transaction writes to {$db} at {$server}]",
375 $lastQuery = end( $this->dbTrxMethodTimes[$name] );
377 $now = microtime(
true );
378 $lastEnd = $lastQuery[2];
379 if ( ( $now - $lastEnd ) > self::EVENT_THRESHOLD_SEC ) {
380 $this->dbTrxMethodTimes[$name][] = [
'...delay...', $lastEnd, $now ];
384 foreach ( $this->dbTrxMethodTimes[$name] as $info ) {
385 $elapsed = ( $info[2] - $info[1] );
386 if ( $elapsed >= self::DB_LOCK_THRESHOLD_SEC ) {
393 foreach ( $this->dbTrxMethodTimes[$name] as $i => [ $query, $sTime, $end ] ) {
395 "%-2d %.3fs %s\n", $i, ( $end - $sTime ), $this->getGeneralizedSql( $query ) );
397 $this->logger->warning(
"Sub-optimal transaction [{dbs}]:\n{trace}", [
398 'dbs' => implode(
', ', array_keys( $this->dbTrxHoldingLocks[$name][
'conns'] ) ),
402 unset( $this->dbTrxHoldingLocks[$name] );
403 unset( $this->dbTrxMethodTimes[$name] );