alibaba/canal · error · CanalParseException

fetch failed by table meta

Error message

fetch failed by table meta:{}

What it means

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.

Solutions

  1. Verify MySQL connectivity and connection pool health (the reconnect path suggests intermittent connection loss).
  2. Increase the connection idle timeout / wait_timeout on MySQL to prevent premature disconnects.
  3. Check if the table exists: run 'show create table schema.table' manually with the canal user.
  4. If using a connection proxy, ensure it doesn't kill long-lived connections during metadata queries.

Example fix

# before
# (no connection timeout configuration)

# after — configure connection persistence
canal.instance.master.jdbc.url=jdbc:mysql://host:3306?autoReconnect=true&connectTimeout=10000&socketTimeout=30000&tcpKeepAlive=true
Defensive patterns

Strategy: retry

Try / catch

try {
    TableMeta meta = tableMetaCache.getTableMeta(schema, table, useCache, position);
} catch (CanalParseException e) {
    if (e.getMessage().contains("fetch failed by table meta")) {
        // TSDB path failed — wait and retry with a fresh connection
        Thread.sleep(5000L);
        connection.reconnect();
        // Retry once more
        meta = tableMetaCache.getTableMeta(schema, table, false, position);
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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

Appendix: source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/dbsync/TableMetaCache.java:213

                        ResultSetPacket packet = null;
                        try {
                            packet = connection.query("show create table " + fullName);
                        } catch (Exception e) {
                            // 尝试做一次retry操作
                            connection.reconnect();
                            packet = connection.query("show create table " + fullName);
                        }

                        String createDDL = null;
                        if (packet.getFieldValues().size() > 0) {
                            createDDL = packet.getFieldValues().get(1);
                        }
                        // 强制覆盖掉内存值
                        tableMetaTSDB.apply(position, schema, createDDL, "first");
                        tableMeta = tableMetaTSDB.find(schema, table);
                    }
                } catch (IOException e) {
                    throw new CanalParseException("fetch failed by table meta:" + fullName, e);
                }
            }
            return tableMeta;
        } else {
            String fullName = getFullName(schema, table);
            if (!useCache) {
                // tableMetaCache.invalidate(getFullName(schema, table));
                tableMetaCache.invalidate(fullName);
            }
            // return tableMetaCache.getUnchecked(getFullName(schema, table));
            return tableMetaCache.getUnchecked(fullName);
        }
    }

    public void clearTableMeta(String schema, String table) {
        if (tableMetaTSDB != null) {
            // tsdb不需要做,会基于ddl sql自动清理
        } else {

View on GitHub (pinned to 87be50e876)