risingwavelabs/risingwave · error

`SHOW BINARY LOGS`: missing `Log_name` column

Error message

`SHOW BINARY LOGS`: missing `Log_name` column

What it means

After running `SHOW BINARY LOGS`, the enumerator decodes each row positionally: column 0 must be the log file name (`Log_name`). If take_opt::<String> returns Ok(None), MySQL returned a row without a value in that column, which is not a valid result for this statement, so the code fails with this anyhow error.

Solutions

  1. Connect directly to the MySQL primary instead of through a proxy for the CDC source.
  2. Verify with an mysql client that `SHOW BINARY LOGS` returns non-NULL Log_name values using the same account.
  3. Check MySQL version/variant compatibility; use a standard MySQL 5.7/8.0 server.
  4. Grant the account REPLICATION CLIENT/SLAVE privileges so the statement returns full rows.

Example fix

// before (via proxy) hostname = 'vitess-proxy:15306'
// after
WITH (connector = 'mysql-cdc', hostname = 'mysql-primary.internal', port = '3306', ...)
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: verify the server returns a proper result set
let rows: Vec<(String, u64)> = sqlx::query_as(
    "SHOW BINARY LOGS"
).fetch_all(&pool).await?;
assert!(!rows.is_empty() && rows.iter().all(|(n, _)| !n.is_empty()));

Try / catch

match monitor_res {
    Err(e) if e.to_string().contains("missing `Log_name`") => {
        log::warn!("MySQL returned malformed SHOW BINARY LOGS output; check for proxy/non-standard server");
        // back off and alert instead of hot-looping
    }
    r => r?,
}

Prevention

When it happens

Trigger: `SHOW BINARY LOGS` on the target MySQL server returns rows whose first column is NULL or absent — e.g. a non-standard proxy/sharding layer rewriting the result set, or a server build with an altered column layout.

Common situations: Connecting through a MySQL-compatible proxy (Vitess, ProxySQL, TiDB variants) that reshapes `SHOW BINARY LOGS` output, or insufficient privileges causing a degenerate result set.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/f1c7ca0377c49b7d. Report an issue: GitHub.

Appendix: source

Thrown at src/connector/src/source/cdc/enumerator/mod.rs:548

            .await
            .context("failed to connect to MySQL")?;

        // Query binlog files using SHOW BINARY LOGS.
        // MySQL 8.0+ may return 3 columns (Log_name, File_size, Encrypted), while some variants
        // only return the first 2. Decode the row manually so we don't panic on column-count
        // differences.
        let rows: Vec<Row> = conn
            .query("SHOW BINARY LOGS")
            .await
            .context("failed to execute `SHOW BINARY LOGS`")?;
        let query_result = rows
            .into_iter()
            .map(|mut row| -> ConnectorResult<(String, u64)> {
                let log_name = row
                    .take_opt::<String, _>(0)
                    .transpose()
                    .context("`SHOW BINARY LOGS`: failed to decode `Log_name`")?
                    .ok_or_else(|| anyhow!("`SHOW BINARY LOGS`: missing `Log_name` column"))?;
                let file_size = row
                    .take_opt::<u64, _>(1)
                    .transpose()
                    .context("`SHOW BINARY LOGS`: failed to decode `File_size`")?
                    .ok_or_else(|| anyhow!("`SHOW BINARY LOGS`: missing `File_size` column"))?;
                Ok((log_name, file_size))
            })
            .collect::<ConnectorResult<Vec<_>>>()?;

        drop(conn);
        pool.disconnect().await.ok();

        Ok(query_result)
    }
}

impl ListCdcSplits for DebeziumSplitEnumerator<Mysql> {
    type CdcSourceType = Mysql;

View on GitHub (pinned to 6469eb736d)