alibaba/canal · error · CanalParseException

use gtid and TableMeta TSDB should be config timestamp > 0

Error message

use gtid and TableMeta TSDB should be config timestamp > 0

What it means

Thrown as CanalParseException by AbstractMysqlEventParser.processTableMeta when GTID-based replication is combined with TableMeta TSDB but the start position lacks a valid positive timestamp. TSDB rollback needs a timestamp to locate the correct historical table schema at that point in time, so a zero/null timestamp makes the operation ambiguous and is rejected.

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/AbstractMysqlEventParser.java:141

        if (binlogParser instanceof LogEventConvert) {
            ((LogEventConvert) binlogParser).setFieldBlackFilterMap(getFieldBlackFilterMap());
        }

        if (tableMetaTSDB != null && tableMetaTSDB instanceof DatabaseTableMeta) {
            ((DatabaseTableMeta) tableMetaTSDB).setFieldBlackFilterMap(getFieldBlackFilterMap());
        }
    }

    /**
     * 回滚到指定位点
     * 
     * @param position
     * @return
     */
    protected boolean processTableMeta(EntryPosition position) {
        if (tableMetaTSDB != null) {
            if (position.getTimestamp() == null || position.getTimestamp() <= 0) {
                throw new CanalParseException("use gtid and TableMeta TSDB should be config timestamp > 0");
            }

            return tableMetaTSDB.rollback(position);
        }

        return true;
    }

    public void start() throws CanalParseException {
        if (enableTsdb) {
            if (tableMetaTSDB == null) {
                synchronized (CanalEventParser.class) {
                    buildTableMetaTSDB(tsdbSpringXml);
                }
            }
        }

        super.start();

View on GitHub (pinned to 87be50e876)

Solutions

  1. Ensure the start position is derived from a real binlog event that carries a timestamp (not a hand-built GTID-only position).
  2. If you must start by GTID, let Canal resolve the position from the master so the timestamp is populated, rather than supplying a bare GTID.
  3. Verify GTID and TSDB are intended to be used together; if not needed, disable TSDB (canal.instance.tsdb.enable=false) for that instance.
  4. Upgrade to a Canal release that populates timestamp alongside GTID positions.

Example fix

# ensure GTID start resolves a timestamped position; do not hand-build bare gtid
canal.instance.gtidon = true
# let canal compute startPosition from the master rather than a manual gtid with no timestamp
Defensive patterns

Strategy: validation

Validate before calling

if (enableTsdb && isGtidMode && (startPosition.getTimestamp() == null || startPosition.getTimestamp() <= 0)) {
    throw new IllegalStateException("GTID + TSDB requires a positive timestamp on the start position");
}

Try / catch

try { parser.start(); }
catch (CanalParseException e) {
    if (e.getMessage().contains("timestamp > 0")) { startPosition = resolveGtidPositionWithTimestamp(); parser.start(); }
    else throw e;
}

Prevention

When it happens

Trigger: processTableMeta(position) with tableMetaTSDB != null and position.getTimestamp() == null or <= 0. Happens when GTID mode is enabled (canal.instance.gtidon=true) and TSDB is enabled, but the resolved start position carries no timestamp (e.g. a GTID-only position without an accompanying timestamp from the binlog).

Common situations: Mixing GTID start with a position source that does not populate timestamp (older connector, manual GTID entry), TSDB enabled without a compatible position strategy, or a position built without timestamp after a reset.

Related errors


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