Skip to content

feat(connectors): add MySQL source polling connector#3568

Open
tusharagrahari wants to merge 7 commits into
apache:masterfrom
tusharagrahari:feature/mysql-source-polling
Open

feat(connectors): add MySQL source polling connector#3568
tusharagrahari wants to merge 7 commits into
apache:masterfrom
tusharagrahari:feature/mysql-source-polling

Conversation

@tusharagrahari

Copy link
Copy Markdown

Which issue does this PR address?

Relates to #3445

Rationale

MySQL is a widely used relational database with no existing Iggy source connector. This adds incremental table polling so users can stream MySQL rows into Iggy topics without CDC infrastructure.

What changed?

Before this PR, there was no way to source data from MySQL into Iggy.

This adds a mysql_source connector plugin supporting incremental table polling via a configurable tracking column. Rows are streamed as JSON, raw bytes, or text depending on the configured payload format. Post-processing options (delete after read, mark as processed) and custom SQL queries with parameter substitution are also supported. CDC (binlog-based) is out of scope and planned as a follow-up.

Local Execution

  • Passed
  • Pre-commit hooks ran

AI Usage

  1. Tools: Claude (Claude Code)
  2. Scope: Writing unit and integration tests, thinking through edge cases, and pair-programming during development.
  3. Verification: Ran all tests locally against a real MySQL container, validated end-to-end polling flow, and ran the full pre-commit hook suite.
  4. Yes, I can explain every line of code if asked.

@github-actions

Copy link
Copy Markdown

Thanks for the PR. It is labeled S-waiting-on-review and queued for review.

Slash commands (own line, regular comment) move it around the queue:

  • /ready - back to S-waiting-on-review after addressing feedback
  • /author - flip to S-waiting-on-author while you finish changes
  • /request-review @user-or-team - request a reviewer

See CONTRIBUTING.md for details.

@github-actions github-actions Bot added the S-waiting-on-review PR is waiting on a reviewer label Jun 25, 2026
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.88424% with 225 lines in your changes missing coverage. Please review.
✅ Project coverage is 41.85%. Comparing base (925706d) to head (7f4ffbe).
⚠️ Report is 20 commits behind head on master.

Files with missing lines Patch % Lines
core/connectors/sources/mysql_source/src/lib.rs 75.88% 182 Missing and 43 partials ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             master    #3568       +/-   ##
=============================================
- Coverage     73.47%   41.85%   -31.63%     
  Complexity      937      937               
=============================================
  Files          1286     1284        -2     
  Lines        141300   123445    -17855     
  Branches     117133    99321    -17812     
=============================================
- Hits         103827    51670    -52157     
- Misses        34229    68975    +34746     
+ Partials       3244     2800      -444     
Components Coverage Δ
Rust Core 34.05% <75.88%> (-39.64%) ⬇️
Java SDK 62.44% <ø> (ø)
C# SDK 71.40% <ø> (-0.71%) ⬇️
Python SDK 92.17% <ø> (ø)
PHP SDK 84.29% <ø> (ø)
Node SDK 91.35% <ø> (ø)
Go SDK 42.28% <ø> (ø)
Files with missing lines Coverage Δ
core/connectors/sources/mysql_source/src/lib.rs 75.88% <75.88%> (ø)

... and 414 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@atharvalade atharvalade left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @tusharagrahari, thanks for the contribution and for taking the time to put this together.

A couple of process things before we dig into review:

  1. Issue approval: I can see you created #3445 yourself, which is great. However, per our CONTRIBUTING.md, new functionality needs maintainer approval on the issue before coding begins (a good-first-issue label or an explicit comment). Connectors are also listed as a high-risk area that needs a design discussion in the issue first. We typically ask first-time contributors to start with something labeled good-first-issue to get familiar with the repo's workflow and CI, then move on to bigger features like this.

  2. Failing CI: Could you take a look and get those green?

Not saying this won't get merged, the implementation looks good to start with. Just want to make sure we follow the process so there are no surprises down the line.

Comment thread core/connectors/sources/mysql_source/src/lib.rs Outdated
Comment thread core/connectors/sources/mysql_source/src/lib.rs Outdated
Comment thread core/connectors/sources/mysql_source/src/lib.rs Outdated
Comment thread core/connectors/sources/mysql_source/src/lib.rs
@github-actions github-actions Bot added S-waiting-on-author PR is waiting on author response and removed S-waiting-on-review PR is waiting on a reviewer labels Jun 25, 2026
Comment thread .gitignore Outdated
@tusharagrahari

Copy link
Copy Markdown
Author

Hi @atharvalade, thanks for the detailed feedback!

On the process side — I did reach out on the Discord community before starting, where I got clearance to proceed with the connector work. I understand that might not substitute for a formal maintainer approval comment on the issue itself, and I'll make sure to get that explicitly documented going forward before picking up anything in high-risk areas.

On the CI failures — on it, will get those green shortly.

Also working through the inline review comments now. Will push the fixes once the CI is sorted.

@tusharagrahari
tusharagrahari force-pushed the feature/mysql-source-polling branch from 1c4d3d9 to dd4ea5c Compare June 28, 2026 14:14
@tusharagrahari

Copy link
Copy Markdown
Author

/ready

@github-actions github-actions Bot added S-waiting-on-review PR is waiting on a reviewer and removed S-waiting-on-author PR is waiting on author response labels Jun 28, 2026

@hubcio hubcio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a couple of notes that don't anchor to the diff:

  • core/connectors/sources/README.md source table doesn't list mysql_source yet - worth adding a row.
  • the two delivery-semantics comments below (delete/mark before send, offset advance on send failure) share one root cause - there is no send ack from the runtime back to the connector - and postgres_source behaves the same way. the sink side of the exact same gap is already tracked in #2927 (consume() return value discarded) and #2928 (offsets committed before sink processing), and #2940 discusses the broader replay-safe progress contract. the source side deserves a sibling issue rather than a fix in this PR.

