DBZ-111 Corrected GTID set comparison logic of the MySQL connector

The MySQL connector was improperly comparing the GTID set required by the connector to the GTID set of the MySQL instance. In particular, when the GTID set of the MySQL server contained a newline character, the comparison logic failed. (This should have been fixed as part of DBZ-107.)
This commit is contained in:
Randall Hauch 2016-08-29 14:53:21 -05:00
parent efd430bbee
commit 5cef237aac
3 changed files with 67 additions and 34 deletions

View File

@ -31,6 +31,7 @@ public final class GtidSet {
* @param gtids the string representation of the GTIDs.
*/
public GtidSet(String gtids) {
gtids = gtids.replaceAll("\n", "");
new com.github.shyiko.mysql.binlog.GtidSet(gtids).getUUIDSets().forEach(uuidSet -> {
uuidSetsByServerId.put(uuidSet.getUUID(), new UUIDSet(uuidSet));
});

View File

@ -216,6 +216,7 @@ protected boolean isBinlogAvailable() {
GtidSet gtidSet = new GtidSet(gtidStr);
GtidSet availableGtidSet = new GtidSet(knownGtidSet());
if (gtidSet.isContainedWithin(availableGtidSet)) {
logger.info("MySQL current GTID set {} does contain the GTID set required by the connector {}", availableGtidSet, gtidSet);
return true;
}
logger.info("Connector last known GTIDs are {}, but MySQL has {}", gtidSet, availableGtidSet);
@ -244,6 +245,7 @@ protected boolean isBinlogAvailable() {
if (!found) {
logger.info("Connector requires binlog file '{}', but MySQL only has {}", binlogFilename, String.join(", ", logNames));
}
logger.info("MySQL has the binlog file '{}' required by the connector", binlogFilename);
return found;
}

View File

@ -19,51 +19,50 @@
*
*/
public class GtidSetTest {
private static final String UUID1 = "24bc7850-2c16-11e6-a073-0242ac110002";
private GtidSet gtids;
@Test
public void shouldCreateSetWithSingleInterval() {
gtids = new GtidSet(UUID1 + ":1-191");
asertIntervalCount(UUID1,1);
asertIntervalExists(UUID1,1,191);
asertFirstInterval(UUID1,1,191);
asertLastInterval(UUID1,1,191);
asertIntervalCount(UUID1, 1);
asertIntervalExists(UUID1, 1, 191);
asertFirstInterval(UUID1, 1, 191);
asertLastInterval(UUID1, 1, 191);
assertThat(gtids.toString()).isEqualTo(UUID1 + ":1-191");
}
@Test
public void shouldCollapseAdjacentIntervals() {
gtids = new GtidSet(UUID1 + ":1-191:192-199");
asertIntervalCount(UUID1,1);
asertIntervalExists(UUID1,1,199);
asertFirstInterval(UUID1,1,199);
asertLastInterval(UUID1,1,199);
asertIntervalCount(UUID1, 1);
asertIntervalExists(UUID1, 1, 199);
asertFirstInterval(UUID1, 1, 199);
asertLastInterval(UUID1, 1, 199);
assertThat(gtids.toString()).isEqualTo(UUID1 + ":1-199");
}
@Test
public void shouldNotCollapseNonAdjacentIntervals() {
gtids = new GtidSet(UUID1 + ":1-191:193-199");
asertIntervalCount(UUID1,2);
asertFirstInterval(UUID1,1,191);
asertLastInterval(UUID1,193,199);
asertIntervalCount(UUID1, 2);
asertFirstInterval(UUID1, 1, 191);
asertLastInterval(UUID1, 193, 199);
assertThat(gtids.toString()).isEqualTo(UUID1 + ":1-191:193-199");
}
@Test
public void shouldCreateWithMultipleIntervals() {
gtids = new GtidSet(UUID1 + ":1-191:193-199:1000-1033");
asertIntervalCount(UUID1,3);
asertFirstInterval(UUID1,1,191);
asertIntervalExists(UUID1,193,199);
asertLastInterval(UUID1,1000,1033);
asertIntervalCount(UUID1, 3);
asertFirstInterval(UUID1, 1, 191);
asertIntervalExists(UUID1, 193, 199);
asertLastInterval(UUID1, 1000, 1033);
assertThat(gtids.toString()).isEqualTo(UUID1 + ":1-191:193-199:1000-1033");
}
@Test
public void shouldCreateWithMultipleIntervalsThatMayBeAdjacent() {
gtids = new GtidSet(UUID1 + ":1-191:192-199:1000-1033:1035-1036:1038-1039");
@ -74,34 +73,65 @@ public void shouldCreateWithMultipleIntervalsThatMayBeAdjacent() {
asertLastInterval(UUID1, 1038, 1039);
assertThat(gtids.toString()).isEqualTo(UUID1 + ":1-199:1000-1033:1035-1036:1038-1039"); // ??
}
protected void asertIntervalCount( String uuid, int count) {
@Test
public void shouldCorrectlyDetermineIfSimpleGtidSetIsContainedWithinAnother() {
gtids = new GtidSet("7c1de3f2-3fd2-11e6-9cdc-42010af000bc:1-41");
assertThat(gtids.isContainedWithin(new GtidSet("7c1de3f2-3fd2-11e6-9cdc-42010af000bc:1-41"))).isTrue();
assertThat(gtids.isContainedWithin(new GtidSet("7c1de3f2-3fd2-11e6-9cdc-42010af000bc:1-42"))).isTrue();
assertThat(gtids.isContainedWithin(new GtidSet("7c1de3f2-3fd2-11e6-9cdc-42010af000bc:2-41"))).isFalse();
assertThat(gtids.isContainedWithin(new GtidSet("7145bf69-d1ca-11e5-a588-0242ac110004:1"))).isFalse();
}
@Test
public void shouldCorrectlyDetermineIfComplexGtidSetIsContainedWithinAnother() {
GtidSet connector = new GtidSet("036d85a9-64e5-11e6-9b48-42010af0000c:1-2,"
+ "7145bf69-d1ca-11e5-a588-0242ac110004:1-3200,"
+ "7c1de3f2-3fd2-11e6-9cdc-42010af000bc:1-41");
GtidSet server = new GtidSet("036d85a9-64e5-11e6-9b48-42010af0000c:1-2,"
+ "7145bf69-d1ca-11e5-a588-0242ac110004:1-3202,"
+ "7c1de3f2-3fd2-11e6-9cdc-42010af000bc:1-41");
assertThat(connector.isContainedWithin(server)).isTrue();
}
@Test
public void shouldCorrectlyDetermineIfComplexGtidSetWithNewlinesIsContainedWithinAnother() {
GtidSet connector = new GtidSet("036d85a9-64e5-11e6-9b48-42010af0000c:1-2,"
+ "7145bf69-d1ca-11e5-a588-0242ac110004:1-3200,"
+ "7c1de3f2-3fd2-11e6-9cdc-42010af000bc:1-41");
GtidSet server = new GtidSet("036d85a9-64e5-11e6-9b48-42010af0000c:1-2," + System.lineSeparator() +
"7145bf69-d1ca-11e5-a588-0242ac110004:1-3202," + System.lineSeparator() +
"7c1de3f2-3fd2-11e6-9cdc-42010af000bc:1-41");
assertThat(connector.isContainedWithin(server)).isTrue();
}
protected void asertIntervalCount(String uuid, int count) {
UUIDSet set = gtids.forServerWithId(uuid);
assertThat(set.getIntervals().size()).isEqualTo(count);
}
protected void asertIntervalExists( String uuid, int start, int end) {
assertThat(hasInterval(uuid,start,end)).isTrue();
protected void asertIntervalExists(String uuid, int start, int end) {
assertThat(hasInterval(uuid, start, end)).isTrue();
}
protected void asertFirstInterval( String uuid, int start, int end) {
protected void asertFirstInterval(String uuid, int start, int end) {
UUIDSet set = gtids.forServerWithId(uuid);
Interval interval = set.getIntervals().iterator().next();
assertThat(interval.getStart()).isEqualTo(start);
assertThat(interval.getEnd()).isEqualTo(end);
}
protected void asertLastInterval( String uuid, int start, int end) {
protected void asertLastInterval(String uuid, int start, int end) {
UUIDSet set = gtids.forServerWithId(uuid);
Interval interval = new LinkedList<>(set.getIntervals()).getLast();
assertThat(interval.getStart()).isEqualTo(start);
assertThat(interval.getEnd()).isEqualTo(end);
}
protected boolean hasInterval( String uuid, int start, int end) {
protected boolean hasInterval(String uuid, int start, int end) {
UUIDSet set = gtids.forServerWithId(uuid);
for ( Interval interval : set.getIntervals() ) {
if ( interval.getStart() == start && interval.getEnd() == end ) return true;
for (Interval interval : set.getIntervals()) {
if (interval.getStart() == start && interval.getEnd() == end) return true;
}
return false;
}