{"record":{"id":"8554a0a8eb93e665","repo":"alibaba/canal","slug":"use-gtid-and-tablemeta-tsdb-should-be-config-times","errorCode":null,"errorMessage":"use gtid and TableMeta TSDB should be config timestamp > 0","messagePattern":"use gtid and TableMeta TSDB should be config timestamp > 0","errorType":"exception","errorClass":"CanalParseException","httpStatus":null,"severity":"error","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/AbstractMysqlEventParser.java","lineNumber":141,"sourceCode":"        if (binlogParser instanceof LogEventConvert) {\n            ((LogEventConvert) binlogParser).setFieldBlackFilterMap(getFieldBlackFilterMap());\n        }\n\n        if (tableMetaTSDB != null && tableMetaTSDB instanceof DatabaseTableMeta) {\n            ((DatabaseTableMeta) tableMetaTSDB).setFieldBlackFilterMap(getFieldBlackFilterMap());\n        }\n    }\n\n    /**\n     * 回滚到指定位点\n     * \n     * @param position\n     * @return\n     */\n    protected boolean processTableMeta(EntryPosition position) {\n        if (tableMetaTSDB != null) {\n            if (position.getTimestamp() == null || position.getTimestamp() <= 0) {\n                throw new CanalParseException(\"use gtid and TableMeta TSDB should be config timestamp > 0\");\n            }\n\n            return tableMetaTSDB.rollback(position);\n        }\n\n        return true;\n    }\n\n    public void start() throws CanalParseException {\n        if (enableTsdb) {\n            if (tableMetaTSDB == null) {\n                synchronized (CanalEventParser.class) {\n                    buildTableMetaTSDB(tsdbSpringXml);\n                }\n            }\n        }\n\n        super.start();","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/AbstractMysqlEventParser.java#L123-L159","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Ensure the start position is derived from a real binlog event that carries a timestamp (not a hand-built GTID-only position).","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.","Verify GTID and TSDB are intended to be used together; if not needed, disable TSDB (canal.instance.tsdb.enable=false) for that instance.","Upgrade to a Canal release that populates timestamp alongside GTID positions."],"exampleFix":"# ensure GTID start resolves a timestamped position; do not hand-build bare gtid\ncanal.instance.gtidon = true\n# let canal compute startPosition from the master rather than a manual gtid with no timestamp","handlingStrategy":"validation","validationCode":"if (enableTsdb && isGtidMode && (startPosition.getTimestamp() == null || startPosition.getTimestamp() <= 0)) {\n    throw new IllegalStateException(\"GTID + TSDB requires a positive timestamp on the start position\");\n}","typeGuard":null,"tryCatchPattern":"try { parser.start(); }\ncatch (CanalParseException e) {\n    if (e.getMessage().contains(\"timestamp > 0\")) { startPosition = resolveGtidPositionWithTimestamp(); parser.start(); }\n    else throw e;\n}","preventionTips":["Derive GTID start positions from real binlog events so timestamp is populated.","Do not hand-build bare GTID positions with TSDB enabled.","If TSDB is not required for an instance, disable it."],"tags":["parse","gtid","tsdb","position","timestamp"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}