{"record":{"id":"0eee198e6823445d","repo":"alibaba/canal","slug":"not-support-for-memory","errorCode":null,"errorMessage":"not support for memory","messagePattern":"not support for memory","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/tsdb/MemoryTableMeta.java","lineNumber":144,"sourceCode":"                        if (table != null) {\n                            tableMeta.setTable(table);\n                        }\n                        if (schema != null) {\n                            tableMeta.setSchema(schema);\n                        }\n\n                        tableMetas.put(keys, tableMeta);\n                    }\n                }\n            }\n        }\n\n        return tableMeta;\n    }\n\n    @Override\n    public boolean rollback(EntryPosition position) {\n        throw new RuntimeException(\"not support for memory\");\n    }\n\n    public Map<String, String> snapshot() {\n        Map<String, String> schemaDdls = new HashMap<>();\n        for (Schema schema : repository.getSchemas()) {\n            StringBuilder data = new StringBuilder(4 * 1024);\n            for (String table : schema.showTables()) {\n                SchemaObject schemaObject = schema.findTable(table);\n                // fixed issue #4899\n                // snapshot输出的DDL语句未正确处理mysql keyword\n                // 导致canal重启回滚时会出现ddl解析失败的问题\n                // schemaObject.getStatement().output(data);\n                SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(data, DbType.mysql);\n                visitor.config(VisitorFeature.OutputNameQuote, true);\n                schemaObject.getStatement().accept(visitor);\n\n                data.append(\"; \\n\");\n            }","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/tsdb/MemoryTableMeta.java#L126-L162","documentation":"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.","triggerScenarios":"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.","commonSituations":"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().","solutions":["Use DatabaseTableMeta (the default TSDB implementation) which properly supports rollback by reconstructing memory state from snapshots and history.","If using MemoryTableMeta directly, never call rollback() — instead recreate the instance from scratch.","Ensure canal.instance.tsdb.snapshot.interval and related TSDB settings are configured to use DatabaseTableMeta.","If this surfaces in production, check for a misconfigured TableMeta factory that returns MemoryTableMeta instead of DatabaseTableMeta."],"exampleFix":"// before\nMemoryTableMeta meta = new MemoryTableMeta();\nmeta.rollback(position); // throws\n\n// after\nDatabaseTableMeta meta = new DatabaseTableMeta();\nmeta.rollback(position); // supported, rebuilds from snapshot+history","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Check if the TableMeta implementation supports rollback before calling it\nif (tableMeta instanceof com.alibaba.otter.canal.parse.inbound.mysql.tsdb.DatabaseTableMeta) {\n    tableMeta.rollback(position); // safe\n} else if (tableMeta instanceof com.alibaba.otter.canal.parse.inbound.mysql.tsdb.MemoryTableMeta) {\n    // rollback not supported — recreate instead\n    tableMeta = new MemoryTableMeta();\n} else {\n    // check supportsRollback() or documentation for custom implementations\n}","tryCatchPattern":null,"preventionTips":["Always use DatabaseTableMeta as the TSDB implementation to get full rollback support.","Never call rollback() on a raw MemoryTableMeta instance.","Check the canal TSDB configuration to ensure DatabaseTableMeta is wired."],"tags":["tsdb","memory-table-meta","rollback","unsupported-operation","canal-parse"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}