rdbms: deprecate seldom used bufferResults() method
authorAaron Schulz <aschulz@wikimedia.org>
Sat, 27 Jul 2019 06:46:39 +0000 (02:46 -0400)
committerAaron Schulz <aschulz@wikimedia.org>
Thu, 15 Aug 2019 14:50:12 +0000 (14:50 +0000)
Change-Id: If67c91fa020f09a89fe2dd50fe4ad30b75d676ef

RELEASE-NOTES-1.34
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/IDatabase.php
maintenance/convertLinks.php

index e98c943..0c6fec2 100644 (file)
@@ -445,6 +445,7 @@ because of Phabricator reports.
 * SearchEngine::textAlreadyUpdatedForIndex() is deprecated, given the
   deprecation above this method is no longer needed/called and should not be
   implemented by SearchEngine implementation.
+* IDatabase::bufferResults() has been deprecated. Use query batching instead.
 
 === Other changes in 1.34 ===
 * …
index f27d042..f0b135f 100644 (file)
@@ -80,6 +80,11 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       /**
+        * @param bool|null $buffer
+        * @return bool
+        * @deprecated Since 1.34 Use query batching
+        */
        public function bufferResults( $buffer = null ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
index aa8a899..1b511d5 100644 (file)
@@ -515,6 +515,27 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return $this->getServerVersion();
        }
 
+       /**
+        * Turns buffering of SQL result sets on (true) or off (false). Default is "on".
+        *
+        * Unbuffered queries are very troublesome in MySQL:
+        *
+        *   - If another query is executed while the first query is being read
+        *     out, the first query is killed. This means you can't call normal
+        *     Database functions while you are reading an unbuffered query result
+        *     from a normal Database connection.
+        *
+        *   - Unbuffered queries cause the MySQL server to use large amounts of
+        *     memory and to hold broad locks which block other queries.
+        *
+        * If you want to limit client-side memory, it's almost always better to
+        * split up queries into batches using a LIMIT clause than to switch off
+        * buffering.
+        *
+        * @param null|bool $buffer
+        * @return bool The previous value of the flag
+        * @deprecated Since 1.34 Use query batching
+        */
        public function bufferResults( $buffer = null ) {
                $res = !$this->getFlag( self::DBO_NOBUFFER );
                if ( $buffer !== null ) {
index 4c18911..d32a12e 100644 (file)
@@ -42,10 +42,10 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        protected function doQuery( $sql ) {
                $conn = $this->getBindingHandle();
 
-               if ( $this->bufferResults() ) {
-                       $ret = $conn->query( $sql );
-               } else {
+               if ( $this->getFlag( self::DBO_NOBUFFER ) ) {
                        $ret = $conn->query( $sql, MYSQLI_USE_RESULT );
+               } else {
+                       $ret = $conn->query( $sql );
                }
 
                return $ret;
index 6b02867..b8c1509 100644 (file)
@@ -138,28 +138,6 @@ interface IDatabase {
         */
        public function getServerInfo();
 
-       /**
-        * Turns buffering of SQL result sets on (true) or off (false). Default is "on".
-        *
-        * Unbuffered queries are very troublesome in MySQL:
-        *
-        *   - If another query is executed while the first query is being read
-        *     out, the first query is killed. This means you can't call normal
-        *     Database functions while you are reading an unbuffered query result
-        *     from a normal Database connection.
-        *
-        *   - Unbuffered queries cause the MySQL server to use large amounts of
-        *     memory and to hold broad locks which block other queries.
-        *
-        * If you want to limit client-side memory, it's almost always better to
-        * split up queries into batches using a LIMIT clause than to switch off
-        * buffering.
-        *
-        * @param null|bool $buffer
-        * @return null|bool The previous value of the flag
-        */
-       public function bufferResults( $buffer = null );
-
        /**
         * Gets the current transaction level.
         *
index 59820a5..02152f7 100644 (file)
@@ -144,30 +144,34 @@ class ConvertLinks extends Maintenance {
                        $this->output( "Loading IDs from $cur table...\n" );
                        $this->performanceLog( $fh, "Reading $numRows rows from cur table...\n" );
                        $this->performanceLog( $fh, "rows read vs seconds elapsed:\n" );
+                       $contentLang = MediaWikiServices::getInstance()->getContentLanguage();
 
-                       $dbw->bufferResults( false );
-                       $res = $dbw->query( "SELECT cur_namespace,cur_title,cur_id FROM $cur" );
                        $ids = [];
-
-                       foreach ( $res as $row ) {
-                               $title = $row->cur_title;
-                               if ( $row->cur_namespace ) {
-                                       $title = MediaWikiServices::getInstance()->getContentLanguage()->
-                                               getNsText( $row->cur_namespace ) . ":$title";
-                               }
-                               $ids[$title] = $row->cur_id;
-                               $curRowsRead++;
-                               if ( $reportCurReadProgress ) {
-                                       if ( ( $curRowsRead % $curReadReportInterval ) == 0 ) {
-                                               $this->performanceLog(
-                                                       $fh,
-                                                       $curRowsRead . " " . ( microtime( true ) - $baseTime ) . "\n"
-                                               );
-                                               $this->output( "\t$curRowsRead rows of $cur table read.\n" );
+                       $lastId = 0;
+                       do {
+                               $res = $dbw->query(
+                                       "SELECT cur_namespace,cur_title,cur_id FROM $cur " .
+                                       "WHERE cur_id > $lastId ORDER BY cur_id LIMIT 10000"
+                               );
+                               foreach ( $res as $row ) {
+                                       $title = $row->cur_title;
+                                       if ( $row->cur_namespace ) {
+                                               $title = $contentLang->getNsText( $row->cur_namespace ) . ":$title";
+                                       }
+                                       $ids[$title] = $row->cur_id;
+                                       $curRowsRead++;
+                                       if ( $reportCurReadProgress ) {
+                                               if ( ( $curRowsRead % $curReadReportInterval ) == 0 ) {
+                                                       $this->performanceLog(
+                                                               $fh,
+                                                               $curRowsRead . " " . ( microtime( true ) - $baseTime ) . "\n"
+                                                       );
+                                                       $this->output( "\t$curRowsRead rows of $cur table read.\n" );
+                                               }
                                        }
+                                       $lastId = $row->cur_id;
                                }
-                       }
-                       $dbw->bufferResults( true );
+                       } while ( $res->numRows() > 0 );
                        $this->output( "Finished loading IDs.\n\n" );
                        $this->performanceLog(
                                $fh,