rdbms: Pass required parameter
[lhc/web/wiklou.git] / includes / libs / rdbms / database / Database.php
index 91cb881..63d648d 100644 (file)
@@ -719,19 +719,27 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                switch ( $type ) {
                        case self::ESTIMATE_DB_APPLY:
-                               $this->ping( $rtt );
-                               $rttAdjTotal = $this->trxWriteAdjQueryCount * $rtt;
-                               $applyTime = max( $this->trxWriteAdjDuration - $rttAdjTotal, 0 );
-                               // For omitted queries, make them count as something at least
-                               $omitted = $this->trxWriteQueryCount - $this->trxWriteAdjQueryCount;
-                               $applyTime += self::TINY_WRITE_SEC * $omitted;
-
-                               return $applyTime;
+                               return $this->pingAndCalculateLastTrxApplyTime();
                        default: // everything
                                return $this->trxWriteDuration;
                }
        }
 
+       /**
+        * @return float Time to apply writes to replicas based on trxWrite* fields
+        */
+       private function pingAndCalculateLastTrxApplyTime() {
+               $this->ping( $rtt );
+
+               $rttAdjTotal = $this->trxWriteAdjQueryCount * $rtt;
+               $applyTime = max( $this->trxWriteAdjDuration - $rttAdjTotal, 0 );
+               // For omitted queries, make them count as something at least
+               $omitted = $this->trxWriteQueryCount - $this->trxWriteAdjQueryCount;
+               $applyTime += self::TINY_WRITE_SEC * $omitted;
+
+               return $applyTime;
+       }
+
        public function pendingWriteCallers() {
                return $this->trxLevel ? $this->trxWriteCallers : [];
        }
@@ -1052,7 +1060,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                //   that transactions by themselves don't make changes, only actual writes
                //   within the transaction matter, which we still detect.
                return !preg_match(
-                       '/^(?:SELECT|BEGIN|ROLLBACK|COMMIT|SET|SHOW|EXPLAIN|\(SELECT)\b/i', $sql );
+                       '/^(?:SELECT|BEGIN|ROLLBACK|COMMIT|SAVEPOINT|RELEASE|SET|SHOW|EXPLAIN|\(SELECT)\b/i',
+                       $sql
+               );
        }
 
        /**
@@ -1542,14 +1552,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $options = [ $options ];
                }
 
-               $res = $this->select( $table, $var, $cond, $fname, $options, $join_conds );
+               $res = $this->select( $table, [ 'value' => $var ], $cond, $fname, $options, $join_conds );
                if ( $res === false ) {
                        return false;
                }
 
                $values = [];
                foreach ( $res as $row ) {
-                       $values[] = $row->$var;
+                       $values[] = $row->value;
                }
 
                return $values;
@@ -2028,10 +2038,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $options = [ $options ];
                }
 
-               $fh = null;
-               if ( isset( $options['fileHandle'] ) ) {
-                       $fh = $options['fileHandle'];
-               }
                $options = $this->makeInsertOptions( $options );
 
                if ( isset( $a[0] ) && is_array( $a[0] ) ) {
@@ -2059,13 +2065,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $sql .= '(' . $this->makeList( $a ) . ')';
                }
 
-               if ( $fh !== null && false === fwrite( $fh, $sql ) ) {
-                       return false;
-               } elseif ( $fh !== null ) {
-                       return true;
-               }
+               $this->query( $sql, $fname );
 
-               return (bool)$this->query( $sql, $fname );
+               return true;
        }
 
        /**
@@ -2109,7 +2111,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $sql .= " WHERE " . $this->makeList( $conds, self::LIST_AND );
                }
 
-               return (bool)$this->query( $sql, $fname );
+               $this->query( $sql, $fname );
+
+               return true;
        }
 
        public function makeList( $a, $mode = self::LIST_COMMA ) {
@@ -2823,8 +2827,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @param string $table Table name
         * @param array|string $rows Row(s) to insert
         * @param string $fname Caller function name
-        *
-        * @return ResultWrapper
         */
        protected function nativeReplace( $table, $rows, $fname ) {
                $table = $this->tableName( $table );
@@ -2847,7 +2849,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $sql .= '(' . $this->makeList( $row ) . ')';
                }
 
-               return $this->query( $sql, $fname );
+               $this->query( $sql, $fname );
        }
 
        public function upsert( $table, array $rows, array $uniqueIndexes, array $set,
@@ -2883,13 +2885,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $this->startAtomic( $fname, self::ATOMIC_CANCELABLE );
                        # Update any existing conflicting row(s)
                        if ( $where !== false ) {
-                               $ok = $this->update( $table, $set, $where, $fname );
+                               $this->update( $table, $set, $where, $fname );
                                $affectedRowCount += $this->affectedRows();
-                       } else {
-                               $ok = true;
                        }
                        # Now insert any non-conflicting row(s)
-                       $ok = $this->insert( $table, $rows, $fname, [ 'IGNORE' ] ) && $ok;
+                       $this->insert( $table, $rows, $fname, [ 'IGNORE' ] );
                        $affectedRowCount += $this->affectedRows();
                        $this->endAtomic( $fname );
                        $this->affectedRowCount = $affectedRowCount;
@@ -2898,7 +2898,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        throw $e;
                }
 
-               return $ok;
+               return true;
        }
 
        public function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds,
@@ -2951,7 +2951,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $sql .= ' WHERE ' . $conds;
                }
 
