|
15 | 15 | */ |
16 | 16 | package com.github.shyiko.mysql.binlog; |
17 | 17 |
|
18 | | -import com.github.shyiko.mysql.binlog.event.Event; |
19 | | -import com.github.shyiko.mysql.binlog.event.EventHeader; |
20 | | -import com.github.shyiko.mysql.binlog.event.EventHeaderV4; |
21 | | -import com.github.shyiko.mysql.binlog.event.EventType; |
22 | | -import com.github.shyiko.mysql.binlog.event.GtidEventData; |
23 | | -import com.github.shyiko.mysql.binlog.event.QueryEventData; |
24 | | -import com.github.shyiko.mysql.binlog.event.RotateEventData; |
25 | | -import com.github.shyiko.mysql.binlog.event.deserialization.ChecksumType; |
26 | | -import com.github.shyiko.mysql.binlog.event.deserialization.EventDataDeserializationException; |
27 | | -import com.github.shyiko.mysql.binlog.event.deserialization.EventDataDeserializer; |
28 | | -import com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer; |
| 18 | +import com.github.shyiko.mysql.binlog.event.*; |
| 19 | +import com.github.shyiko.mysql.binlog.event.deserialization.*; |
29 | 20 | import com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer.EventDataWrapper; |
30 | | -import com.github.shyiko.mysql.binlog.event.deserialization.GtidEventDataDeserializer; |
31 | | -import com.github.shyiko.mysql.binlog.event.deserialization.QueryEventDataDeserializer; |
32 | | -import com.github.shyiko.mysql.binlog.event.deserialization.RotateEventDataDeserializer; |
33 | 21 | import com.github.shyiko.mysql.binlog.io.ByteArrayInputStream; |
34 | 22 | import com.github.shyiko.mysql.binlog.jmx.BinaryLogClientMXBean; |
35 | 23 | import com.github.shyiko.mysql.binlog.network.AuthenticationException; |
|
46 | 34 | import com.github.shyiko.mysql.binlog.network.protocol.Packet; |
47 | 35 | import com.github.shyiko.mysql.binlog.network.protocol.PacketChannel; |
48 | 36 | import com.github.shyiko.mysql.binlog.network.protocol.ResultSetRowPacket; |
49 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.AuthenticateNativePasswordCommand; |
50 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.AuthenticateSHA2Command; |
51 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.AuthenticateSecurityPasswordCommand; |
52 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.Command; |
53 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.DumpBinaryLogCommand; |
54 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.DumpBinaryLogGtidCommand; |
55 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.PingCommand; |
56 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.QueryCommand; |
57 | | -import com.github.shyiko.mysql.binlog.network.protocol.command.SSLRequestCommand; |
| 37 | +import com.github.shyiko.mysql.binlog.network.protocol.command.*; |
58 | 38 |
|
59 | 39 | import javax.net.ssl.SSLContext; |
60 | 40 | import javax.net.ssl.TrustManager; |
@@ -141,6 +121,8 @@ public X509Certificate[] getAcceptedIssuers() { |
141 | 121 | private boolean useBinlogFilenamePositionInGtidMode; |
142 | 122 | private String gtid; |
143 | 123 | private boolean tx; |
| 124 | + private boolean isMariadb = false; |
| 125 | + private boolean mariadbSendAnnotateRowsEvent = false; |
144 | 126 |
|
145 | 127 | private EventDeserializer eventDeserializer = new EventDeserializer(); |
146 | 128 |
|
@@ -335,7 +317,12 @@ public void setGtidSet(String gtidSet) { |
335 | 317 | this.binlogFilename = ""; |
336 | 318 | } |
337 | 319 | synchronized (gtidSetAccessLock) { |
338 | | - this.gtidSet = gtidSet != null ? new GtidSet(gtidSet) : null; |
| 320 | + // mariadb GtidSet format will be domainId-serverId-sequence |
| 321 | + if (gtidSet != null && !gtidSet.contains(":")) { |
| 322 | + this.gtidSet = new MariadbGtidSet(gtidSet); |
| 323 | + } else { |
| 324 | + this.gtidSet = gtidSet != null ? new GtidSet(gtidSet) : null; |
| 325 | + } |
339 | 326 | } |
340 | 327 | } |
341 | 328 |
|
@@ -501,6 +488,19 @@ public void setThreadFactory(ThreadFactory threadFactory) { |
501 | 488 | this.threadFactory = threadFactory; |
502 | 489 | } |
503 | 490 |
|
| 491 | + public boolean isMariadbSendAnnotateRowsEvent() { |
| 492 | + return mariadbSendAnnotateRowsEvent; |
| 493 | + } |
| 494 | + |
| 495 | + /** |
| 496 | + * Only in Mariadb, if set true, the Slave server connects with the BINLOG_SEND_ANNOTATE_ROWS_EVENT flag (value is 2) |
| 497 | + * in the COM_BINLOG_DUMP Slave Registration phase |
| 498 | + * @param mariadbSendAnnotateRowsEvent |
| 499 | + */ |
| 500 | + public void setMariadbSendAnnotateRowsEvent(boolean mariadbSendAnnotateRowsEvent) { |
| 501 | + this.mariadbSendAnnotateRowsEvent = mariadbSendAnnotateRowsEvent; |
| 502 | + } |
| 503 | + |
504 | 504 | /** |
505 | 505 | * Connect to the replication stream. Note that this method blocks until disconnected. |
506 | 506 | * @throws AuthenticationException if authentication fails |
@@ -538,10 +538,15 @@ public void connect() throws IOException, IllegalStateException { |
538 | 538 | channel.authenticationComplete(); |
539 | 539 |
|
540 | 540 | connectionId = greetingPacket.getThreadId(); |
| 541 | + isMariadb = greetingPacket.getServerVersion().toLowerCase().contains("mariadb"); |
541 | 542 | if ("".equals(binlogFilename)) { |
542 | 543 | synchronized (gtidSetAccessLock) { |
543 | 544 | if (gtidSet != null && "".equals(gtidSet.toString()) && gtidSetFallbackToPurged) { |
544 | | - gtidSet = new GtidSet(fetchGtidPurged()); |
| 545 | + if (isMariadb) { |
| 546 | + gtidSet = new MariadbGtidSet(fetchGtidPurged()); |
| 547 | + } else { |
| 548 | + gtidSet = new GtidSet(fetchGtidPurged()); |
| 549 | + } |
545 | 550 | } |
546 | 551 | } |
547 | 552 | } |
@@ -594,6 +599,11 @@ public void connect() throws IOException, IllegalStateException { |
594 | 599 | if (gtidSet != null) { |
595 | 600 | ensureEventDataDeserializer(EventType.GTID, GtidEventDataDeserializer.class); |
596 | 601 | ensureEventDataDeserializer(EventType.QUERY, QueryEventDataDeserializer.class); |
| 602 | + if (isMariadb) { |
| 603 | + ensureEventDataDeserializer(EventType.ANNOTATE_ROWS, AnnotateRowsEventDataDeserializer.class); |
| 604 | + ensureEventDataDeserializer(EventType.MARIADB_GTID, MariadbGtidEventDataDeserializer.class); |
| 605 | + ensureEventDataDeserializer(EventType.MARIADB_GTID_LIST, MariadbGtidListEventDataDeserializer.class); |
| 606 | + } |
597 | 607 | } |
598 | 608 | } |
599 | 609 | listenForEventPackets(); |
@@ -730,10 +740,22 @@ private void requestBinaryLogStream() throws IOException { |
730 | 740 | Command dumpBinaryLogCommand; |
731 | 741 | synchronized (gtidSetAccessLock) { |
732 | 742 | if (gtidSet != null) { |
733 | | - dumpBinaryLogCommand = new DumpBinaryLogGtidCommand(serverId, |
734 | | - useBinlogFilenamePositionInGtidMode ? binlogFilename : "", |
735 | | - useBinlogFilenamePositionInGtidMode ? binlogPosition : 4, |
736 | | - gtidSet); |
| 743 | + if (isMariadb) { |
| 744 | + channel.write(new QueryCommand("SET @mariadb_slave_capability=4")); |
| 745 | + checkError(channel.read()); |
| 746 | + channel.write(new QueryCommand("SET @slave_connect_state = '" + gtidSet.toString() + "'")); |
| 747 | + checkError(channel.read()); |
| 748 | + channel.write(new QueryCommand("SET @slave_gtid_strict_mode = 0")); |
| 749 | + checkError(channel.read()); |
| 750 | + channel.write(new QueryCommand("SET @slave_gtid_ignore_duplicates = 0")); |
| 751 | + checkError(channel.read()); |
| 752 | + dumpBinaryLogCommand = new DumpBinaryLogCommand(serverId, "", 0L, isMariadbSendAnnotateRowsEvent()); |
| 753 | + } else { |
| 754 | + dumpBinaryLogCommand = new DumpBinaryLogGtidCommand(serverId, |
| 755 | + useBinlogFilenamePositionInGtidMode ? binlogFilename : "", |
| 756 | + useBinlogFilenamePositionInGtidMode ? binlogPosition : 4, |
| 757 | + gtidSet); |
| 758 | + } |
737 | 759 | } else { |
738 | 760 | dumpBinaryLogCommand = new DumpBinaryLogCommand(serverId, binlogFilename, binlogPosition); |
739 | 761 | } |
@@ -1034,13 +1056,30 @@ private void updateGtidSet(Event event) { |
1034 | 1056 | GtidEventData gtidEventData = (GtidEventData) EventDataWrapper.internal(event.getData()); |
1035 | 1057 | gtid = gtidEventData.getGtid(); |
1036 | 1058 | break; |
| 1059 | + case MARIADB_GTID: |
| 1060 | + MariadbGtidEventData mariadbGtidEventData = (MariadbGtidEventData) EventDataWrapper.internal(event.getData()); |
| 1061 | + mariadbGtidEventData.setServerId(eventHeader.getServerId()); |
| 1062 | + gtid = mariadbGtidEventData.toString(); |
| 1063 | + break; |
| 1064 | + case MARIADB_GTID_LIST: |
| 1065 | + MariadbGtidListEventData mariadbGtidListEventData = (MariadbGtidListEventData) EventDataWrapper.internal(event.getData()); |
| 1066 | + gtid = mariadbGtidListEventData.getMariaGTIDSet().toString(); |
| 1067 | + break; |
1037 | 1068 | case XID: |
1038 | 1069 | commitGtid(); |
1039 | 1070 | tx = false; |
1040 | 1071 | break; |
1041 | 1072 | case QUERY: |
1042 | | - QueryEventData queryEventData = (QueryEventData) EventDataWrapper.internal(event.getData()); |
1043 | | - String sql = queryEventData.getSql(); |
| 1073 | + case ANNOTATE_ROWS: |
| 1074 | + String sql; |
| 1075 | + if (eventHeader.getEventType() == EventType.QUERY) { |
| 1076 | + QueryEventData queryEventData = (QueryEventData) EventDataWrapper.internal(event.getData()); |
| 1077 | + sql = queryEventData.getSql(); |
| 1078 | + } else { |
| 1079 | + AnnotateRowsEventData annotateRowsEventData = (AnnotateRowsEventData) EventDataWrapper.internal(event.getData()); |
| 1080 | + sql = annotateRowsEventData.getRowsQuery(); |
| 1081 | + } |
| 1082 | + |
1044 | 1083 | if (sql == null) { |
1045 | 1084 | break; |
1046 | 1085 | } |
|
0 commit comments