mirror of
https://github.com/alibaba/canal.git
synced 2026-11-04 00:30:15 +08:00
fix bug #890
This commit is contained in:
@@ -66,18 +66,11 @@ public final class LogContext {
|
|||||||
mapOfTable.clear();
|
mapOfTable.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void putGtid(GtidLogEvent logEvent) {
|
|
||||||
if (logEvent != null) {
|
|
||||||
String gtid = logEvent.getSid().toString() + ":" + logEvent.getGno();
|
|
||||||
if (gtidSet == null) {
|
|
||||||
gtid = logEvent.getSid().toString() + ":1-" + logEvent.getGno();
|
|
||||||
gtidSet = MysqlGTIDSet.parse(gtid);
|
|
||||||
}
|
|
||||||
gtidSet.update(gtid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public GTIDSet getGtidSet() {
|
public GTIDSet getGtidSet() {
|
||||||
return gtidSet;
|
return gtidSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGtidSet(GTIDSet gtidSet) {
|
||||||
|
this.gtidSet = gtidSet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.IOException;
|
|||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
|
||||||
import com.alibaba.otter.canal.parse.driver.mysql.packets.GTIDSet;
|
import com.alibaba.otter.canal.parse.driver.mysql.packets.GTIDSet;
|
||||||
|
import com.alibaba.otter.canal.parse.driver.mysql.packets.MysqlGTIDSet;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -160,6 +161,7 @@ public final class LogDecoder {
|
|||||||
// remove checksum bytes
|
// remove checksum bytes
|
||||||
buffer.limit(header.getEventLen() - LogEvent.BINLOG_CHECKSUM_LEN);
|
buffer.limit(header.getEventLen() - LogEvent.BINLOG_CHECKSUM_LEN);
|
||||||
}
|
}
|
||||||
|
GTIDSet gtidSet = context.getGtidSet();
|
||||||
switch (header.getType()) {
|
switch (header.getType()) {
|
||||||
case LogEvent.QUERY_EVENT: {
|
case LogEvent.QUERY_EVENT: {
|
||||||
QueryLogEvent event = new QueryLogEvent(header, buffer, descriptionEvent);
|
QueryLogEvent event = new QueryLogEvent(header, buffer, descriptionEvent);
|
||||||
@@ -373,8 +375,11 @@ public final class LogDecoder {
|
|||||||
GtidLogEvent event = new GtidLogEvent(header, buffer, descriptionEvent);
|
GtidLogEvent event = new GtidLogEvent(header, buffer, descriptionEvent);
|
||||||
/* updating position in context */
|
/* updating position in context */
|
||||||
logPosition.position = header.getLogPos();
|
logPosition.position = header.getLogPos();
|
||||||
|
if (gtidSet != null) {
|
||||||
|
gtidSet.update(event.getGtidStr());
|
||||||
// update latest gtid
|
// update latest gtid
|
||||||
context.putGtid(event);
|
header.putGtidStr(gtidSet);
|
||||||
|
}
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
case LogEvent.PREVIOUS_GTIDS_LOG_EVENT: {
|
case LogEvent.PREVIOUS_GTIDS_LOG_EVENT: {
|
||||||
|
|||||||
@@ -82,4 +82,11 @@ public class GtidLogEvent extends LogEvent {
|
|||||||
public Long getSequenceNumber() {
|
public Long getSequenceNumber() {
|
||||||
return sequenceNumber;
|
return sequenceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getGtidStr() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(sid.toString()).append(":");
|
||||||
|
sb.append(gno);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import java.util.TimerTask;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import com.alibaba.otter.canal.parse.driver.mysql.packets.GTIDSet;
|
||||||
|
import com.alibaba.otter.canal.parse.inbound.mysql.MysqlMultiStageCoprocessor;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
import org.apache.commons.lang.math.RandomUtils;
|
import org.apache.commons.lang.math.RandomUtils;
|
||||||
@@ -235,12 +237,14 @@ public abstract class AbstractEventParser<EVENT> extends AbstractCanalLifeCycle
|
|||||||
if (parallel) {
|
if (parallel) {
|
||||||
// build stage processor
|
// build stage processor
|
||||||
multiStageCoprocessor = buildMultiStageCoprocessor();
|
multiStageCoprocessor = buildMultiStageCoprocessor();
|
||||||
multiStageCoprocessor.start();
|
|
||||||
|
|
||||||
if (isGTIDMode()) {
|
if (isGTIDMode()) {
|
||||||
// 判断所属instance是否启用GTID模式,是的话调用ErosaConnection中GTID对应方法dump数据
|
// 判断所属instance是否启用GTID模式,是的话调用ErosaConnection中GTID对应方法dump数据
|
||||||
erosaConnection.dump(MysqlGTIDSet.parse(startPosition.getGtid()), multiStageCoprocessor);
|
GTIDSet gtidSet = MysqlGTIDSet.parse(startPosition.getGtid());
|
||||||
|
((MysqlMultiStageCoprocessor) multiStageCoprocessor).setGtidSet(gtidSet);
|
||||||
|
multiStageCoprocessor.start();
|
||||||
|
erosaConnection.dump(gtidSet, multiStageCoprocessor);
|
||||||
} else {
|
} else {
|
||||||
|
multiStageCoprocessor.start();
|
||||||
if (StringUtils.isEmpty(startPosition.getJournalName())
|
if (StringUtils.isEmpty(startPosition.getJournalName())
|
||||||
&& startPosition.getTimestamp() != null) {
|
&& startPosition.getTimestamp() != null) {
|
||||||
erosaConnection.dump(startPosition.getTimestamp(), multiStageCoprocessor);
|
erosaConnection.dump(startPosition.getTimestamp(), multiStageCoprocessor);
|
||||||
|
|||||||
@@ -76,13 +76,6 @@ public abstract class AbstractMysqlEventParser extends AbstractEventParser {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected boolean processTableMeta(EntryPosition position) {
|
protected boolean processTableMeta(EntryPosition position) {
|
||||||
if (isGTIDMode()) {
|
|
||||||
if (binlogParser instanceof LogEventConvert) {
|
|
||||||
// 记录gtid
|
|
||||||
((LogEventConvert) binlogParser).setGtidSet(MysqlGTIDSet.parse(position.getGtid()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tableMetaTSDB != null) {
|
if (tableMetaTSDB != null) {
|
||||||
if (position.getTimestamp() == null || position.getTimestamp() <= 0) {
|
if (position.getTimestamp() == null || position.getTimestamp() <= 0) {
|
||||||
throw new CanalParseException("use gtid and TableMeta TSDB should be config timestamp > 0");
|
throw new CanalParseException("use gtid and TableMeta TSDB should be config timestamp > 0");
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ public class MysqlConnection implements ErosaConnection {
|
|||||||
fetcher.start(connector.getChannel());
|
fetcher.start(connector.getChannel());
|
||||||
LogDecoder decoder = new LogDecoder(LogEvent.UNKNOWN_EVENT, LogEvent.ENUM_END_EVENT);
|
LogDecoder decoder = new LogDecoder(LogEvent.UNKNOWN_EVENT, LogEvent.ENUM_END_EVENT);
|
||||||
LogContext context = new LogContext();
|
LogContext context = new LogContext();
|
||||||
|
// fix bug: #890 将gtid传输至context中,供decode使用
|
||||||
|
context.setGtidSet(gtidSet);
|
||||||
while (fetcher.fetch()) {
|
while (fetcher.fetch()) {
|
||||||
accumulateReceivedBytes(fetcher.limit());
|
accumulateReceivedBytes(fetcher.limit());
|
||||||
LogEvent event = null;
|
LogEvent event = null;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.util.concurrent.locks.LockSupport;
|
|||||||
|
|
||||||
import com.alibaba.otter.canal.common.AbstractCanalLifeCycle;
|
import com.alibaba.otter.canal.common.AbstractCanalLifeCycle;
|
||||||
import com.alibaba.otter.canal.common.utils.NamedThreadFactory;
|
import com.alibaba.otter.canal.common.utils.NamedThreadFactory;
|
||||||
|
import com.alibaba.otter.canal.parse.driver.mysql.packets.GTIDSet;
|
||||||
import com.alibaba.otter.canal.parse.exception.CanalParseException;
|
import com.alibaba.otter.canal.parse.exception.CanalParseException;
|
||||||
import com.alibaba.otter.canal.parse.inbound.ErosaConnection;
|
import com.alibaba.otter.canal.parse.inbound.ErosaConnection;
|
||||||
import com.alibaba.otter.canal.parse.inbound.EventTransactionBuffer;
|
import com.alibaba.otter.canal.parse.inbound.EventTransactionBuffer;
|
||||||
@@ -63,6 +64,7 @@ public class MysqlMultiStageCoprocessor extends AbstractCanalLifeCycle implement
|
|||||||
private String destination;
|
private String destination;
|
||||||
private volatile CanalParseException exception;
|
private volatile CanalParseException exception;
|
||||||
private AtomicLong eventsPublishBlockingTime;
|
private AtomicLong eventsPublishBlockingTime;
|
||||||
|
private GTIDSet gtidSet;
|
||||||
|
|
||||||
public MysqlMultiStageCoprocessor(int ringBufferSize, int parserThreadCount, LogEventConvert logEventConvert,
|
public MysqlMultiStageCoprocessor(int ringBufferSize, int parserThreadCount, LogEventConvert logEventConvert,
|
||||||
EventTransactionBuffer transactionBuffer, String destination){
|
EventTransactionBuffer transactionBuffer, String destination){
|
||||||
@@ -227,6 +229,9 @@ public class MysqlMultiStageCoprocessor extends AbstractCanalLifeCycle implement
|
|||||||
public SimpleParserStage(){
|
public SimpleParserStage(){
|
||||||
decoder = new LogDecoder(LogEvent.UNKNOWN_EVENT, LogEvent.ENUM_END_EVENT);
|
decoder = new LogDecoder(LogEvent.UNKNOWN_EVENT, LogEvent.ENUM_END_EVENT);
|
||||||
context = new LogContext();
|
context = new LogContext();
|
||||||
|
if (gtidSet != null) {
|
||||||
|
context.setGtidSet(gtidSet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEvent(MessageEvent event, long sequence, boolean endOfBatch) throws Exception {
|
public void onEvent(MessageEvent event, long sequence, boolean endOfBatch) throws Exception {
|
||||||
@@ -447,4 +452,7 @@ public class MysqlMultiStageCoprocessor extends AbstractCanalLifeCycle implement
|
|||||||
this.eventsPublishBlockingTime = eventsPublishBlockingTime;
|
this.eventsPublishBlockingTime = eventsPublishBlockingTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGtidSet(GTIDSet gtidSet) {
|
||||||
|
this.gtidSet = gtidSet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,13 +99,6 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
|||||||
private boolean filterRows = false;
|
private boolean filterRows = false;
|
||||||
private boolean useDruidDdlFilter = true;
|
private boolean useDruidDdlFilter = true;
|
||||||
|
|
||||||
// latest gtid
|
|
||||||
private GTIDSet gtidSet;
|
|
||||||
|
|
||||||
public LogEventConvert(GTIDSet gtidSet){
|
|
||||||
this.gtidSet = gtidSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LogEventConvert(){
|
public LogEventConvert(){
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -172,10 +165,9 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
|||||||
|
|
||||||
private Entry parseGTIDLogEvent(GtidLogEvent logEvent) {
|
private Entry parseGTIDLogEvent(GtidLogEvent logEvent) {
|
||||||
LogHeader logHeader = logEvent.getHeader();
|
LogHeader logHeader = logEvent.getHeader();
|
||||||
String value = logEvent.getSid().toString() + ":" + logEvent.getGno();
|
|
||||||
Pair.Builder builder = Pair.newBuilder();
|
Pair.Builder builder = Pair.newBuilder();
|
||||||
builder.setKey("gtid");
|
builder.setKey("gtid");
|
||||||
builder.setValue(value);
|
builder.setValue(logEvent.getGtidStr());
|
||||||
|
|
||||||
if (logEvent.getLastCommitted() != null) {
|
if (logEvent.getLastCommitted() != null) {
|
||||||
builder.setKey("lastCommitted");
|
builder.setKey("lastCommitted");
|
||||||
@@ -974,8 +966,4 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
|||||||
public void setFilterRows(boolean filterRows) {
|
public void setFilterRows(boolean filterRows) {
|
||||||
this.filterRows = filterRows;
|
this.filterRows = filterRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGtidSet(GTIDSet gtidSet) {
|
|
||||||
this.gtidSet = gtidSet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user