Merge "rdbms: make $i in LoadBalancer::getConnection override $groups"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 13 Apr 2018 16:30:37 +0000 (16:30 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 13 Apr 2018 16:30:37 +0000 (16:30 +0000)
1  2 
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php

@@@ -85,8 -85,6 +85,8 @@@ interface ILoadBalancer 
        const DOMAIN_ANY = '';
  
        /** @var int DB handle should have DBO_TRX disabled and the caller will leave it as such */
 +      const CONN_TRX_AUTOCOMMIT = 1;
 +      /** @var int Alias for CONN_TRX_AUTOCOMMIT for b/c; deprecated since 1.31 */
        const CONN_TRX_AUTO = 1;
  
        /**
        /**
         * Get a connection handle by server index
         *
 -       * The CONN_TRX_AUTO flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
 +       * The CONN_TRX_AUTOCOMMIT flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
         * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
         * can be used to check such flags beforehand.
         *
 -       * If the caller uses $domain or sets CONN_TRX_AUTO in $flags, then it must also
 +       * If the caller uses $domain or sets CONN_TRX_AUTOCOMMIT in $flags, then it must also
         * call ILoadBalancer::reuseConnection() on the handle when finished using it.
         * In all other cases, this is not necessary, though not harmful either.
         *
-        * @param int $i Server index or DB_MASTER/DB_REPLICA
+        * @param int $i Server index (overrides $groups) or DB_MASTER/DB_REPLICA
         * @param array|string|bool $groups Query group(s), or false for the generic reader
         * @param string|bool $domain Domain ID, or false for the current domain
         * @param int $flags Bitfield of CONN_* class constants
         *
         * The handle's methods simply wrap those of a Database handle
         *
 -       * The CONN_TRX_AUTO flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
 +       * The CONN_TRX_AUTOCOMMIT flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
         * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
         * can be used to check such flags beforehand.
         *
         * @param int $i Server index or DB_MASTER/DB_REPLICA
         * @param array|string|bool $groups Query group(s), or false for the generic reader
         * @param string|bool $domain Domain ID, or false for the current domain
 -       * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTO)
 +       * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTOCOMMIT)
         * @return DBConnRef
         */
        public function getConnectionRef( $i, $groups = [], $domain = false, $flags = 0 );
         *
         * The handle's methods simply wrap those of a Database handle
         *
 -       * The CONN_TRX_AUTO flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
 +       * The CONN_TRX_AUTOCOMMIT flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
         * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
         * can be used to check such flags beforehand.
         *
         * @param int $i Server index or DB_MASTER/DB_REPLICA
         * @param array|string|bool $groups Query group(s), or false for the generic reader
         * @param string|bool $domain Domain ID, or false for the current domain
 -       * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTO)
 +       * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTOCOMMIT)
         * @return DBConnRef
         */
        public function getLazyConnectionRef( $i, $groups = [], $domain = false, $flags = 0 );
         *
         * The handle's methods simply wrap those of a Database handle
         *
 -       * The CONN_TRX_AUTO flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
 +       * The CONN_TRX_AUTOCOMMIT flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
         * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
         * can be used to check such flags beforehand.
         *
         * @param int $db Server index or DB_MASTER/DB_REPLICA
         * @param array|string|bool $groups Query group(s), or false for the generic reader
         * @param string|bool $domain Domain ID, or false for the current domain
 -       * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTO)
 +       * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTOCOMMIT)
         * @return MaintainableDBConnRef
         */
        public function getMaintenanceConnectionRef( $db, $groups = [], $domain = false, $flags = 0 );
         * The index must be an actual index into the array. If a connection to the server is
         * already open and not considered an "in use" foreign connection, this simply returns it.
         *
 -       * Avoid using CONN_TRX_AUTO for databases with ATTR_DB_LEVEL_LOCKING (e.g. sqlite) in
 +       * Avoid using CONN_TRX_AUTOCOMMIT for databases with ATTR_DB_LEVEL_LOCKING (e.g. sqlite) in
         * order to avoid deadlocks. ILoadBalancer::getServerAttributes() can be used to check
         * such flags beforehand.
         *
 -       * If the caller uses $domain or sets CONN_TRX_AUTO in $flags, then it must also
 +       * If the caller uses $domain or sets CONN_TRX_AUTOCOMMIT in $flags, then it must also
         * call ILoadBalancer::reuseConnection() on the handle when finished using it.
         * In all other cases, this is not necessary, though not harmful either.
         *
         *
         * @param int $i Server index (does not support DB_MASTER/DB_REPLICA)
         * @param string|bool $domain Domain ID, or false for the current domain
 -       * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTO)
 +       * @param int $flags Bitfield of CONN_* class constants (e.g. CONN_TRX_AUTOCOMMIT)
         * @return Database|bool Returns false on errors
         * @throws DBAccessError
         */
