{"record":{"id":"329e127ecf954dd5","repo":"alibaba/canal","slug":"fetch-failed-by-table-meta","errorCode":null,"errorMessage":"fetch failed by table meta:{}","messagePattern":"fetch failed by table meta:(.+?)","errorType":"exception","errorClass":"CanalParseException","httpStatus":null,"severity":"error","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/TableMetaCache.java","lineNumber":213,"sourceCode":"                        ResultSetPacket packet = null;\n                        try {\n                            packet = connection.query(\"show create table \" + fullName);\n                        } catch (Exception e) {\n                            // 尝试做一次retry操作\n                            connection.reconnect();\n                            packet = connection.query(\"show create table \" + fullName);\n                        }\n\n                        String createDDL = null;\n                        if (packet.getFieldValues().size() > 0) {\n                            createDDL = packet.getFieldValues().get(1);\n                        }\n                        // 强制覆盖掉内存值\n                        tableMetaTSDB.apply(position, schema, createDDL, \"first\");\n                        tableMeta = tableMetaTSDB.find(schema, table);\n                    }\n                } catch (IOException e) {\n                    throw new CanalParseException(\"fetch failed by table meta:\" + fullName, e);\n                }\n            }\n            return tableMeta;\n        } else {\n            String fullName = getFullName(schema, table);\n            if (!useCache) {\n                // tableMetaCache.invalidate(getFullName(schema, table));\n                tableMetaCache.invalidate(fullName);\n            }\n            // return tableMetaCache.getUnchecked(getFullName(schema, table));\n            return tableMetaCache.getUnchecked(fullName);\n        }\n    }\n\n    public void clearTableMeta(String schema, String table) {\n        if (tableMetaTSDB != null) {\n            // tsdb不需要做,会基于ddl sql自动清理\n        } else {","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/TableMetaCache.java#L195-L231","documentation":"Thrown from the TSDB code path of TableMetaCache.getTableMeta() when an IOException occurs during the 'show create table' query that follows a TSDB cache miss. Unlike error 414 (which uses the Guava cache loader path), this is the explicit TSDB synchronization path: Canal found no tableMeta in TSDB, acquires a synchronized lock, retries the query after reconnect, and if that still fails, wraps the IOException in this CanalParseException.","triggerScenarios":"getTableMeta(schema, table, useCache, position) is called with tableMetaTSDB != null (TSDB enabled). tableMetaTSDB.find() returns null, so Canal enters the synchronized block and runs 'show create table'. If the first query throws, it reconnects and retries; if the retry throws IOException, this exception fires.","commonSituations":"TSDB is enabled but the MySQL connection dropped during metadata synchronization. The connection was closed by a server-side timeout between the TSDB lookup and the 'show create table' query. A failover occurred during TSDB initialization. The table was dropped between the binlog event and the TSDB sync attempt.","solutions":["Verify MySQL connectivity and connection pool health (the reconnect path suggests intermittent connection loss).","Increase the connection idle timeout / wait_timeout on MySQL to prevent premature disconnects.","Check if the table exists: run 'show create table schema.table' manually with the canal user.","If using a connection proxy, ensure it doesn't kill long-lived connections during metadata queries."],"exampleFix":"# before\n# (no connection timeout configuration)\n\n# after — configure connection persistence\ncanal.instance.master.jdbc.url=jdbc:mysql://host:3306?autoReconnect=true&connectTimeout=10000&socketTimeout=30000&tcpKeepAlive=true","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    TableMeta meta = tableMetaCache.getTableMeta(schema, table, useCache, position);\n} catch (CanalParseException e) {\n    if (e.getMessage().contains(\"fetch failed by table meta\")) {\n        // TSDB path failed — wait and retry with a fresh connection\n        Thread.sleep(5000L);\n        connection.reconnect();\n        // Retry once more\n        meta = tableMetaCache.getTableMeta(schema, table, false, position);\n    }\n}","preventionTips":["Use JDBC URL with tcpKeepAlive=true and autoReconnect=true to prevent silent connection drops.","Increase MySQL wait_timeout to exceed Canal's longest idle period between metadata queries.","Monitor connection pool health and alert on reconnect events."],"tags":["mysql","tsdb","table-meta","connection","synchronized"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}