Missing Delete Events (op: d) after upgrading Oracle Connector from 3.0.0 to 3.3.1

20 views
Skip to first unread message

hyojin lee

unread,
Feb 3, 2026, 10:54:47 PMFeb 3
to debezium

Hi, debezium. 


I recently upgraded my Debezium Oracle source connector from version 3.0.0 to 3.3.1. In the previous version, whenever a DELETE operation occurred in the Oracle database, two messages were produced to the Kafka topic as expected:

  1. A record with op: d (due to ExtractNewRecordState SMT with rewrite mode).

  2. A Tombstone record (null value).

However, after upgrading to 3.3.1, the record with op: d is no longer being produced, and only the tombstone record (or nothing at all) appears.

Configuration Changes

I have maintained almost the same configuration, but noticed a few behavior changes in the new version. My SMT settings for unwrap are as follows:

"transforms": "unwrap",
"transforms.unwrap.type": "io.debezium.transforms.ExtractNewRecordState",
"transforms.unwrap.drop.tombstones": "false",
"transforms.unwrap.delete.handling.mode": "rewrite",
"transforms.unwrap.add.fields": "op,source.ts_ms",
"tombstones.on.delete": "true"

Key Observations & Questions

  1. Change in log.mining.strategy: I changed the strategy from online_catalog to hybrid. Could this impact how LogMiner captures or formats delete operations?

  2. SMT Behavior in 3.x: Has there been a breaking change in ExtractNewRecordState (unwrap) between 3.0.0 and 3.3.1 regarding how delete.handling.mode: rewrite interacts with tombstones.on.delete: true?

  3. Missing Record: Even though drop.tombstones is set to false, the actual delete event containing the before state (mapped to the fields via rewrite) is missing from the topic.

Comparison of Configurations

  • Version 3.0.0: Used online_catalog, snapshot.mode: schema_only, and log.mining.continuous.mine: false. (Delete events worked fine).

  • Version 3.3.1: Using hybrid, snapshot.mode: no_data, and log.mining.continuous.mine: true.

Why are the op: d events no longer appearing in the Kafka topic after the upgrade?



topic KEY

{
"schema": {
"type": "struct",
"fields": [
{
"type": "string",
"optional": false,
"field": "COMPANY_CD"
},
{
"type": "string",
"optional": false,
"field": "PC_CD"
},
{
"type": "string",
"optional": false,
"field": "DOCU_NO"
}
],
"optional": false,
"name": "dev-erp10.COMET.FI_DOCU_MST.Key"
},
"payload": {
"COMPANY_CD": "TEST",
"PC_CD": "TEST",
"DOCU_NO": "FI202306010002"
}
}


 topic value

{
"schema": {
"type": "struct",
"fields": [
{
"type": "string",
"optional": false,
"field": "COMPANY_CD"
},
{
"type": "string",
"optional": false,
"field": "PC_CD"
},
{
"type": "string",
"optional": false,
"field": "DOCU_NO"
},
{
"type": "string",
"optional": true,
"field": "ABDOCU_NO"
},
{
"type": "string",
"optional": false,
"field": "WRT_DT"
},
{
"type": "string",
"optional": false,
"field": "ACTG_NO"
},
{
"type": "string",
"optional": false,
"field": "DOCU_CD"
},
{
"type": "string",
"optional": true,
"field": "CNSUL_DC"
},
{
"type": "string",
"optional": false,
"field": "WRT_DEPT_CD"
},
{
"type": "string",
"optional": false,
"field": "WRT_EMP_NO"
},
{
"type": "string",
"optional": false,
"field": "ACTG_DT"
},
{
"type": "string",
"optional": false,
"default": "00",
"field": "GAAP_CD"
},
{
"type": "string",
"optional": false,
"field": "DOCU_ST_CD"
},
{
"type": "string",
"optional": true,
"field": "EXCH_CD"
},
{
"type": "string",
"optional": true,
"field": "GWAPRVLST_CD"
},
{
"type": "string",
"optional": true,
"field": "INSR_FG_CD"
},
{
"type": "string",
"optional": true,
"field": "DOCU_FG_CD"
},
{
"type": "string",
"optional": true,
"field": "APRVL_EMP_NO"
},
{
"type": "string",
"optional": true,
"field": "MENU_CD"
},
{
"type": "string",
"optional": true,
"field": "MODULE_MNG_NO"
},
{
"type": "string",
"optional": true,
"field": "ABDOCU_FG_CD"
},
{
"type": "string",
"optional": true,
"default": "N",
"field": "GW_YN"
},
{
"type": "string",
"optional": true,
"field": "AUDOFIR_ID"
},
{
"type": "string",
"optional": true,
"field": "ATCH_CHNLNG_VER_VR"
},
{
"type": "string",
"optional": true,
"field": "APRVL_DT"
},
{
"type": "string",
"optional": true,
"field": "REVJRNZ_FG_CD"
},
{
"type": "int16",
"optional": false,
"field": "ACCSEQ_SQ"
},
{
"type": "string",
"optional": true,
"field": "FILE_ATCH_DC"
},
{
"type": "string",
"optional": true,
"field": "ATCH_FILE_NM"
},
{
"type": "string",
"optional": true,
"field": "INSERT_ID"
},
{
"type": "string",
"optional": true,
"field": "INSERT_IP"
},
{
"type": "string",
"optional": true,
"field": "INSERT_MCADDR_NM"
},
{
"type": "int64",
"optional": true,
"name": "org.apache.kafka.connect.data.Timestamp",
"version": 1,
"field": "INSERT_DTS"
},
{
"type": "string",
"optional": true,
"field": "UPDATE_ID"
},
{
"type": "string",
"optional": true,
"field": "UPDATE_IP"
},
{
"type": "string",
"optional": true,
"field": "UPDATE_MCADDR_NM"
},
{
"type": "int64",
"optional": true,
"name": "org.apache.kafka.connect.data.Timestamp",
"version": 1,
"field": "UPDATE_DTS"
},
{
"type": "string",
"optional": true,
"field": "ATHZ_RPTS_CD"
},
{
"type": "string",
"optional": true,
"field": "GWDOCU_NO"
},
{
"type": "string",
"optional": true,
"field": "RMENU_CD"
},
{
"type": "string",
"optional": true,
"field": "CONN_KEY_VR"
}
],
"optional": true,
"name": "dev-erp10.COMET.FI_DOCU_MST.Value"
},
"payload": null
}


