From: Aaron Schulz Date: Fri, 9 Feb 2018 02:48:38 +0000 (-0800) Subject: rdbms: make DOMAIN_ANY ignore bogus MySQL DB names in config X-Git-Tag: 1.31.0-rc.0~653^2 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=e59b0556f4531b87d80113fcefc845ed9d6e3500 rdbms: make DOMAIN_ANY ignore bogus MySQL DB names in config This regressed in 14ee3f2, trying to select the server config "dbname" value as the database on connect. If that config is bogus, then the connection attempt would fail. Instead, always pass null to the driver's connection function if the DB domain doesn't matter. This affected WMF sites during lag checks, on account of the "serverTemplate" value in $wgLBFactoryConf always using the local wiki domain (whether the cluster had such a database or not). Use strlen() as mysqli sees null and "" as the same for $dbname. Bug: T186764 Change-Id: I6699d17c0125a08415046211fee7906bbaf2c366 --- diff --git a/includes/libs/rdbms/database/DatabaseMysqlBase.php b/includes/libs/rdbms/database/DatabaseMysqlBase.php index 208f506520..fcedf56958 100644 --- a/includes/libs/rdbms/database/DatabaseMysqlBase.php +++ b/includes/libs/rdbms/database/DatabaseMysqlBase.php @@ -159,7 +159,7 @@ abstract class DatabaseMysqlBase extends Database { $this->reportConnectionError( $error ); } - if ( $dbName != '' ) { + if ( strlen( $dbName ) ) { MediaWiki\suppressWarnings(); $success = $this->selectDB( $dbName ); MediaWiki\restoreWarnings(); diff --git a/includes/libs/rdbms/loadbalancer/LoadBalancer.php b/includes/libs/rdbms/loadbalancer/LoadBalancer.php index f41088251a..d070c1eeb0 100644 --- a/includes/libs/rdbms/loadbalancer/LoadBalancer.php +++ b/includes/libs/rdbms/loadbalancer/LoadBalancer.php @@ -1006,7 +1006,17 @@ class LoadBalancer implements ILoadBalancer { throw new DBAccessError(); } - if ( $domainOverride->getDatabase() !== null ) { + // Handle $domainOverride being a specified or an unspecified domain + if ( $domainOverride->getDatabase() === null ) { + // Normally, an RDBMS requires a DB name specified on connection and the $server + // configuration array is assumed to already specify an appropriate DB name. + if ( $server['type'] === 'mysql' ) { + // For MySQL, DATABASE and SCHEMA are synonyms, connections need not specify a DB, + // and the DB name in $server might not exist due to legacy reasons (the default + // domain used to ignore the local LB domain, even when mismatched). + $server['dbname'] = null; + } + } else { $server['dbname'] = $domainOverride->getDatabase(); $server['schema'] = $domainOverride->getSchema(); } diff --git a/tests/phpunit/includes/db/LBFactoryTest.php b/tests/phpunit/includes/db/LBFactoryTest.php index fa1cfc98ee..356ebe55ba 100644 --- a/tests/phpunit/includes/db/LBFactoryTest.php +++ b/tests/phpunit/includes/db/LBFactoryTest.php @@ -376,14 +376,14 @@ class LBFactoryTest extends MediaWikiTestCase { $db = $lb->getConnection( DB_MASTER, [], '' ); $this->assertEquals( - $wgDBname, + '', $db->getDomainId(), - 'Main domain ID handle used; same DB name' + 'Null domain ID handle used' ); $this->assertEquals( - $wgDBname, + '', $db->getDBname(), - 'Main domain ID handle used; same DB name' + 'Null domain ID handle used' ); $this->assertEquals( '', @@ -446,16 +446,16 @@ class LBFactoryTest extends MediaWikiTestCase { $dbname = 'unittest-domain'; // explodes if DB is selected $factory = $this->newLBFactoryMulti( [ 'localDomain' => ( new DatabaseDomain( $dbname, null, '' ) )->getId() ], - [ 'dbFilePath' => $dbPath ] + [ + 'dbFilePath' => $dbPath, + 'dbName' => 'do_not_select_me' // explodes if DB is selected + ] ); $lb = $factory->getMainLB(); /** @var Database $db */ $db = $lb->getConnection( DB_MASTER, [], '' ); - $this->assertEquals( - $wgDBname, - $db->getDomainID() - ); + $this->assertEquals( '', $db->getDomainID(), "Null domain used" ); $this->assertEquals( $this->quoteTable( $db, 'page' ),