- $sql = "SELECT MASTER_POS_WAIT($encFile, $encPos, $timeout)";
- $res = $this->doQuery( $sql );
-
- $status = false;
- if ( $res ) {
- $row = $this->fetchRow( $res );
- if ( $row ) {
- $status = $row[0]; // can be NULL, -1, or 0+ per the MySQL manual
- if ( ctype_digit( $status ) ) { // success
- $this->lastKnownSlavePos = $pos;
- }
+ $res = $this->doQuery( "SELECT MASTER_POS_WAIT($encFile, $encPos, $timeout)" );
+
+ $row = $res ? $this->fetchRow( $res ) : false;
+ if ( !$row ) {
+ throw new DBExpectedError( $this, "Failed to query MASTER_POS_WAIT()" );
+ }
+
+ // Result can be NULL (error), -1 (timeout), or 0+ per the MySQL manual
+ $status = ( $row[0] !== null ) ? intval( $row[0] ) : null;
+ if ( $status === null ) {
+ // T126436: jobs programmed to wait on master positions might be referencing binlogs
+ // with an old master hostname. Such calls make MASTER_POS_WAIT() return null. Try
+ // to detect this and treat the slave as having reached the position; a proper master
+ // switchover already requires that the new master be caught up before the switch.
+ $slavePos = $this->getSlavePos();
+ if ( $slavePos && !$slavePos->channelsMatch( $pos ) ) {
+ $this->lastKnownSlavePos = $slavePos;
+ $status = 0;