Symptom 1: Missing op: d and Null Payloads

In the Kafka topic, I see the key correctly, but the Value Payload is null. This indicates that only the Tombstone record is being generated, and the actual Delete record (op: d)—which should have been generated by the ExtractNewRecordState SMT with delete.handling.mode: rewrite—is missing.

Example Topic Key:

JSON
{ "schema": { ... }, "payload": { "COMPANY_CD": "TEST", "PC_CD": "TEST", "DOCU_NO": "FI202306010002" } }

Example Topic Value:

JSON
{ "schema": { ... }, "payload": null }

Symptom 2: JDBC Sink Connector DLQ Failure

Because the payload is null (Tombstone), the Confluent JDBC Sink Connector fails to process the record and sends it to the Dead Letter Queue (DLQ). The error in the DLQ header is as follows:

Exception: io.confluent.connect.jdbc.sink.TableAlterOrCreateException Message: Cannot ALTER TABLE "sjsrm"."fi_docu_mst" to add missing field SinkRecordField{schema=Schema{STRING}, name='COMPANY_CD', isPrimaryKey=false}, as the field is not optional and does not have a default value

Analysis & Questions

  1. Compatibility Change: This setup worked perfectly on Debezium 3.0.0. After upgrading to 3.3.1, the op: d record (the "rewrite" event) seems to be skipped, leaving only the Tombstone.

  2. Sink Conflict: The JDBC Sink Connector expects the fields (like COMPANY_CD) to be present to perform the deletion/update, but since it receives a null payload (Tombstone), it interprets the missing fields as a schema mismatch and attempts an ALTER TABLE, which fails because the columns are NOT NULL.

  3. Source or Sink?: Given that this only occurs with the Oracle Source Connector after the upgrade, is there a specific change in how Debezium 3.3.1 handles LogMiner delete events or how the ExtractNewRecordState SMT interacts with Oracle?

Is this a known issue in Debezium 3.3.1, and why is the op: d record no longer being produced before the Tombstone?



Nathan Smit

unread,
Feb 4, 2026, 12:07:02 AMFeb 4
to debezium
Hey hyojin, check out the documentation for extract new record state here.  You'll see that the configuration has changed:  https://debezium.io/documentation/reference/stable/transformations/event-flattening.html

An example of what my configuration for flattening looks like:

# Transformations Configuration transforms=unwrap
transforms.unwrap.type=io.debezium.transforms.ExtractNewRecordState
transforms.unwrap.delete.tombstone.handling.mode=rewrite 
transforms.unwrap.add.fields=...list of added fields...

hyojin lee

unread,
Feb 4, 2026, 12:50:46 AMFeb 4
to debezium

Thank you for the quick response. I missed the updated SMT documentation you shared, and that was exactly the issue.

The problem was that I was using the old configuration:

  • As-is: transforms.unwrap.delete.handling.mode: rewrite

After checking the documentation, I updated it to use the newer property:

  • To-be: transforms.unwrap.delete.tombstone.handling.mode: rewrite-with-tombstone

This change successfully restored both the delete events with the "before" data and the tombstones. My configuration now looks like this:

JSON
"transforms": "unwrap", "transforms.unwrap.type": "io.debezium.transforms.ExtractNewRecordState", "transforms.unwrap.delete.tombstone.handling.mode": "rewrite-with-tombstone", "transforms.unwrap.add.fields": "op,source.ts_ms", "tombstones.on.delete": "true"

Everything is working perfectly now. I really appreciate your help!



2026년 2월 4일 수요일 PM 2시 7분 2초 UTC+9에 nath...@pepkorit.com님이 작성:
Reply all
Reply to author
Forward
0 new messages