{"record":{"id":"0bf781b5402dd4fa","repo":"alibaba/canal","slug":"apply-to-memory-is-failed","errorCode":null,"errorMessage":"apply to memory is failed","messagePattern":"apply to memory is failed","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/tsdb/DatabaseTableMeta.java","lineNumber":293,"sourceCode":"        try {\n            return memoryTableMeta.find(schema, table);\n        } finally {\n            lock.readLock().unlock();\n        }\n    }\n\n    @Override\n    public boolean apply(EntryPosition position, String schema, String ddl, String extra) {\n        // 首先记录到内存结构\n        lock.writeLock().lock();\n        try {\n            if (memoryTableMeta.apply(position, schema, ddl, extra)) {\n                this.lastPosition = position;\n                this.hasNewDdl = true;\n                // 同步每次变更给远程做历史记录\n                return applyHistoryToDB(position, schema, ddl, extra);\n            } else {\n                throw new RuntimeException(\"apply to memory is failed\");\n            }\n        } finally {\n            lock.writeLock().unlock();\n        }\n    }\n\n    @Override\n    public boolean rollback(EntryPosition position) {\n        // 每次rollback需要重新构建一次memory data\n        // FIXME The global MemoryTableMeta may cause OOM when it store too many tables\n        this.memoryTableMeta = new MemoryTableMeta();\n        boolean flag = false;\n        EntryPosition snapshotPosition = buildMemFromSnapshot(position);\n        if (snapshotPosition != null) {\n            applyHistoryOnMemory(snapshotPosition, position);\n            flag = true;\n        }\n","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/tsdb/DatabaseTableMeta.java#L275-L311","documentation":"Thrown by DatabaseTableMeta.apply() when the underlying memoryTableMeta.apply() returns false, indicating the DDL could not be applied to the in-memory schema representation. This blocks further DDL history persistence since the memory state is inconsistent.","triggerScenarios":"memoryTableMeta.apply() returns false when the Druid DDL parser fails to parse or apply the DDL statement to the in-memory schema repository. This can happen with unsupported DDL syntax, DDL referencing non-existent objects, or parser bugs with complex statements.","commonSituations":"Unsupported MySQL DDL syntax (e.g., PARTITION, generated columns, spatial indexes); DDL for tables filtered out by canal configuration; Druid parser version incompatible with the MySQL version's DDL features; corrupt or truncated DDL text from binlog.","solutions":["Check the canal log for the specific DDL statement that caused memoryTableMeta.apply() to return false.","If the DDL uses unsupported syntax, add the table to the canal block filter (canal.instance.filter.black.regex).","Upgrade the Druid dependency to a version that supports the DDL syntax in use.","If the DDL is from a non-critical table, exclude it from DDL tracking."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    tableMeta.apply(position, schema, ddl, extra);\n} catch (RuntimeException e) {\n    if (e.getMessage().equals(\"apply to memory is failed\")) {\n        logger.warn(\"DDL could not be applied to memory, skipping: \" + ddl);\n        // optionally add table to blacklist filter\n    } else {\n        throw e;\n    }\n}","preventionTips":["Add tables with unsupported DDL syntax to the canal block filter regex.","Keep the Druid parser dependency up to date.","Test new DDL features against the canal version before deploying to production."],"tags":["tsdb","ddl","druid","memory-table-meta","canal-parse"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}