From 9df277a4ba3b1dc86e11f469d742c3781141da70 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Fri, 22 Mar 2019 00:17:36 -0700 Subject: [PATCH] rdbms: halt on some common broken $wgDBServers configurations Mention the changes, usually simple, needed to fix the problem. Bug: T215850 Change-Id: I9911f5f5213682ffb52ac548e3082db548e37b3d --- includes/ServiceWiring.php | 5 ++- includes/db/MWLBFactory.php | 79 +++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 12e782d34f..73e4543a2a 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -149,7 +149,10 @@ return [ $lbConf = MWLBFactory::applyDefaultConfig( $mainConfig->get( 'LBFactoryConf' ), $mainConfig, - $services->getConfiguredReadOnlyMode() + $services->getConfiguredReadOnlyMode(), + $services->getLocalServerObjectCache(), + $services->getMainObjectStash(), + $services->getMainWANObjectCache() ); $class = MWLBFactory::getLBFactoryClass( $lbConf ); diff --git a/includes/db/MWLBFactory.php b/includes/db/MWLBFactory.php index cb1a69dfd4..a930b3b0eb 100644 --- a/includes/db/MWLBFactory.php +++ b/includes/db/MWLBFactory.php @@ -22,7 +22,6 @@ */ use MediaWiki\Logger\LoggerFactory; -use MediaWiki\MediaWikiServices; use Wikimedia\Rdbms\LBFactory; use Wikimedia\Rdbms\DatabaseDomain; @@ -39,10 +38,18 @@ abstract class MWLBFactory { * @param array $lbConf Config for LBFactory::__construct() * @param Config $mainConfig Main config object from MediaWikiServices * @param ConfiguredReadOnlyMode $readOnlyMode + * @param BagOStuff $srvCace + * @param BagOStuff $mainStash + * @param WANObjectCache $wanCache * @return array */ - public static function applyDefaultConfig( array $lbConf, Config $mainConfig, - ConfiguredReadOnlyMode $readOnlyMode + public static function applyDefaultConfig( + array $lbConf, + Config $mainConfig, + ConfiguredReadOnlyMode $readOnlyMode, + BagOStuff $srvCace, + BagOStuff $mainStash, + WANObjectCache $wanCache ) { global $wgCommandLineMode; @@ -91,6 +98,20 @@ abstract class MWLBFactory { 'port' => $mainConfig->get( 'DBport' ), 'useWindowsAuth' => $mainConfig->get( 'DBWindowsAuthentication' ) ]; + } elseif ( $server['type'] === 'mysql' ) { + // A DB name is not needed to connect to mysql; 'dbname' is useless. + // This field only defines the DB to use for unspecified DB domains. + $ldDB = $mainConfig->get( 'DBname' ); // local domain DB + $srvDB = $server['dbname'] ?? null; // server DB + if ( $srvDB !== null && $srvDB !== $ldDB ) { + self::reportMismatchedDBs( $srvDB, $ldDB ); + } + } + + $ldTP = $mainConfig->get( 'DBprefix' ); // local domain prefix + $srvTP = $server['tablePrefix'] ?? null; // server table prefix + if ( $srvTP !== '' && $srvTP !== $ldTP ) { + self::reportMismatchedPrefixes( $srvTP, $ldTP ); } if ( in_array( $server['type'], $typesWithSchema, true ) ) { @@ -151,18 +172,28 @@ abstract class MWLBFactory { } } - $services = MediaWikiServices::getInstance(); + $lbConf = self::applyDefaultCaching( $lbConf, $srvCace, $mainStash, $wanCache ); + + return $lbConf; + } + /** + * @param array $lbConf + * @param BagOStuff $sCache + * @param BagOStuff $mStash + * @param WANObjectCache $wCache + * @return array + */ + private static function applyDefaultCaching( + array $lbConf, BagOStuff $sCache, BagOStuff $mStash, WANObjectCache $wCache + ) { // Use APC/memcached style caching, but avoids loops with CACHE_DB (T141804) - $sCache = $services->getLocalServerObjectCache(); if ( $sCache->getQoS( $sCache::ATTR_EMULATION ) > $sCache::QOS_EMULATION_SQL ) { $lbConf['srvCache'] = $sCache; } - $mStash = $services->getMainObjectStash(); if ( $mStash->getQoS( $mStash::ATTR_EMULATION ) > $mStash::QOS_EMULATION_SQL ) { $lbConf['memStash'] = $mStash; } - $wCache = $services->getMainWANObjectCache(); if ( $wCache->getQoS( $wCache::ATTR_EMULATION ) > $wCache::QOS_EMULATION_SQL ) { $lbConf['wanCache'] = $wCache; } @@ -170,6 +201,40 @@ abstract class MWLBFactory { return $lbConf; } + /** + * @param string $srvDB Server config database + * @param string $ldDB Local DB domain database + */ + private static function reportMismatchedDBs( $srvDB, $ldDB ) { + $e = new UnexpectedValueException( + "\$wgDBservers has dbname='$srvDB' but \$wgDBname='$ldDB'. " . + "Set \$wgDBname to the database used by this wiki project. " . + "There is rarely a need to set 'dbname' in \$wgDBservers. " . + "Functions like wfWikiId(), remote wiki database access, the use " . + "of Database::getDomainId(), and other features are not reliable when " . + "\$wgDBservers does not match the local wiki database/prefix." + ); + MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY ); + exit; + } + + /** + * @param string $srvTP Server config table prefix + * @param string $ldTP Local DB domain database + */ + private static function reportMismatchedPrefixes( $srvTP, $ldTP ) { + $e = new UnexpectedValueException( + "\$wgDBservers has tablePrefix='$srvTP' but \$wgDBprefix='$ldTP'. " . + "Set \$wgDBprefix to the table prefix used by this wiki project. " . + "There is rarely a need to set 'tablePrefix' in \$wgDBservers. " . + "Functions like wfWikiId(), remote wiki database access, the use " . + "of Database::getDomainId(), and other features are not reliable when " . + "\$wgDBservers does not match the local wiki database/prefix." + ); + MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY ); + exit; + } + /** * Returns the LBFactory class to use and the load balancer configuration. * -- 2.20.1