[
https://issues.apache.org/jira/browse/FLINK-41272?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18134284#comment-18134284
]
Seungki Kim edited comment on FLINK-41272 at 10/29/26, 3:59 PM:
----------------------------------------------------------------
We(me and my team) ran into this in our production MySQL CDC pipeline, where
binlog events were silently turning NULLs into column defaults. As a
workaround, I've been running a custom DebeziumDeserializationSchema in
production that converts the "before"/"after" images with a copy of the schema
whose field defaults are removed, reading values via Struct#getWithoutDefault.
This keeps NULL as null without upgrading the bundled Kafka Connect.
I'd like to share this approach and contribute it upstream, e.g. as an option
equivalent to `replace.null.with.default`. (default true, so existing behavior
is unchanged)
I'm also open to other approaches, such as upgrading Kafka Connect, if you
think there's a better way.
Once we agree on the approach, could a committer assign this issue to me?
was (Author: JIRAUSER314455):
I ran into this in our production MySQL CDC pipeline, where binlog events were
silently turning NULLs into column defaults. As a workaround, we've been
running a custom DebeziumDeserializationSchema in production that converts the
"before"/"after" images with a copy of the schema whose field defaults are
removed, reading values via Struct#getWithoutDefault. This keeps NULL as null
without upgrading the bundled Kafka Connect.
I'd like to share this approach and contribute it upstream, e.g. as an option
equivalent to `replace.null.with.default`. (default true, so existing behavior
is unchanged)
I'm also open to other approaches, such as upgrading Kafka Connect, if you
think there's a better way.
Once we agree on the approach, could a committer assign this issue to me?
> [mysql-cdc] NULL values of nullable columns with a DEFAULT are emitted as the
> default value in Debezium JSON
> ------------------------------------------------------------------------------------------------------------
>
> Key: FLINK-41272
> URL: https://issues.apache.org/jira/browse/FLINK-41272
> Project: Flink
> Issue Type: Bug
> Components: Flink CDC
> Affects Versions: cdc-3.6.0
> Environment: * flink-sql-connector-mysql-cdc 3.6.0-2.2 (Debezium
> 1.9.8.Final, bundled Kafka Connect 3.2.0, shaded)
> * MySQL 8.0 (Aurora MySQL 3)
> * JsonConverter configured with schemas.enable=false
> Reporter: Seungki Kim
> Priority: Major
>
> *Problem*
> For a MySQL column that is nullable and has a DEFAULT (e.g. `count INT NULL
> DEFAULT 0`),
> a row whose stored value is NULL is emitted as the column default (0) instead
> of null
> when change events are converted to JSON with
> JsonDebeziumDeserializationSchema
> (or the shaded Kafka Connect JsonConverter directly).
> Snapshot reads of the same rows from the database return NULL, so the binlog
> output
> silently diverges from the source.
> This was previously reported on GitHub (ververica/flink-cdc-connectors#516)
> and closed
> because it predated 2.3.0. It still reproduces on 3.6.0.
>
> *Steps to reproduce*
> {code:java}
> CREATE TABLE t (id BIGINT PRIMARY KEY, cnt INT NULL DEFAULT 0, note
> VARCHAR(10));
> INSERT INTO t (id, cnt, note) VALUES (1, NULL, 'a');
> UPDATE t SET note = 'b' WHERE id = 1;{code}
> Expected "after": \{"id":1,"cnt":null,"note":"b"}
> Actual "after": \{"id":1,"cnt":0,"note":"b"}
>
>
> *Root cause*
> Debezium copies the column DEFAULT into the Connect field schema
> (defaultValue).
> Kafka Connect's JsonConverter writes schema.defaultValue() whenever the field
> value is null.
> KIP-581 added `replace.null.with.default` (Kafka 3.5) to disable this, but
> the Kafka Connect
> version shaded into flink-sql-connector-mysql-cdc is 3.2.0, so
> JsonConverterConfig only
> supports schemas.enable, schemas.cache.size and decimal.format. Passing
> replace.null.with.default via customConverterConfigs is silently ignored.
> Because the classes are relocated, users cannot swap in a newer connect-json
> either.
>
> *Impact*
> Every nullable column with a non-null DEFAULT is affected. Downstream tables
> built from the
> binlog get default values where the source has NULL. In our case this
> affected 87 columns
> across 11 tables, including DATETIME columns defaulting to '1970-01-01
> 00:00:00'.
>
> *Possible fixes*
> Expose an equivalent of Kafka's `replace.null.with.default` (KIP-581) in
> Flink CDC,
> e.g. as a JsonDebeziumDeserializationSchema / connector option, defaulting to
> true so that
> existing output does not change. Setting it to false would keep NULL as null.
> It could be implemented either by:
> # Bundling Kafka Connect >= 3.5 and passing the option through to
> JsonConverter, or
> # Without a Kafka upgrade, converting the row images ("before"/"after") with
> a schema copy whose field defaults are removed, reading values via
> Struct#getWithoutDefault.
>
> *Workaround*
> A custom DebeziumDeserializationSchema that rebuilds the before/after schemas
> without
> defaults and copies values with Struct#getWithoutDefault before calling
> JsonConverter.
> {code}
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)