From: Aaron Schulz Date: Sun, 12 Aug 2018 10:14:54 +0000 (-0700) Subject: Use LB server configuration to force DB domains in ExternalStorageDB X-Git-Tag: 1.31.1~7 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=633252c3e9a3e462282c94ccad71f808175394b2 Use LB server configuration to force DB domains in ExternalStorageDB This is for backwards-compatibility for pre 14ee3f210782 external store configuration that relied on not using the main wiki DB name(s). (cherry-picked from 92e4ace7eae612ce0fa040e02d932516c4d99712) Bug: T200471 Change-Id: Ie60cae64e32ff2532565cbd79c8e084634a61cce --- diff --git a/includes/externalstore/ExternalStoreDB.php b/includes/externalstore/ExternalStoreDB.php index 5edb4b2ef0..6ed5047947 100644 --- a/includes/externalstore/ExternalStoreDB.php +++ b/includes/externalstore/ExternalStoreDB.php @@ -21,10 +21,11 @@ */ use MediaWiki\MediaWikiServices; -use Wikimedia\Rdbms\LoadBalancer; +use Wikimedia\Rdbms\ILoadBalancer; use Wikimedia\Rdbms\IDatabase; use Wikimedia\Rdbms\DBConnRef; use Wikimedia\Rdbms\MaintainableDBConnRef; +use Wikimedia\Rdbms\DatabaseDomain; /** * DB accessible external objects. @@ -112,7 +113,7 @@ class ExternalStoreDB extends ExternalStoreMedium { * Get a LoadBalancer for the specified cluster * * @param string $cluster Cluster name - * @return LoadBalancer + * @return ILoadBalancer */ private function getLoadBalancer( $cluster ) { $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); @@ -128,8 +129,8 @@ class ExternalStoreDB extends ExternalStoreMedium { public function getSlave( $cluster ) { global $wgDefaultExternalStore; - $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false; $lb = $this->getLoadBalancer( $cluster ); + $domainId = $this->getDomainId( $lb->getServerInfo( $lb->getWriterIndex() ) ); if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) { wfDebug( "read only external store\n" ); @@ -138,7 +139,7 @@ class ExternalStoreDB extends ExternalStoreMedium { wfDebug( "writable external store\n" ); } - $db = $lb->getConnectionRef( DB_REPLICA, [], $wiki ); + $db = $lb->getConnectionRef( DB_REPLICA, [], $domainId ); $db->clearFlag( DBO_TRX ); // sanity return $db; @@ -151,15 +152,38 @@ class ExternalStoreDB extends ExternalStoreMedium { * @return MaintainableDBConnRef */ public function getMaster( $cluster ) { - $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false; $lb = $this->getLoadBalancer( $cluster ); + $domainId = $this->getDomainId( $lb->getServerInfo( $lb->getWriterIndex() ) ); - $db = $lb->getMaintenanceConnectionRef( DB_MASTER, [], $wiki ); + $db = $lb->getMaintenanceConnectionRef( DB_MASTER, [], $domainId ); $db->clearFlag( DBO_TRX ); // sanity return $db; } + /** + * @param array $server Master DB server configuration array for LoadBalancer + * @return string|bool Database domain ID or false + */ + private function getDomainId( array $server ) { + if ( isset( $server['dbname'] ) ) { + // T200471: for b/c, treat any "dbname" field as forcing which database to use. + // MediaWiki/LoadBalancer previously did not enforce any concept of a local DB + // domain, but rather assumed that the LB server configuration matched $wgDBname. + // This check is useful when the external storage DB for this cluster does not use + // the same name as the corresponding "main" DB(s) for wikis. + $domain = new DatabaseDomain( + $server['dbname'], + $server['schema'] ?? null, + $server['tablePrefix'] ?? '' + ); + + return $domain->getId(); + } + + return $this->params['wiki'] ?? false; // local domain unless explictly given + } + /** * Get the 'blobs' table name for this database * diff --git a/includes/libs/rdbms/loadbalancer/ILoadBalancer.php b/includes/libs/rdbms/loadbalancer/ILoadBalancer.php index fec496e455..d6b7e3bd0c 100644 --- a/includes/libs/rdbms/loadbalancer/ILoadBalancer.php +++ b/includes/libs/rdbms/loadbalancer/ILoadBalancer.php @@ -335,6 +335,14 @@ interface ILoadBalancer { */ public function getServerType( $i ); + /** + * Return the server info structure for a given index, or false if the index is invalid. + * @param int $i + * @return array|bool + * @since 1.31 + */ + public function getServerInfo( $i ); + /** * @param int $i Server index * @return array (Database::ATTRIBUTE_* constant => value) for all such constants diff --git a/includes/libs/rdbms/loadbalancer/LoadBalancer.php b/includes/libs/rdbms/loadbalancer/LoadBalancer.php index 51fdfe308a..29793ee853 100644 --- a/includes/libs/rdbms/loadbalancer/LoadBalancer.php +++ b/includes/libs/rdbms/loadbalancer/LoadBalancer.php @@ -1173,6 +1173,14 @@ class LoadBalancer implements ILoadBalancer { return ( $name != '' ) ? $name : 'localhost'; } + public function getServerInfo( $i ) { + if ( isset( $this->servers[$i] ) ) { + return $this->servers[$i]; + } else { + return false; + } + } + public function getServerType( $i ) { return isset( $this->servers[$i]['type'] ) ? $this->servers[$i]['type'] : 'unknown'; }