@@@ -575,6 -575,7 +575,6 @@@ class LoadBalancer implements ILoadBala
                        if ( !empty( $connsByServer[$i] ) ) {
                                /** @var IDatabase[] $serverConns */
                                $serverConns = $connsByServer[$i];
 -
                                return reset( $serverConns );
                        }
                }
                        $domain = false; // local connection requested
                }
  
 -              if ( ( $flags & self::CONN_TRX_AUTO ) === self::CONN_TRX_AUTO ) {
 +              if ( ( $flags & self::CONN_TRX_AUTOCOMMIT ) === self::CONN_TRX_AUTOCOMMIT ) {
                        // Assuming all servers are of the same type (or similar), which is overwhelmingly
                        // the case, use the master server information to get the attributes. The information
                        // for $i cannot be used since it might be DB_REPLICA, which might require connection
                                // rows (e.g. FOR UPDATE) or (b) make small commits during a larger transactions
                                // to reduce lock contention. None of these apply for sqlite and using separate
                                // connections just causes self-deadlocks.
 -                              $flags &= ~self::CONN_TRX_AUTO;
 -                              $this->connLogger->info( __METHOD__ . ': ignoring CONN_TRX_AUTO to avoid deadlocks.' );
 +                              $flags &= ~self::CONN_TRX_AUTOCOMMIT;
 +                              $this->connLogger->info( __METHOD__ .
 +                                      ': ignoring CONN_TRX_AUTOCOMMIT to avoid deadlocks.' );
                        }
                }
  
  
                if ( $i == self::DB_MASTER ) {
                        $i = $this->getWriterIndex();
-               } else {
+               } elseif ( $i == self::DB_REPLICA ) {
                        # Try to find an available server in any the query groups (in order)
                        foreach ( $groups as $group ) {
                                $groupIndex = $this->getReaderIndex( $group, $domain );
                // main set of DB connections but rather its own pool since:
                // a) those are usually set to implicitly use transaction rounds via DBO_TRX
                // b) those must support the use of explicit transaction rounds via beginMasterChanges()
 -              $autoCommit = ( ( $flags & self::CONN_TRX_AUTO ) == self::CONN_TRX_AUTO );
 +              $autoCommit = ( ( $flags & self::CONN_TRX_AUTOCOMMIT ) == self::CONN_TRX_AUTOCOMMIT );
  
                if ( $domain !== false ) {
                        // Connection is to a foreign domain
                $domainInstance = DatabaseDomain::newFromId( $domain );
                $dbName = $domainInstance->getDatabase();
                $prefix = $domainInstance->getTablePrefix();
 -              $autoCommit = ( ( $flags & self::CONN_TRX_AUTO ) == self::CONN_TRX_AUTO );
 +              $autoCommit = ( ( $flags & self::CONN_TRX_AUTOCOMMIT ) == self::CONN_TRX_AUTOCOMMIT );
  
                if ( $autoCommit ) {
                        $connFreeKey = self::KEY_FOREIGN_FREE_NOROUND;
        }
  
        public function closeConnection( IDatabase $conn ) {
 -              $serverIndex = $conn->getLBInfo( 'serverIndex' ); // second index level of mConns
 +              $serverIndex = $conn->getLBInfo( 'serverIndex' );
                foreach ( $this->conns as $type => $connsByServer ) {
                        if ( !isset( $connsByServer[$serverIndex] ) ) {
                                continue;