use Wikimedia\Rdbms\DBQueryError;
use Wikimedia\Rdbms\DBConnectionError;
use Wikimedia\Rdbms\LoadBalancer;
-use Wikimedia\Rdbms\TransactionProfiler;
+use Wikimedia\ScopedCallback;
use Wikimedia\WaitConditionLoop;
/**
if ( is_string( $tag ) ) {
$this->serverTags[$index] = $tag;
} else {
- $this->serverTags[$index] = isset( $info['host'] ) ? $info['host'] : "#$index";
+ $this->serverTags[$index] = $info['host'] ?? "#$index";
}
++$index;
}
if ( $this->serverInfos ) {
// Use custom database defined by server connection info
$info = $this->serverInfos[$serverIndex];
- $type = isset( $info['type'] ) ? $info['type'] : 'mysql';
- $host = isset( $info['host'] ) ? $info['host'] : '[unknown]';
+ $type = $info['type'] ?? 'mysql';
+ $host = $info['host'] ?? '[unknown]';
$this->logger->debug( __CLASS__ . ": connecting to $host" );
- // Use a blank trx profiler to ignore expections as this is a cache
- $info['trxProfiler'] = new TransactionProfiler();
$db = Database::factory( $type, $info );
$db->clearFlag( DBO_TRX ); // auto-commit mode
} else {
$index = $this->replicaOnly ? DB_REPLICA : DB_MASTER;
if ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' ) {
// Keep a separate connection to avoid contention and deadlocks
- $db = $lb->getConnection( $index, [], false, $lb::CONN_TRX_AUTO );
- // @TODO: Use a blank trx profiler to ignore expections as this is a cache
+ $db = $lb->getConnection( $index, [], false, $lb::CONN_TRX_AUTOCOMMIT );
} else {
// However, SQLite has the opposite behavior due to DB-level locking.
// Stock sqlite MediaWiki installs use a separate sqlite cache DB instead.
$result = true;
$exptime = (int)$expiry;
+ $silenceScope = $this->silenceTransactionProfiler();
foreach ( $keysByTable as $serverIndex => $serverKeys ) {
$db = null;
try {
protected function cas( $casToken, $key, $value, $exptime = 0 ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
$db = null;
+ $silenceScope = $this->silenceTransactionProfiler();
try {
$db = $this->getDB( $serverIndex );
$exptime = intval( $exptime );
public function delete( $key ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
$db = null;
+ $silenceScope = $this->silenceTransactionProfiler();
try {
$db = $this->getDB( $serverIndex );
$db->delete(
public function incr( $key, $step = 1 ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
$db = null;
+ $silenceScope = $this->silenceTransactionProfiler();
try {
$db = $this->getDB( $serverIndex );
$step = intval( $step );
public function changeTTL( $key, $expiry = 0 ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
$db = null;
+ $silenceScope = $this->silenceTransactionProfiler();
try {
$db = $this->getDB( $serverIndex );
$db->update(
* @return bool
*/
public function deleteObjectsExpiringBefore( $timestamp, $progressCallback = false ) {
+ $silenceScope = $this->silenceTransactionProfiler();
for ( $serverIndex = 0; $serverIndex < $this->numServers; $serverIndex++ ) {
$db = null;
try {
* @return bool
*/
public function deleteAll() {
+ $silenceScope = $this->silenceTransactionProfiler();
for ( $serverIndex = 0; $serverIndex < $this->numServers; $serverIndex++ ) {
$db = null;
try {
return ( $loop->invoke() === $loop::CONDITION_REACHED );
}
+
+ /**
+ * Returns a ScopedCallback which resets the silence flag in the transaction profiler when it is
+ * destroyed on the end of a scope, for example on return or throw
+ * @return ScopedCallback
+ * @since 1.32
+ */
+ protected function silenceTransactionProfiler() {
+ $trxProfiler = Profiler::instance()->getTransactionProfiler();
+ $oldSilenced = $trxProfiler->setSilenced( true );
+ return new ScopedCallback( function () use ( $trxProfiler, $oldSilenced ) {
+ $trxProfiler->setSilenced( $oldSilenced );
+ } );
+ }
}