-               return $this->query( $sql, $fname );
+               $this->query( $sql, $fname );
+
+               return true;
        }
 
        final public function insertSelect(
@@ -2966,7 +2968,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $this->cliMode && $this->isInsertSelectSafe( $insertOptions, $selectOptions ) ) {
                        // For massive migrations with downtime, we don't want to select everything
                        // into memory and OOM, so do all this native on the server side if possible.
-                       return $this->nativeInsertSelect(
+                       $this->nativeInsertSelect(
+                               $destTable,
+                               $srcTable,
+                               $varMap,
+                               $conds,
+                               $fname,
+                               array_diff( $insertOptions, $hints ),
+                               $selectOptions,
+                               $selectJoinConds
+                       );
+               } else {
+                       $this->nonNativeInsertSelect(
                                $destTable,
                                $srcTable,
                                $varMap,
@@ -2978,16 +2991,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        );
                }
 
-               return $this->nonNativeInsertSelect(
-                       $destTable,
-                       $srcTable,
-                       $varMap,
-                       $conds,
-                       $fname,
-                       array_diff( $insertOptions, $hints ),
-                       $selectOptions,
-                       $selectJoinConds
-               );
+               return true;
        }
 
        /**
@@ -3013,7 +3017,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @param array $insertOptions
         * @param array $selectOptions
         * @param array $selectJoinConds
-        * @return bool
         */
        protected function nonNativeInsertSelect( $destTable, $srcTable, $varMap, $conds,
                $fname = __METHOD__,
@@ -3031,7 +3034,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $srcTable, implode( ',', $fields ), $conds, $fname, $selectOptions, $selectJoinConds
                );
                if ( !$res ) {
-                       return false;
+                       return;
                }
 
                try {
@@ -3064,7 +3067,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        } else {
                                $this->cancelAtomic( $fname );
                        }
-                       return $ok;
                } catch ( Exception $e ) {
                        $this->cancelAtomic( $fname );
                        throw $e;
@@ -3084,7 +3086,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @param array $insertOptions
         * @param array $selectOptions
         * @param array $selectJoinConds
-        * @return bool
         */
        protected function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds,
                $fname = __METHOD__,
@@ -3111,7 +3112,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        " INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ') ' .
                        $selectSql;
 
-               return $this->query( $sql, $fname );
+               $this->query( $sql, $fname );
        }
 
        /**
@@ -3684,6 +3685,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                $sectionId = new AtomicSectionIdentifier;
                $this->trxAtomicLevels[] = [ $fname, $sectionId, $savepointId ];
+               $this->queryLogger->debug( 'startAtomic: entering level ' .
+                       ( count( $this->trxAtomicLevels ) - 1 ) . " ($fname)" );
 
                return $sectionId;
        }
@@ -3696,6 +3699,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                // Check if the current section matches $fname
                $pos = count( $this->trxAtomicLevels ) - 1;
                list( $savedFname, $sectionId, $savepointId ) = $this->trxAtomicLevels[$pos];
+               $this->queryLogger->debug( "endAtomic: leaving level $pos ($fname)" );
 
                if ( $savedFname !== $fname ) {
                        throw new DBUnexpectedError(
@@ -3728,6 +3732,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        throw new DBUnexpectedError( $this, "No atomic section is open (got $fname)." );
                }
 
+               $excisedFnames = [];
                if ( $sectionId !== null ) {
                        // Find the (last) section with the given $sectionId
                        $pos = -1;
@@ -3737,12 +3742,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                }
                        }
                        if ( $pos < 0 ) {
-                               throw new DBUnexpectedError( "Atomic section not found (for $fname)" );
+                               throw new DBUnexpectedError( $this, "Atomic section not found (for $fname)" );
                        }
                        // Remove all descendant sections and re-index the array
                        $excisedIds = [];
                        $len = count( $this->trxAtomicLevels );
                        for ( $i = $pos + 1; $i < $len; ++$i ) {
+                               $excisedFnames[] = $this->trxAtomicLevels[$i][0];
                                $excisedIds[] = $this->trxAtomicLevels[$i][1];
                        }
                        $this->trxAtomicLevels = array_slice( $this->trxAtomicLevels, 0, $pos + 1 );
@@ -3753,6 +3759,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $pos = count( $this->trxAtomicLevels ) - 1;
                list( $savedFname, $savedSectionId, $savepointId ) = $this->trxAtomicLevels[$pos];
 
+               if ( $excisedFnames ) {
+                       $this->queryLogger->debug( "cancelAtomic: canceling level $pos ($savedFname) " .
+                               "and descendants " . implode( ', ', $excisedFnames ) );
+               } else {
+                       $this->queryLogger->debug( "cancelAtomic: canceling level $pos ($savedFname)" );
+               }
+
                if ( $savedFname !== $fname ) {
                        throw new DBUnexpectedError(
                                $this,
@@ -3958,10 +3971,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        // Avoid fatals if close() was called
                        $this->assertOpen();
 
-                       $writeTime = $this->pendingWriteQueryDuration( self::ESTIMATE_DB_APPLY );
                        $this->doRollback( $fname );
                        $this->trxStatus = self::STATUS_TRX_NONE;
                        $this->trxAtomicLevels = [];
+                       // Estimate the RTT via a query now that trxStatus is OK
+                       $writeTime = $this->pingAndCalculateLastTrxApplyTime();
 
                        if ( $this->trxDoneWrites ) {
                                $this->trxProfiler->transactionWritingOut(