risingwavelabs/risingwave · critical
implement MySQL CDC parallelized backfill
Error message
implement MySQL CDC parallelized backfill
What it means
split_snapshot_read on the MySQL external table reader is an unimplemented stub: it immediately panics with todo!. Parallelized (split-key based) CDC backfill for MySQL is not yet implemented, so calling this path aborts the stream task.
Source
Thrown at src/connector/src/source/cdc/external/mysql.rs:522
self.pool.disconnect().await.map_err(|e| e.into())
}
fn get_parallel_cdc_splits(
&self,
_options: CdcTableSnapshotSplitOption,
) -> BoxStream<'_, ConnectorResult<CdcTableSnapshotSplit>> {
// TODO(zw): feat: impl
stream::empty::<ConnectorResult<CdcTableSnapshotSplit>>().boxed()
}
fn split_snapshot_read(
&self,
_table_name: SchemaTableName,
_left: OwnedRow,
_right: OwnedRow,
_split_columns: Vec<Field>,
) -> BoxStream<'_, ConnectorResult<OwnedRow>> {
todo!("implement MySQL CDC parallelized backfill")
}
}
impl MySqlExternalTableReader {
/// Get MySQL version from the connection
async fn get_mysql_version(pool: &mysql_async::Pool) -> ConnectorResult<(u8, u8, bool)> {
let mut conn = pool.get_conn().await?;
let result: Option<String> = conn.query_first("SELECT VERSION()").await?;
if let Some(version_str) = result {
let parts: Vec<&str> = version_str.split('.').collect();
if parts.len() >= 2 {
let major_version = parts[0]
.parse::<u8>()
.context("Failed to parse major version")?;
let minor_version = parts[1]
.parse::<u8>()
.context("Failed to parse minor version")?;View on GitHub (pinned to 6469eb736d)
Solutions
- Do not configure parallel split-based backfill for MySQL CDC; use the default single-threaded snapshot path.
- Upgrade RisingWave to a version where MySQL parallel backfill is implemented.
- If you maintain the code, implement the method (range-query rows between _left and _right on _split_columns) or route to the non-split reader.
- File an issue / check the tracker for 'MySQL CDC parallelized backfill' progress.
Example fix
// before
fn split_snapshot_read(...) -> ... {
todo!("implement MySQL CDC parallelized backfill")
}
// after
fn split_snapshot_read(...) -> ... {
self.stream_snapshot_read(...) // fall back to non-parallel snapshot read
} Defensive patterns
Strategy: try-catch
Validate before calling
// Prefer the non-split snapshot path when using MySQL CDC:
let use_parallel_backfill = false; // MySQL parallelized backfill is unimplemented
if connector == "mysql-cdc" && use_parallel_backfill {
return Err("MySQL CDC does not support parallel split-based backfill".into());
} Try / catch
match reader.split_snapshot_read(table, left, right, cols).await.next().await {
Some(Err(e)) if e.to_string().contains("parallelized backfill") || e.to_string().contains("not implemented") => {
eprintln!("Falling back to sequential snapshot read");
reader.snapshot_read(table).await
}
other => other,
} Prevention
- Do not enable parallel split backfill for MySQL CDC sources.
- Use the default backfill configuration.
- Track RisingWave releases for MySQL parallel backfill support before opting in.
- Guard feature flags that route to split_snapshot_read for MySQL.
When it happens
Trigger: The backfill planner assigns a split-based parallel snapshot read for a MySQL CDC table, invoking MySqlExternalTableReader::split_snapshot_read with left/right split rows.
Common situations: Users enabling parallel/serialized split backfill options on MySQL CDC sources; developers exercising the external-table reader API directly in tests.
Related errors
- received a DDL message, please set `canal.instance.filter.qu
- no value found at column: {}, index: {}
- failed to deserialize MySQL value into rust value
- failed to deserialize MySQL value into rw value
- invalid value for boolean: {:?}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/e5ef79fa7cc99320.
Report an issue: GitHub.