Use LB server configuration to force DB domains in ExternalStorageDB
authorAaron Schulz <aschulz@wikimedia.org>
Sun, 12 Aug 2018 10:14:54 +0000 (03:14 -0700)
committerKrinkle <krinklemail@gmail.com>
Mon, 13 Aug 2018 18:58:02 +0000 (18:58 +0000)
This is for backwards-compatibility for pre 14ee3f210782 external store
configuration that relied on not using the main wiki DB name(s).

Bug: T200471
Change-Id: Ie60cae64e32ff2532565cbd79c8e084634a61cce

includes/externalstore/ExternalStoreDB.php

index 422e1fb..5a77e89 100644 (file)
  */
 
 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 = $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 = $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
         *