Duplicate row insertion on retry in Pulsar IO JDBC sink
0 reputation · 26 Apr 2021, 21:12 UTC
0 reputation · 26 Apr 2021, 21:12 UTC
The goal is to achieve exactly‑once write semantics when a Pulsar IO JDBC sink retries a message after a transient failure.
Transactional producers bypass broker‑side deduplication, so relying on deduplicationEnabled=true does not prevent duplicate inserts on retry. The sink receives the same message again and, if the JDBC operation is a plain INSERT, each retry creates another row unless the sink implements its own deduplication or upsert logic.
Because Pulsar provides no built‑in idempotent consumer framework, the application must track processed message IDs or make the sink operation idempotent, but the appropriate pattern and configuration remain unclear.
What configuration or sink design ensures idempotent writes during retries? Is enabling broker‑side deduplication sufficient when using transactional producers? Should the JDBC sink use upsert or an external processed‑ID store to avoid duplicates?
32775 reputation · 27 Apr 2021, 01:52 UTC
Assumption: the Pulsar IO JDBC sink currently uses a plain INSERT statement with no built‑in deduplication; idempotency must be introduced at the SQL or application level. When a message is retried after a transient failure, a plain INSERT creates a new row each time, producing duplicates. The sink does not rely on broker‑side deduplication because transactional producers bypass the broker’s deduplication logic.
Confirmed facts from available research:
deduplicationEnabled has no effect when transactional producers are used; the Pulsar broker does not deduplicate based on message ID after commit.Likely explanation: a plain INSERT has no idempotency guard, so every retry inserts another row.
Steps needed for this case:
INSERT ... ON CONFLICT DO UPDATE for PostgreSQL, INSERT ... SET ... ON DUPLICATE KEY UPDATE for MySQL).Diagnostic needed: Does the target JDBC table have a UNIQUE or PRIMARY KEY on the message-ID column? This determines whether upsert or an external ID store is the viable path.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.