-
Notifications
You must be signed in to change notification settings - Fork 511
MySQL Source Versioning V2 - reorganized boogaloo #36333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b1d06b8
139ba39
6080b0b
bbce9d4
725768c
fd56192
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| // by the Apache License, Version 2.0. | ||
|
|
||
| use maplit::btreemap; | ||
| use mysql_async::binlog::events::OptionalMetaExtractor; | ||
| use mysql_common::binlog::events::{QueryEvent, RowsEventData}; | ||
| use mz_mysql_util::{MySqlError, pack_mysql_row}; | ||
| use mz_ore::iter::IteratorExt; | ||
|
|
@@ -221,7 +222,7 @@ pub(super) async fn handle_query_event( | |
| /// frontier with which to advance the dataflow's progress. | ||
| pub(super) async fn handle_rows_event( | ||
| event: RowsEventData<'_>, | ||
| ctx: &ReplContext<'_>, | ||
| ctx: &mut ReplContext<'_>, | ||
| new_gtid: &GtidPartition, | ||
| event_buffer: &mut Vec<( | ||
| (usize, Result<SourceMessage, DataflowError>), | ||
|
|
@@ -262,6 +263,11 @@ pub(super) async fn handle_rows_event( | |
| // Capability for this event. | ||
| let gtid_cap = ctx.data_cap_set.delayed(new_gtid); | ||
|
|
||
| // We can check here if the binlog has full row metadata by looking at the column name optional | ||
| // metadata, which is only present if full metadata is enabled. | ||
| let optional_metadata = OptionalMetaExtractor::new(table_map_event.iter_optional_meta())?; | ||
| let has_full_metadata = optional_metadata.iter_column_name().next().is_some(); | ||
|
|
||
| // Iterate over the rows in this RowsEvent. Each row is a pair of 'before_row', 'after_row', | ||
| // to accomodate for updates and deletes (which include a before_row), | ||
| // and updates and inserts (which inclued an after row). | ||
|
|
@@ -289,20 +295,37 @@ pub(super) async fn handle_rows_event( | |
| before_row.map(|r| (r, Diff::MINUS_ONE)), | ||
| after_row.map(|r| (r, Diff::ONE)), | ||
| ]; | ||
| let gtid_str = format!("{new_gtid:?}"); | ||
| for (binlog_row, diff) in updates.into_iter().flatten() { | ||
| let row = mysql_async::Row::try_from(binlog_row)?; | ||
| for (output, row_val) in outputs.iter().repeat_clone(row) { | ||
| let event = match pack_mysql_row(&mut final_row, row_val, &output.desc) { | ||
| Ok(row) => Ok(SourceMessage { | ||
| key: Row::default(), | ||
| value: row, | ||
| metadata: Row::default(), | ||
| }), | ||
| // Produce a DefiniteError in the stream for any rows that fail to decode | ||
| Err(err @ MySqlError::ValueDecodeError { .. }) => Err(DataflowError::from( | ||
| DefiniteError::ValueDecodeError(err.to_string()), | ||
| )), | ||
| Err(err) => Err(err)?, | ||
| let event = if !has_full_metadata && output.binlog_full_metadata { | ||
| ctx.errored_outputs.insert(output.output_index); | ||
| Err(DataflowError::from(DefiniteError::ValueDecodeError( | ||
| format!( | ||
| "Table {0} was created with binlog_row_metadata=FULL but binlog_row_metadata has since been set to a different value, meaning we cannot reliably decode the columns", | ||
| output.table_name | ||
| ), | ||
|
Comment on lines
+304
to
+308
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We never mark the export(s) as borked ( Consider we have source will full metadata, a row with a value A that sees some updates and is deleted, and interleaved someone accidentally changes row metadata:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like something that is fundamentally unrecoverable, no? You mean that by adding it to
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, by adding it - we stop processing events for it. The last thing appended would be the error. I believe we do this for the MySQL DDL errors, and you should also find it in PG. |
||
| ))) | ||
| } else { | ||
| match pack_mysql_row( | ||
| &mut final_row, | ||
| row_val, | ||
| &output.desc, | ||
| Some(>id_str), | ||
| output.binlog_full_metadata, | ||
| ) { | ||
| Ok(row) => Ok(SourceMessage { | ||
| key: Row::default(), | ||
| value: row, | ||
| metadata: Row::default(), | ||
| }), | ||
| // Produce a DefiniteError in the stream for any rows that fail to decode | ||
| Err(err @ MySqlError::ValueDecodeError { .. }) => Err(DataflowError::from( | ||
| DefiniteError::ValueDecodeError(err.to_string()), | ||
| )), | ||
| Err(err) => Err(err)?, | ||
| } | ||
| }; | ||
|
|
||
| let data = (output.output_index, event); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.