alibaba/canal · error · CanalParseException

apply history to db failed caused by : {errorMessage}

Error message

apply history to db failed caused by : {errorMessage}

What it means

Thrown as CanalParseException by DatabaseTableMeta.applyHistoryToDB() when inserting a MetaHistoryDO record into the database fails with a non-duplicate-key exception. Duplicate key exceptions are silently ignored (idempotent replay), but all other DB exceptions propagate here.

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/tsdb/DatabaseTableMeta.java:445

        if (ddlResults.size() > 0) {
            DdlResult ddlResult = ddlResults.get(0);
            metaDO.setSqlSchema(ddlResult.getSchemaName());
            metaDO.setSqlTable(ddlResult.getTableName());
            metaDO.setSqlType(ddlResult.getType().name());
            metaDO.setSqlText(ddl);
            metaDO.setExtra(extra);
        }
        try {
            // 会建立唯一约束,解决:
            // 1. 重复的binlog file+offest
            // 2. 重复的masterId+timestamp
            metaHistoryDAO.insert(metaDO);
        } catch (Throwable e) {
            if (isUkDuplicateException(e)) {
                // 忽略掉重复的位点
                logger.warn("dup apply for sql : " + ddl);
            } else {
                throw new CanalParseException("apply history to db failed caused by : " + e.getMessage(), e);
            }

        }
        return true;
    }

    /**
     * 发布数据到console上
     */
    private boolean applySnapshotToDB(EntryPosition position, boolean init) {
        // 获取一份快照
        Map<String, String> schemaDdls = null;
        lock.readLock().lock();
        try {
            if (!init && !hasNewDdl) {
                // 如果是持续构建,则识别一下是否有DDL变更过,如果没有就忽略了
                return false;
            }

View on GitHub (pinned to 87be50e876)

Solutions

  1. Check the cause exception (e) for the specific database error — getMessage() contains the DB error message.
  2. Verify the TSDB database connection is valid and the canal user has INSERT permission on the meta_history table.
  3. If 'Data too long', increase the column size for the sql_text or extra fields in the TSDB schema.
  4. If 'Table doesn't exist', run the canal TSDB DDL migration scripts.
  5. If connection issues, check datasource configuration and database availability.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    tableMeta.apply(position, schema, ddl, extra);
} catch (CanalParseException e) {
    if (e.getMessage().contains("apply history to db failed")) {
        Throwable dbCause = e.getCause();
        // handle DB-specific failure (connection, schema, etc.)
    }
}

Prevention

When it happens

Trigger: metaHistoryDAO.insert() throws a non-UK-duplicate exception: connection failure, table doesn't exist, column type mismatch, data too long for a column, database is read-only, or deadlocks that aren't classified as UK violations.

Common situations: TSDB database (MySQL) is unreachable or credentials changed; the canal_tsdb table schema is out of date after a canal upgrade; the DDL text is too long for the sql_text column; database connection pool exhausted; the TSDB MySQL was restarted mid-operation.

Related errors


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