mirror of
https://github.com/alibaba/canal.git
synced 2026-11-04 00:30:15 +08:00
fixed issue #1070, support mysql8.0.13
This commit is contained in:
@@ -275,6 +275,7 @@ public class MysqlMultiStageCoprocessor extends AbstractCanalLifeCycle implement
|
||||
needDmlParse = true;
|
||||
break;
|
||||
case LogEvent.UPDATE_ROWS_EVENT_V1:
|
||||
case LogEvent.PARTIAL_UPDATE_ROWS_EVENT:
|
||||
case LogEvent.UPDATE_ROWS_EVENT:
|
||||
tableMeta = logEventConvert.parseRowsEventForTableMeta((UpdateRowsLogEvent) logEvent);
|
||||
needDmlParse = true;
|
||||
|
||||
@@ -120,6 +120,7 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
case LogEvent.WRITE_ROWS_EVENT:
|
||||
return parseRowsEvent((WriteRowsLogEvent) logEvent);
|
||||
case LogEvent.UPDATE_ROWS_EVENT_V1:
|
||||
case LogEvent.PARTIAL_UPDATE_ROWS_EVENT:
|
||||
case LogEvent.UPDATE_ROWS_EVENT:
|
||||
return parseRowsEvent((UpdateRowsLogEvent) logEvent);
|
||||
case LogEvent.DELETE_ROWS_EVENT_V1:
|
||||
@@ -261,7 +262,7 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
}
|
||||
|
||||
boolean isDml = (type == EventType.INSERT || type == EventType.UPDATE || type == EventType.DELETE);
|
||||
|
||||
|
||||
if (!isSeek && !isDml) {
|
||||
// 使用新的表结构元数据管理方式
|
||||
EntryPosition position = createPosition(event.getHeader());
|
||||
@@ -504,7 +505,8 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
int type = event.getHeader().getType();
|
||||
if (LogEvent.WRITE_ROWS_EVENT_V1 == type || LogEvent.WRITE_ROWS_EVENT == type) {
|
||||
eventType = EventType.INSERT;
|
||||
} else if (LogEvent.UPDATE_ROWS_EVENT_V1 == type || LogEvent.UPDATE_ROWS_EVENT == type) {
|
||||
} else if (LogEvent.UPDATE_ROWS_EVENT_V1 == type || LogEvent.UPDATE_ROWS_EVENT == type
|
||||
|| LogEvent.PARTIAL_UPDATE_ROWS_EVENT == type) {
|
||||
eventType = EventType.UPDATE;
|
||||
} else if (LogEvent.DELETE_ROWS_EVENT_V1 == type || LogEvent.DELETE_ROWS_EVENT == type) {
|
||||
eventType = EventType.DELETE;
|
||||
@@ -523,7 +525,7 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
|
||||
boolean tableError = false;
|
||||
int rowsCount = 0;
|
||||
while (buffer.nextOneRow(columns)) {
|
||||
while (buffer.nextOneRow(columns, false)) {
|
||||
// 处理row记录
|
||||
RowData.Builder rowDataBuilder = RowData.newBuilder();
|
||||
if (EventType.INSERT == eventType) {
|
||||
@@ -535,7 +537,7 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
} else {
|
||||
// update需要处理before/after
|
||||
tableError |= parseOneRow(rowDataBuilder, event, buffer, columns, false, tableMeta);
|
||||
if (!buffer.nextOneRow(changeColumns)) {
|
||||
if (!buffer.nextOneRow(changeColumns, true)) {
|
||||
rowChangeBuider.addRowDatas(rowDataBuilder.build());
|
||||
break;
|
||||
}
|
||||
@@ -577,7 +579,8 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
boolean isAfter, TableMeta tableMeta) throws UnsupportedEncodingException {
|
||||
int columnCnt = event.getTable().getColumnCnt();
|
||||
ColumnInfo[] columnInfo = event.getTable().getColumnInfo();
|
||||
|
||||
// mysql8.0针对set @@global.binlog_row_metadata='FULL' 可以记录部分的metadata信息
|
||||
boolean existOptionalMetaData = event.getTable().isExistOptionalMetaData();
|
||||
boolean tableError = false;
|
||||
// check table fileds count,只能处理加字段
|
||||
boolean existRDSNoPrimaryKey = false;
|
||||
@@ -631,22 +634,43 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
continue;
|
||||
}
|
||||
|
||||
if (existRDSNoPrimaryKey && i == columnCnt - 1 && info.type == LogEvent.MYSQL_TYPE_LONGLONG) {
|
||||
// 不解析最后一列
|
||||
buffer.nextValue(info.type, info.meta, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
Column.Builder columnBuilder = Column.newBuilder();
|
||||
|
||||
FieldMeta fieldMeta = null;
|
||||
if (tableMeta != null && !tableError) {
|
||||
// 处理file meta
|
||||
fieldMeta = tableMeta.getFields().get(i);
|
||||
}
|
||||
|
||||
if (existRDSNoPrimaryKey && i == columnCnt - 1 && info.type == LogEvent.MYSQL_TYPE_LONGLONG) {
|
||||
// 不解析最后一列
|
||||
buffer.nextValue(fieldMeta.getColumnName(), i, info.type, info.meta, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fieldMeta != null && existOptionalMetaData) {
|
||||
// check column info
|
||||
boolean check = StringUtils.equalsIgnoreCase(fieldMeta.getColumnName(), info.name);
|
||||
check &= (fieldMeta.isUnsigned() == info.unsigned);
|
||||
check &= (fieldMeta.isNullable() == info.nullable);
|
||||
|
||||
if (!check) {
|
||||
throw new CanalParseException("MySQL8.0 unmatch column metadata & pls submit issue , db : "
|
||||
+ fieldMeta.toString() + " , binlog : " + info.toString()
|
||||
+ " , on : " + event.getHeader().getLogFileName() + ":"
|
||||
+ event.getHeader().getLogPos());
|
||||
}
|
||||
}
|
||||
|
||||
Column.Builder columnBuilder = Column.newBuilder();
|
||||
if (fieldMeta != null) {
|
||||
columnBuilder.setName(fieldMeta.getColumnName());
|
||||
columnBuilder.setIsKey(fieldMeta.isKey());
|
||||
// 增加mysql type类型,issue 73
|
||||
columnBuilder.setMysqlType(fieldMeta.getColumnType());
|
||||
} else if (existOptionalMetaData) {
|
||||
columnBuilder.setName(info.name);
|
||||
columnBuilder.setIsKey(info.pk);
|
||||
// mysql8.0里没有mysql type类型
|
||||
// columnBuilder.setMysqlType(fieldMeta.getColumnType());
|
||||
}
|
||||
columnBuilder.setIndex(i);
|
||||
columnBuilder.setIsNull(false);
|
||||
@@ -664,12 +688,8 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
isSingleBit = true;
|
||||
}
|
||||
}
|
||||
buffer.nextValue(info.type, info.meta, isBinary);
|
||||
if (existRDSNoPrimaryKey && i == columnCnt - 1 && info.type == LogEvent.MYSQL_TYPE_LONGLONG) {
|
||||
// 不解析最后一列
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer.nextValue(fieldMeta.getColumnName(), i, info.type, info.meta, isBinary);
|
||||
int javaType = buffer.getJavaType();
|
||||
if (buffer.isNull()) {
|
||||
columnBuilder.setIsNull(true);
|
||||
@@ -683,7 +703,8 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
case Types.BIGINT:
|
||||
// 处理unsigned类型
|
||||
Number number = (Number) value;
|
||||
if (fieldMeta != null && fieldMeta.isUnsigned() && number.longValue() < 0) {
|
||||
boolean isUnsigned = (fieldMeta != null ? fieldMeta.isUnsigned() : (existOptionalMetaData ? info.unsigned : false));
|
||||
if (isUnsigned && number.longValue() < 0) {
|
||||
switch (buffer.getLength()) {
|
||||
case 1: /* MYSQL_TYPE_TINY */
|
||||
columnBuilder.setValue(String.valueOf(Integer.valueOf(TINYINT_MAX_VALUE
|
||||
@@ -772,7 +793,6 @@ public class LogEventConvert extends AbstractCanalLifeCycle implements BinlogPar
|
||||
default:
|
||||
columnBuilder.setValue(value.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
columnBuilder.setSqlType(javaType);
|
||||
|
||||
Reference in New Issue
Block a user