Comment thread core/connectors/sources/mysql_source/src/lib.rs
Comment thread core/connectors/sources/mysql_source/src/lib.rs Outdated
Comment thread core/connectors/sources/mysql_source/src/lib.rs
Comment thread core/connectors/sources/mysql_source/src/lib.rs
Comment thread core/connectors/sources/mysql_source/src/lib.rs Outdated
Comment thread core/connectors/sources/mysql_source/src/lib.rs Outdated
Comment thread core/connectors/sources/mysql_source/src/lib.rs Outdated
Comment thread core/connectors/sources/mysql_source/README.md Outdated
Comment thread core/connectors/sources/mysql_source/Cargo.toml Outdated
Comment thread core/integration/tests/connectors/mysql/mod.rs
@github-actions github-actions Bot added S-waiting-on-author PR is waiting on author response and removed S-waiting-on-review PR is waiting on a reviewer labels Jul 1, 2026
Comment thread core/connectors/sources/mysql_source/src/lib.rs
Comment thread core/connectors/sources/mysql_source/src/lib.rs
Comment thread core/connectors/sources/mysql_source/src/lib.rs
Comment thread core/connectors/sources/mysql_source/src/lib.rs Outdated
Comment thread core/connectors/sources/mysql_source/src/lib.rs
@ryerraguntla

Copy link
Copy Markdown
Contributor

@tusharagrahari - Overall looks good. Outside of the mysql source connector, two places needs to be updated for the newer connectors..

  1. core/connectors/sources/README.md:9-14 — mysql_source missing from Available Sources table. Fix: add row.
  2. .github/workflows/_build_rust_artifacts.yml:49 — iggy_connector_mysql_source absent from connector_plugins default list; edge releases ship no prebuilt .so. Postgres listed. Fix: register crate. (

@ryerraguntla

Copy link
Copy Markdown
Contributor

/author

@tusharagrahari

Copy link
Copy Markdown
Author

Opened #3635 as the sibling issue for the missing runtime→source send ack, cross-linked with #2927/#2928/#2940. Left the current behavior in this PR as-is. @ryerraguntla @hubcio

@tusharagrahari
tusharagrahari force-pushed the feature/mysql-source-polling branch from 6591d6b to 631cc2e Compare July 10, 2026 21:32
@tusharagrahari

Copy link
Copy Markdown
Author

/ready

@github-actions github-actions Bot added S-waiting-on-review PR is waiting on a reviewer and removed S-waiting-on-author PR is waiting on author response labels Jul 10, 2026

### Delivery semantics

Both `delete_after_read` and `processed_column` mutate MySQL during the poll, before the batch is actually sent to Iggy. If the connector crashes or the send fails in that window, those rows are gone or marked processed anyway — they won't be retried. So both options are at-most-once, not at-least-once.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those rows are gone or marked processed anyway - will it be deleted (gone) or marked? It should be either one in each pass, could this be confirmed and update the documentation

| ------ | ----------- | ------ | ----------- |
| `bytea` / `raw` | `BLOB`, `BINARY`, `VARBINARY` | `raw` | Raw bytes passthrough |
| `text` | `TEXT`, `VARCHAR` | `text` | UTF-8 text |
| `json_direct` / `jsonb` | `JSON` | `json` | JSON object serialized to bytes |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lib.rs:110-116 — README lists jsonbalias; code only acceptsjson_direct. Fix: add jsonb to from_config or drop from README.

Some(self.extract_payload_column(row, i, config.payload_format)?);
}
if name == config.tracking_column || name == config.pk_column {
let as_string = value_as_string(&extract_column_value(row, i)?);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value_as_string only String|Number; BOOL/NULL/JSON tracking/PK ⇒ no offset/PK for mark. Fix: canonical scalar encoding or open-time schema probe.

let quoted_table = quote_qualified_identifier(table)?;
let quoted_pk = quote_identifier(pk_column)?;

let ids_list = ids

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BINARY PK base64 in JSON path; IN clause uses quoted string literal ⇒ mark/delete miss. Fix: hex/binary bind or typed PK encoder.

|| self.config.processed_column.is_some();

for mut batch in batches {
if mark_or_delete && !batch.messages.is_empty() && batch.processed_ids.is_empty() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mark/delete configured but empty processed_ids: warn then still emit + advance offset. Fix: fail batch when mark configured without scalar PK.

.unwrap_or_default();
let offset = format_offset_value(&offset_value);
let now = Utc::now();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lib.rs:399 vs lib.rs:424 - custom_query $table unquoted; built-in path quotes. Fix: quote_qualified_identifier on $table (postgres same pattern).

) -> Result<String, Error> {
let quoted_table = quote_qualified_identifier(table)?;
let quoted_tracking = quote_identifier(tracking_column)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

748-791,427 — hot path: per-row serde_json Map + SELECT *. Fix: column projection + direct serialize (v1 acceptable, matches postgres shape).

[dependencies]
async-trait = { workspace = true }
base64 = { workspace = true }
chrono = { workspace = true }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dashmap dep unused in lib.rs. Validate and Fix: remove dep + machete ignore.

@ryerraguntla

Copy link
Copy Markdown
Contributor

No major issues. Most of them are suggestions/documentation. Should be good to merge in the next iteration

@ryerraguntla

Copy link
Copy Markdown
Contributor

/author

@github-actions github-actions Bot added S-waiting-on-author PR is waiting on author response and removed S-waiting-on-review PR is waiting on a reviewer labels Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author PR is waiting on author response

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants