alibaba/canal · error · CanalParseException

MySQL8.0 unmatch column metadata & pls submit issue , table

Error message

MySQL8.0 unmatch column metadata & pls submit issue , table : {}, db fieldMeta : {} , binlog fieldMeta : {} , on : {}:[]

What it means

Thrown from parseOneRow() during a strict column-metadata consistency check that only runs under two conditions: existOptionalMetaData is true (MySQL 8.0+ binlog includes extra column metadata) and tableMetaCache.isOnTSDB(). The check compares four attributes — column name, unsigned flag, nullable flag — between the DB's fieldMeta and the binlog's fieldMeta (info). If any mismatch is found, Canal aborts with this exception, indicating a serious TSDB/binlog metadata inconsistency.

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/LogEventConvert.java:719

                    }
                }
                continue;
            }

            FieldMeta fieldMeta = null;
            if (tableMeta != null && !tableError) {
                // 处理file meta
                fieldMeta = tableMeta.getFields().get(i);
            }

            if (fieldMeta != null && existOptionalMetaData && tableMetaCache.isOnTSDB()) {
                // 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 , table : "
                                                  + tableMeta.getFullName() + ", db fieldMeta : "
                                                  + fieldMeta.toString() + " , binlog fieldMeta : " + info.toString()
                                                  + " , on : " + event.getHeader().getLogFileName() + ":"
                                                  + (event.getHeader().getLogPos() - event.getHeader().getEventLen()));
                }
            }

            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());

View on GitHub (pinned to 87be50e876)

Solutions

  1. Delete the TSDB history file (canal.instance.tsdb.dir contents) and restart Canal to force a full TSDB rebuild from the current DB state.
  2. Run canal.instance.tsdb.snapshot.expire to force-expire the stale TSDB entries.
  3. Verify the DDL events are not filtered (canal.instance.filter.query.ddl should be false when TSDB is enabled).
  4. If the mismatch is a known Canal bug for your MySQL 8.0.x version, upgrade Canal.

Example fix

# before — stale TSDB persists mismatch
canal.instance.tsdb.enable=true
canal.instance.tsdb.dir=../conf/tsdb

# fix — clear TSDB history and restart
# rm -rf ../conf/tsdb/*
# then restart canal; TSDB will rebuild from live DDL
Defensive patterns

Strategy: fallback

Try / catch

try {
    parseRowsEventForTableMeta(event);
} catch (CanalParseException e) {
    if (e.getMessage().contains("MySQL8.0 unmatch column metadata")) {
        // TSDB snapshot is stale — clear and rebuild
        logger.error("Column metadata mismatch on MySQL 8.0, clearing TSDB history", e);
        clearTsdbHistory(); // delete tsdb.dir contents
        // Restart Canal to rebuild TSDB from current DDL
    }
}

Prevention

When it happens

Trigger: During parseOneRow(), for each column where fieldMeta != null && existOptionalMetaData && isOnTSDB(), Canal compares fieldMeta.getColumnName() vs info.name (case-insensitive), fieldMeta.isUnsigned() vs info.unsigned, and fieldMeta.isNullable() vs info.nullable. A single mismatch triggers the exception. The message includes table name, both metadata representations, and the binlog position.

Common situations: The TSDB snapshot is stale — a DDL changed column attributes (e.g. added NOT NULL, changed signed→unsigned) but TSDB didn't capture the change. MySQL 8.0's binlog includes richer column metadata that Canal's TSDB hasn't been synchronized with. A manual DDL was applied outside of Canal's binlog stream (e.g. on a different replicated server). TSDB history file was corrupted or manually edited.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/50bed5d0b5ab0ead. Report an issue: GitHub.