Add LoadBalancer::safeWaitForPos()
authorAaron Schulz <aschulz@wikimedia.org>
Fri, 29 Jan 2016 21:00:08 +0000 (13:00 -0800)
committerAaron Schulz <aschulz@wikimedia.org>
Fri, 29 Jan 2016 21:05:41 +0000 (13:05 -0800)
This is useful for waiting on a specific slave handle to
reach a given master position.

Change-Id: Ia4569c4fc82c25eb4089cf7198f01e349636e2c7

includes/db/loadbalancer/LoadBalancer.php

index b5a79a9..fc7fa13 100644 (file)
@@ -1363,10 +1363,10 @@ class LoadBalancer {
         * function instead of Database::getLag() avoids a fatal error in this
         * case on many installations.
         *
-        * @param DatabaseBase $conn
+        * @param IDatabase $conn
         * @return int
         */
-       public function safeGetLag( $conn ) {
+       public function safeGetLag( IDatabase $conn ) {
                if ( $this->getServerCount() == 1 ) {
                        return 0;
                } else {
@@ -1374,6 +1374,38 @@ class LoadBalancer {
                }
        }
 
+       /**
+        * Wait for a slave DB to reach a specified master position
+        *
+        * This will connect to the master to get an accurate position if $pos is not given
+        *
+        * @param IDatabase $conn Slave DB
+        * @param DBMasterPos|bool $pos Master position; default: current position
+        * @param integer $timeout Timeout in seconds
+        * @return bool Success
+        * @since 1.27
+        */
+       public function safeWaitForPos( IDatabase $conn, $pos = false, $timeout = 10 ) {
+               if ( $this->getServerCount() == 1 || !$conn->getLBInfo( 'slave' ) ) {
+                       return true; // server is not a slave DB
+               }
+
+               $pos = $pos ?: $this->getConnection( DB_MASTER )->getMasterPos();
+
+               $result = $conn->masterPosWait( $pos, $timeout );
+               if ( $result == -1 || is_null( $result ) ) {
+                       $msg = __METHOD__ . ": Timed out waiting on {$conn->getServer()} pos {$pos}";
+                       wfDebugLog( 'replication', "$msg\n" );
+                       wfDebugLog( 'DBPerformance', "$msg:\n" . wfBacktrace( true ) );
+                       $ok = false;
+               } else {
+                       wfDebugLog( 'replication', __METHOD__ . ": Done\n" );
+                       $ok = true;
+               }
+
+               return $ok;
+       }
+
        /**
         * Clear the cache for slag lag delay times
         *