-
Notifications
You must be signed in to change notification settings - Fork 117
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
Extraneous bytes in RotateEvent file name #189
Comments
Hi. Most likely a bug in the parser. Could you, please, attach the files? |
Here they are |
Well, it seems that this rotate event is FAKE_ROTATE_EVENT, i.e. it is not written into the binlog file. I believe the issue is the following: Client must read FORMAT_DESCRIPTION_EVENT (FDE) to be able to correctly handle event footer (i.e. to know that there should be (or should not be) a checksum), but FAKE_ROTATE_EVENT goes first and there is no way for a client to guess server configuration and to distinguish whether the footer is empty or it is not empty and contains a checksum. It seems that your server configured in a way that it adds checksums to binlog events, so this 4 additional bytes is most likely a checksum. I'm not sure how to correctly handle this. For now I suggest you to delay this event until FDE is received. Then you should be able to chop off a checksum if it's necessary (you can decide by looking at (fde.footer().get_checksum_alg()) |
Yeah, I’ve just checked and the server is configured with The Go I’ll try to use the FDE and report back, but probably only on Monday. |
This seems to have worked, though it seems weird to me because the stripped-off bytes don't match the result from use futures_util::StreamExt;
use mysql_async::{
binlog::events::{BinlogEventFooter, EventData},
BinlogRequest, Conn, OptsBuilder, Result,
};
#[tokio::main]
async fn main() -> Result<()> {
let opts = OptsBuilder::default()
.ip_or_hostname("localhost")
.tcp_port(3306)
.user(Some("user"))
.pass(Some("pass"));
let conn = Conn::new(opts).await?;
let req = BinlogRequest::new(1).with_pos::<u64>(4);
let mut stream = conn.get_binlog_stream(req).await?;
let mut name = "".to_owned();
while let Some(Ok(event)) = stream.next().await {
let data = event.read_data()?.unwrap();
match data {
EventData::RotateEvent(e) => {
println!("[-] rotate event");
if name.len() == 0 && event.header().timestamp() == 0 {
// first fake rotate event
name = if let Ok(Some(alg)) = event.fde().footer().get_checksum_alg() {
let cksum = event.calc_checksum(alg);
println!(" - checksum={:?}", u32::to_be_bytes(cksum));
let raw = e.name_raw();
let raw = &raw[..raw.len() - BinlogEventFooter::BINLOG_CHECKSUM_LEN];
String::from_utf8_lossy(raw).to_string()
} else {
e.name().to_string()
}
} else {
name = e.name().to_string();
}
println!(" - name={}", name);
println!(" - orig name={:?}", e.name_raw());
}
_ => {}
}
}
Ok(())
} Output:
|
Do you think this workaround makes sense? I'm not sure if the calculated checksums are really supposed to match with extra bytes after the file name. |
I've tried replacing MariaDB with MySQL, and in that setup the extra bytes do not appear, even with I've also noticed that the extra bytes only seem to appear in the first event yielded by the fn binlog_file_name(event: &RotateEvent, footer: &BinlogEventFooter, first: bool) -> String {
if !first {
return event.name().to_string();
}
if let Ok(Some(BinlogChecksumAlg::BINLOG_CHECKSUM_ALG_CRC32)) = footer.get_checksum_alg() {
let name = event.name_raw();
let name = &name[..name.len() - BinlogEventFooter::BINLOG_CHECKSUM_LEN];
return String::from_utf8_lossy(name).to_string();
}
event.name().to_string()
} |
MariaDB generates some artificial binlog events that should be skipped; check out https://mariadb.com/kb/en/fake-rotate_event/. This event, in particular, sometimes includes an invalid binlog filename. See blackbeam/mysql_async#189. I found that it's safe to just skip artificial events. MariaDB reports `longtext` as a `column_type` for JSON columns. I've added a special check to distinguish MariaDB JSON columns from text columns.
MariaDB generates some artificial binlog events that should be skipped; check out https://mariadb.com/kb/en/fake-rotate_event/. This event, in particular, sometimes includes an invalid binlog filename. See blackbeam/mysql_async#189. I found that it's safe to just skip artificial events. MariaDB reports `longtext` as a `column_type` for JSON columns. I've added a special check to distinguish MariaDB JSON columns from text columns.
MariaDB generates some artificial binlog events that should be skipped; check out https://mariadb.com/kb/en/fake-rotate_event/. This event, in particular, sometimes includes an invalid binlog filename. See blackbeam/mysql_async#189. I found that it's safe to just skip artificial events. MariaDB reports `longtext` as a `column_type` for JSON columns. I've added a special check to distinguish MariaDB JSON columns from text columns.
* test: unittests for the MySQL connector Increase the coverage of the MySQL connector implementation above 90% with a combination of unittests and integration tests. * fix: mariadb MariaDB generates some artificial binlog events that should be skipped; check out https://mariadb.com/kb/en/fake-rotate_event/. This event, in particular, sometimes includes an invalid binlog filename. See blackbeam/mysql_async#189. I found that it's safe to just skip artificial events. MariaDB reports `longtext` as a `column_type` for JSON columns. I've added a special check to distinguish MariaDB JSON columns from text columns. * test: mariadb Perform integration tests on both MySQL and MariaDB.
Hello
I'm using mysql_async to write a program that tails the MariaDB binlog. I'm using MariaDB 10.5.15. The server is configured with the following binlog-related settings:
The following binlogs are available:
When running the program below, I'm seeing extraneous characters in the result of the
name()
andname_raw()
methods in theRotateEvent
struct:The program output is as follows:
Notice that in the first event, there are 4 extra bytes after the ones corresponding to
mariadb-bin.000001
,82, 60, 115, 84
, which I've found to be unexpected.If I change the
BinlogRequest
as follows (pointing it to the end of the last binlog file):then I get extra bytes in the name of that file:
Do you know what could be causing this?
The text was updated successfully, but these errors were encountered: