alibaba/canal · error · RuntimeException

not support for memory

Error message

not support for memory

What it means

Thrown as UnsupportedOperationException-equivalent (RuntimeException) by MemoryTableMeta.rollback() — the in-memory-only table meta implementation does not support rollback operations. Rollback requires persistent history which MemoryTableMeta does not maintain.

Source

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

                        if (table != null) {
                            tableMeta.setTable(table);
                        }
                        if (schema != null) {
                            tableMeta.setSchema(schema);
                        }

                        tableMetas.put(keys, tableMeta);
                    }
                }
            }
        }

        return tableMeta;
    }

    @Override
    public boolean rollback(EntryPosition position) {
        throw new RuntimeException("not support for memory");
    }

    public Map<String, String> snapshot() {
        Map<String, String> schemaDdls = new HashMap<>();
        for (Schema schema : repository.getSchemas()) {
            StringBuilder data = new StringBuilder(4 * 1024);
            for (String table : schema.showTables()) {
                SchemaObject schemaObject = schema.findTable(table);
                // fixed issue #4899
                // snapshot输出的DDL语句未正确处理mysql keyword
                // 导致canal重启回滚时会出现ddl解析失败的问题
                // schemaObject.getStatement().output(data);
                SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(data, DbType.mysql);
                visitor.config(VisitorFeature.OutputNameQuote, true);
                schemaObject.getStatement().accept(visitor);

                data.append("; \n");
            }

View on GitHub (pinned to 87be50e876)

Solutions

  1. Use DatabaseTableMeta (the default TSDB implementation) which properly supports rollback by reconstructing memory state from snapshots and history.
  2. If using MemoryTableMeta directly, never call rollback() — instead recreate the instance from scratch.
  3. Ensure canal.instance.tsdb.snapshot.interval and related TSDB settings are configured to use DatabaseTableMeta.
  4. If this surfaces in production, check for a misconfigured TableMeta factory that returns MemoryTableMeta instead of DatabaseTableMeta.

Example fix

// before
MemoryTableMeta meta = new MemoryTableMeta();
meta.rollback(position); // throws

// after
DatabaseTableMeta meta = new DatabaseTableMeta();
meta.rollback(position); // supported, rebuilds from snapshot+history
Defensive patterns

Strategy: type-guard

Type guard

// Check if the TableMeta implementation supports rollback before calling it
if (tableMeta instanceof com.alibaba.otter.canal.parse.inbound.mysql.tsdb.DatabaseTableMeta) {
    tableMeta.rollback(position); // safe
} else if (tableMeta instanceof com.alibaba.otter.canal.parse.inbound.mysql.tsdb.MemoryTableMeta) {
    // rollback not supported — recreate instead
    tableMeta = new MemoryTableMeta();
} else {
    // check supportsRollback() or documentation for custom implementations
}

Prevention

When it happens

Trigger: Calling rollback() directly on a MemoryTableMeta instance. This should never happen in normal canal operation because DatabaseTableMeta wraps MemoryTableMeta and handles rollback itself by rebuilding memory state. It would fire if application code bypasses DatabaseTableMeta and calls rollback on the memory implementation directly.

Common situations: Custom code that obtains a reference to the inner MemoryTableMeta and calls rollback(); misconfigured TableMeta strategy that uses MemoryTableMeta where DatabaseTableMeta is expected; testing code that directly exercises MemoryTableMeta.rollback().

Related errors


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