$thisPosByDomain = $this->getGtidCoordinates();
$thatPosByDomain = $pos->getGtidCoordinates();
if ( $thisPosByDomain && $thatPosByDomain ) {
- $reached = true;
- // Check that this has positions GTE all of those in $pos for all domains in $pos
+ $comparisons = [];
+ // Check that this has positions reaching those in $pos for all domains in common
foreach ( $thatPosByDomain as $domain => $thatPos ) {
- $thisPos = isset( $thisPosByDomain[$domain] ) ? $thisPosByDomain[$domain] : -1;
- $reached = $reached && ( $thatPos <= $thisPos );
+ if ( isset( $thisPosByDomain[$domain] ) ) {
+ $comparisons[] = ( $thatPos <= $thisPosByDomain[$domain] );
+ }
}
-
- return $reached;
+ // Check that $this has a GTID for at least one domain also in $pos; due to MariaDB
+ // quirks, prior master switch-overs may result in inactive garbage GTIDs that cannot
+ // be cleaned up. Assume that the domains in both this and $pos cover the relevant
+ // active channels.
+ return ( $comparisons && !in_array( false, $comparisons, true ) );
}
// Fallback to the binlog file comparisons
$thisPosDomains = array_keys( $this->getGtidCoordinates() );
$thatPosDomains = array_keys( $pos->getGtidCoordinates() );
if ( $thisPosDomains && $thatPosDomains ) {
- // Check that this has GTIDs for all domains in $pos
- return !array_diff( $thatPosDomains, $thisPosDomains );
+ // Check that $this has a GTID for at least one domain also in $pos; due to MariaDB
+ // quirks, prior master switch-overs may result in inactive garbage GTIDs that cannot
+ // easily be cleaned up. Assume that the domains in both this and $pos cover the
+ // relevant active channels.
+ return array_intersect( $thatPosDomains, $thisPosDomains ) ? true : false;
}
// Fallback to the binlog file comparisons
* @dataProvider provideComparePositions
* @covers Wikimedia\Rdbms\MySQLMasterPos
*/
- public function testHasReached( MySQLMasterPos $lowerPos, MySQLMasterPos $higherPos, $match ) {
+ public function testHasReached(
+ MySQLMasterPos $lowerPos, MySQLMasterPos $higherPos, $match, $hetero
+ ) {
if ( $match ) {
$this->assertTrue( $lowerPos->channelsMatch( $higherPos ) );
- $this->assertTrue( $higherPos->hasReached( $lowerPos ) );
- $this->assertTrue( $higherPos->hasReached( $higherPos ) );
+ if ( $hetero ) {
+ // Each position is has one channel higher than the other
+ $this->assertFalse( $higherPos->hasReached( $lowerPos ) );
+ } else {
+ $this->assertTrue( $higherPos->hasReached( $lowerPos ) );
+ }
$this->assertTrue( $lowerPos->hasReached( $lowerPos ) );
+ $this->assertTrue( $higherPos->hasReached( $higherPos ) );
$this->assertFalse( $lowerPos->hasReached( $higherPos ) );
} else { // channels don't match
$this->assertFalse( $lowerPos->channelsMatch( $higherPos ) );
[
new MySQLMasterPos( 'db1034-bin.000976/843431247', $now ),
new MySQLMasterPos( 'db1034-bin.000976/843431248', $now ),
- true
+ true,
+ false
],
[
new MySQLMasterPos( 'db1034-bin.000976/999', $now ),
new MySQLMasterPos( 'db1034-bin.000976/1000', $now ),
- true
+ true,
+ false
],
[
new MySQLMasterPos( 'db1034-bin.000976/999', $now ),
new MySQLMasterPos( 'db1035-bin.000976/1000', $now ),
+ false,
false
],
// MySQL GTID style
[
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:23', $now ),
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:24', $now ),
- true
+ true,
+ false
],
[
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:99', $now ),
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:100', $now ),
- true
+ true,
+ false
],
[
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:99', $now ),
new MySQLMasterPos( '1E11FA47-71CA-11E1-9E33-C80AA9429562:100', $now ),
+ false,
false
],
// MariaDB GTID style
[
new MySQLMasterPos( '255-11-23', $now ),
new MySQLMasterPos( '255-11-24', $now ),
- true
+ true,
+ false
],
[
new MySQLMasterPos( '255-11-99', $now ),
new MySQLMasterPos( '255-11-100', $now ),
- true
+ true,
+ false
],
[
new MySQLMasterPos( '255-11-999', $now ),
new MySQLMasterPos( '254-11-1000', $now ),
+ false,
+ false
+ ],
+ [
+ new MySQLMasterPos( '255-11-23,256-12-50', $now ),
+ new MySQLMasterPos( '255-11-24', $now ),
+ true,
+ false
+ ],
+ [
+ new MySQLMasterPos( '255-11-99,256-12-50,257-12-50', $now ),
+ new MySQLMasterPos( '255-11-1000', $now ),
+ true,
+ false
+ ],
+ [
+ new MySQLMasterPos( '255-11-23,256-12-50', $now ),
+ new MySQLMasterPos( '255-11-24,155-52-63', $now ),
+ true,
+ false
+ ],
+ [
+ new MySQLMasterPos( '255-11-99,256-12-50,257-12-50', $now ),
+ new MySQLMasterPos( '255-11-1000,256-12-51', $now ),
+ true,
+ false
+ ],
+ [
+ new MySQLMasterPos( '255-11-99,256-12-50', $now ),
+ new MySQLMasterPos( '255-13-1000,256-14-49', $now ),
+ true,
+ true
+ ],
+ [
+ new MySQLMasterPos( '253-11-999,255-11-999', $now ),
+ new MySQLMasterPos( '254-11-1000', $now ),
+ false,
false
],
];