ITADN

source/mysql 0.2.4 crashes (double-free / heap corruption) on every binlog row event with binlog_row_metadata=FULL

#602Opendanielgerlag 创建于 2026-06-25
D
danielgerlagcommented
### Summary The published **`source/mysql`** plugin (v0.2.4, the latest version compatible with `drasi-server` 0.2.0 / plugin-sdk 0.9.0) **crashes the entire server process with a native memory error on every binlog row event** when `binlog_row_metadata=FULL` is configured on the MySQL server. Because `FULL` metadata is *required* for the source to identify rows by key column name, and GTID is *required* by the source's `AUTO_POSITION` binlog streaming, there is no working configuration: the source either crashes (`FULL`) or cannot construct row identities (`MINIMAL`). This makes the MySQL source unusable for live change capture. ### Environment - `drasi-server` 0.2.0 (rustc 1.88.0, plugin-sdk 0.9.0) - Plugins (auto-installed from `ghcr.io/drasi-project`): `source/mysql` **0.2.4**, `bootstrap/mysql` 0.2.7 - MySQL server: `mysql:8.0` (Docker), `binlog-format=ROW`, `binlog-row-image=FULL`, `gtid-mode=ON`, `enforce-gtid-consistency=ON` - Reproduced on **both Windows (x86_64-pc-windows-msvc)** and **Linux (x86_64-unknown-linux-gnu)**. - Source deps (from `components/sources/mysql/Cargo.toml`): `mysql_async = "0.34"`, `mysql_common = "0.32"`. ### Steps to reproduce 1. Start MySQL 8.0 with ROW binlog, GTID on, and `binlog-row-metadata=FULL`. 2. Create a table with a non-`id` primary key, e.g.: ```sql CREATE TABLE vehicles ( plate VARCHAR(10) PRIMARY KEY, location VARCHAR(20) NOT NULL DEFAULT 'Parking' -- ...other columns ); ``` 3. Configure a `source/mysql` with `tables: [vehicles]` and `tableKeys: [{ table: vehicles, keyColumns: [plate] }]`, plus `bootstrap/mysql`. Bootstrap succeeds and loads the seed rows. 4. Make **any** change to the table (INSERT *or* UPDATE), e.g. `UPDATE vehicles SET location='Curbside' WHERE plate='A1234';`. ### Actual behavior The server process dies the instant the binlog row event is decoded: - **Linux:** `double free or corruption (fasttop)` (glibc abort). - **Windows:** exit code `0xC0000374` (`STATUS_HEAP_CORRUPTION`). This happens for both INSERT and UPDATE events. The crash is in the native plugin while parsing the FULL binlog row metadata (`components/sources/mysql/src/decoder.rs` `row_to_element` path, which reads `column.name_str()` from the `mysql_common` binlog `TableMapEvent`/`BinlogRow`). ### Why `MINIMAL` metadata is not a workaround With the MySQL 8.0 default `binlog_row_metadata=MINIMAL`, the binlog carries no column names, so `extract_column_names()` returns `col_0, col_1, ...`. The configured key column `plate` is never matched, and the decoder bails with: ``` Cannot construct a deterministic element ID for table 'vehicles': no key columns configured and no 'id' column found. Configure key_columns for this table. ``` …then enters an endless reconnect loop (no changes are ever delivered). So `FULL` is required for correct operation, but `FULL` is what crashes. ### Why GTID cannot be disabled Turning GTID off produces: ``` ERROR HY000 (1236): The replication sender thread cannot start in AUTO_POSITION mode: this server has GTID_MODE = OFF instead of ON. ``` So `gtid-mode=ON` is mandatory; it cannot be used to avoid the FULL-metadata code path. ### Expected behavior `source/mysql` should decode binlog row events with `binlog_row_metadata=FULL` without corrupting memory, and deliver INSERT/UPDATE/DELETE changes keyed by the configured `tableKeys`. ### Impact The MySQL source cannot be used for any live-CDC scenario (e.g. porting the Curbside Pickup tutorial, which joins a PostgreSQL source to a MySQL source). The PostgreSQL source works correctly in the same setup. ### Notes / smaller papercuts found alongside - `bootstrap/mysql` requires its **own** full connection config (`host`/`port`/`database`/`user`/`password`/`tables`/`tableKeys`); unlike `bootstrap/postgres`, it does not inherit the source's connection. With only `kind: mysql` it fails with `missing field 'database'`. - Both `source/mysql` and `bootstrap/mysql` reject database-qualified table names (`PhysicalOperations.vehicles`) with `contains invalid characters. Only letters, numbers, and underscores are allowed`; the unqualified `vehicles` must be used (the source is already scoped by the `database` field).
0 条评论