Skip to content

Commit b734a32

Browse files
committed
fixed issue #626, support xa rollback/commit event
1 parent 1f16310 commit b734a32

File tree

5 files changed

+4860
-4176
lines changed

5 files changed

+4860
-4176
lines changed

example/src/main/java/com/alibaba/otter/canal/example/AbstractCanalClientTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
1919
import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
2020
import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
21+
import com.alibaba.otter.canal.protocol.CanalEntry.Pair;
2122
import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
2223
import com.alibaba.otter.canal.protocol.CanalEntry.RowData;
2324
import com.alibaba.otter.canal.protocol.CanalEntry.TransactionBegin;
@@ -199,6 +200,7 @@ protected void printEntry(List<Entry> entrys) {
199200
String.valueOf(entry.getHeader().getExecuteTime()), simpleDateFormat.format(date),
200201
entry.getHeader().getGtid(), String.valueOf(delayTime) });
201202
logger.info(" BEGIN ----> Thread id: {}", begin.getThreadId());
203+
printXAInfo(begin.getPropsList());
202204
} else if (entry.getEntryType() == EntryType.TRANSACTIONEND) {
203205
TransactionEnd end = null;
204206
try {
@@ -209,6 +211,7 @@ protected void printEntry(List<Entry> entrys) {
209211
// 打印事务提交信息,事务id
210212
logger.info("----------------\n");
211213
logger.info(" END ----> transaction id: {}", end.getTransactionId());
214+
printXAInfo(end.getPropsList());
212215
logger.info(transaction_format,
213216
new Object[] { entry.getHeader().getLogfileName(),
214217
String.valueOf(entry.getHeader().getLogfileOffset()),
@@ -241,6 +244,7 @@ protected void printEntry(List<Entry> entrys) {
241244
continue;
242245
}
243246

247+
printXAInfo(rowChage.getPropsList());
244248
for (RowData rowData : rowChage.getRowDatasList()) {
245249
if (eventType == EventType.DELETE) {
246250
printColumn(rowData.getBeforeColumnsList());
@@ -267,6 +271,27 @@ protected void printColumn(List<Column> columns) {
267271
}
268272
}
269273

274+
protected void printXAInfo(List<Pair> pairs) {
275+
if (pairs == null) {
276+
return;
277+
}
278+
279+
String xaType = null;
280+
String xaXid = null;
281+
for (Pair pair : pairs) {
282+
String key = pair.getKey();
283+
if (StringUtils.endsWithIgnoreCase(key, "XA_TYPE")) {
284+
xaType = pair.getValue();
285+
} else if (StringUtils.endsWithIgnoreCase(key, "XA_XID")) {
286+
xaXid = pair.getValue();
287+
}
288+
}
289+
290+
if (xaType != null && xaXid != null) {
291+
logger.info(" ------> " + xaType + " " + xaXid);
292+
}
293+
}
294+
270295
public void setConnector(CanalConnector connector) {
271296
this.connector = connector;
272297
}

parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/LogEventConvert.java

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@
6767
*/
6868
public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogParser<LogEvent> {
6969

70+
public static final String XA_XID = "XA_XID";
71+
public static final String XA_TYPE = "XA_TYPE";
72+
public static final String XA_START = "XA START";
73+
public static final String XA_END = "XA END";
74+
public static final String XA_COMMIT = "XA COMMIT";
75+
public static final String XA_ROLLBACK = "XA ROLLBACK";
7076
public static final String ISO_8859_1 = "ISO-8859-1";
7177
public static final String UTF_8 = "UTF-8";
7278
public static final int TINYINT_MAX_VALUE = 256;
@@ -174,7 +180,43 @@ private Entry parseGTIDLogEvent(GtidLogEvent logEvent) {
174180

175181
private Entry parseQueryEvent(QueryLogEvent event, boolean isSeek) {
176182
String queryString = event.getQuery();
177-
if (StringUtils.endsWithIgnoreCase(queryString, BEGIN)) {
183+
if (StringUtils.startsWithIgnoreCase(queryString, XA_START)) {
184+
// xa start use TransactionBegin
185+
TransactionBegin.Builder beginBuilder = TransactionBegin.newBuilder();
186+
beginBuilder.setThreadId(event.getSessionId());
187+
beginBuilder.addProps(createSpecialPair(XA_TYPE, XA_START));
188+
beginBuilder.addProps(createSpecialPair(XA_XID, getXaXid(queryString, XA_START)));
189+
TransactionBegin transactionBegin = beginBuilder.build();
190+
Header header = createHeader(binlogFileName, event.getHeader(), "", "", null);
191+
return createEntry(header, EntryType.TRANSACTIONBEGIN, transactionBegin.toByteString());
192+
} else if (StringUtils.startsWithIgnoreCase(queryString, XA_END)) {
193+
// xa start use TransactionEnd
194+
TransactionEnd.Builder endBuilder = TransactionEnd.newBuilder();
195+
endBuilder.setTransactionId(String.valueOf(0L));
196+
endBuilder.addProps(createSpecialPair(XA_TYPE, XA_END));
197+
endBuilder.addProps(createSpecialPair(XA_XID, getXaXid(queryString, XA_END)));
198+
TransactionEnd transactionEnd = endBuilder.build();
199+
Header header = createHeader(binlogFileName, event.getHeader(), "", "", null);
200+
return createEntry(header, EntryType.TRANSACTIONEND, transactionEnd.toByteString());
201+
} else if (StringUtils.startsWithIgnoreCase(queryString, XA_COMMIT)) {
202+
// xa commit
203+
Header header = createHeader(binlogFileName, event.getHeader(), "", "", EventType.XACOMMIT);
204+
RowChange.Builder rowChangeBuider = RowChange.newBuilder();
205+
rowChangeBuider.setSql(queryString);
206+
rowChangeBuider.addProps(createSpecialPair(XA_TYPE, XA_COMMIT));
207+
rowChangeBuider.addProps(createSpecialPair(XA_XID, getXaXid(queryString, XA_COMMIT)));
208+
rowChangeBuider.setEventType(EventType.XACOMMIT);
209+
return createEntry(header, EntryType.ROWDATA, rowChangeBuider.build().toByteString());
210+
} else if (StringUtils.startsWithIgnoreCase(queryString, XA_ROLLBACK)) {
211+
// xa rollback
212+
Header header = createHeader(binlogFileName, event.getHeader(), "", "", EventType.XAROLLBACK);
213+
RowChange.Builder rowChangeBuider = RowChange.newBuilder();
214+
rowChangeBuider.setSql(queryString);
215+
rowChangeBuider.addProps(createSpecialPair(XA_TYPE, XA_ROLLBACK));
216+
rowChangeBuider.addProps(createSpecialPair(XA_XID, getXaXid(queryString, XA_ROLLBACK)));
217+
rowChangeBuider.setEventType(EventType.XAROLLBACK);
218+
return createEntry(header, EntryType.ROWDATA, rowChangeBuider.build().toByteString());
219+
} else if (StringUtils.endsWithIgnoreCase(queryString, BEGIN)) {
178220
TransactionBegin transactionBegin = createTransactionBegin(event.getSessionId());
179221
Header header = createHeader(binlogFileName, event.getHeader(), "", "", null);
180222
return createEntry(header, EntryType.TRANSACTIONBEGIN, transactionBegin.toByteString());
@@ -237,6 +279,10 @@ private Entry parseQueryEvent(QueryLogEvent event, boolean isSeek) {
237279
}
238280
}
239281

282+
private String getXaXid(String queryString, String type) {
283+
return StringUtils.substringAfter(queryString, type);
284+
}
285+
240286
private boolean processFilter(String queryString, DdlResult result) {
241287
String schemaName = result.getSchemaName();
242288
String tableName = result.getTableName();

parse/src/test/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlDumpTest.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.nio.charset.Charset;
55
import java.util.List;
66

7+
import org.apache.commons.lang.StringUtils;
78
import org.junit.Assert;
89
import org.junit.Test;
910

@@ -16,6 +17,7 @@
1617
import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
1718
import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
1819
import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
20+
import com.alibaba.otter.canal.protocol.CanalEntry.Pair;
1921
import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
2022
import com.alibaba.otter.canal.protocol.CanalEntry.RowData;
2123
import com.alibaba.otter.canal.protocol.position.EntryPosition;
@@ -27,8 +29,8 @@ public class MysqlDumpTest {
2729
@Test
2830
public void testSimple() {
2931
final MysqlEventParser controller = new MysqlEventParser();
30-
final EntryPosition startPosition = new EntryPosition("mysql-bin.000010", 154L, 100L);
31-
startPosition.setGtid("f1ceb61a-a5d5-11e7-bdee-107c3dbcf8a7:1-17");
32+
final EntryPosition startPosition = new EntryPosition("mysql-bin.000012", 34051L, 100L);
33+
// startPosition.setGtid("f1ceb61a-a5d5-11e7-bdee-107c3dbcf8a7:1-17");
3234
controller.setConnectionCharset(Charset.forName("UTF-8"));
3335
controller.setSlaveId(3344L);
3436
controller.setDetectingEnable(false);
@@ -39,7 +41,7 @@ public void testSimple() {
3941
controller.setTsdbSpringXml("classpath:tsdb/h2-tsdb.xml");
4042
controller.setEventFilter(new AviaterRegexFilter("test\\..*"));
4143
controller.setEventBlackFilter(new AviaterRegexFilter("canal_tsdb\\..*"));
42-
controller.setIsGTIDMode(true);
44+
controller.setIsGTIDMode(false);
4345
controller.setEventSink(new AbstractCanalEventSinkTest<List<Entry>>() {
4446

4547
public boolean sink(List<Entry> entrys, InetSocketAddress remoteAddress, String destination)
@@ -73,6 +75,7 @@ public boolean sink(List<Entry> entrys, InetSocketAddress remoteAddress, String
7375
System.out.println(" sql ----> " + rowChage.getSql());
7476
}
7577

78+
printXAInfo(rowChage.getPropsList());
7679
for (RowData rowData : rowChage.getRowDatasList()) {
7780
if (eventType == EventType.DELETE) {
7881
print(rowData.getBeforeColumnsList());
@@ -119,4 +122,25 @@ private void print(List<Column> columns) {
119122
System.out.println(column.getName() + " : " + column.getValue() + " update=" + column.getUpdated());
120123
}
121124
}
125+
126+
private void printXAInfo(List<Pair> pairs) {
127+
if (pairs == null) {
128+
return;
129+
}
130+
131+
String xaType = null;
132+
String xaXid = null;
133+
for (Pair pair : pairs) {
134+
String key = pair.getKey();
135+
if (StringUtils.endsWithIgnoreCase(key, "XA_TYPE")) {
136+
xaType = pair.getValue();
137+
} else if (StringUtils.endsWithIgnoreCase(key, "XA_XID")) {
138+
xaXid = pair.getValue();
139+
}
140+
}
141+
142+
if (xaType != null && xaXid != null) {
143+
System.out.println(" ------> " + xaType + " " + xaXid);
144+
}
145+
}
122146
}

0 commit comments

Comments
 (0)