davidzollo opened a new issue, #11381:
URL: https://github.com/apache/seatunnel/issues/11381

   ### Motivation
   
   PR #11156 fixes an unsafe ordering in the Doris sink by flushing the 
in-flight Stream Load before applying a schema change in non-2PC mode, and by 
rejecting unsafe `sink.enable-2pc=true` with positional formats such as CSV.
   
   That connector-level fix is still useful, but SeaTunnel should also provide 
a stronger engine-level guarantee: before a `SchemaChangeEvent` reaches sink 
writers and downstream DDL is applied, all records written with the previous 
schema should have crossed a checkpoint / flush boundary.
   
   Without this guarantee, a source or transform path that emits a 
`SchemaChangeEvent` without first triggering the existing schema-change 
checkpoint protocol can still let buffered old-schema rows be committed after 
the target table has already been altered.
   
   ### Current behavior
   
   SeaTunnel already has part of the required mechanism:
   
   - CDC deserialization can mark schema-change checkpoint boundaries through 
`Collector.markSchemaChangeBeforeCheckpoint()` and 
`Collector.markSchemaChangeAfterCheckpoint()`.
   - `SeaTunnelSourceCollector` captures these signals.
   - `SourceFlowLifeCycle` triggers `SCHEMA_CHANGE_BEFORE_POINT_TYPE` / 
`SCHEMA_CHANGE_AFTER_POINT_TYPE` checkpoints and pauses source collection while 
schema change is in progress.
   - Sink checkpoint handling calls `SinkWriter.prepareCommit(checkpointId)` 
and `SinkWriter.snapshotState(checkpointId)`, which is the right place for 
connectors to flush / pre-commit buffered data.
   
   However, the sink-side schema event path still applies DDL directly when the 
event arrives:
   
   - `SinkFlowLifeCycle.received(...)` handles `SchemaChangeEvent` by directly 
calling `SupportSchemaEvolutionSinkWriter.applySchemaChange(event)` or the 
deprecated `SinkWriter.applySchemaChange(event)`.
   
   This means the global protection depends on every source producing the 
correct schema-change-before checkpoint signal before the schema event. It is 
not currently enforced by the engine for all `SchemaChangeEvent` paths.
   
   ### Proposal
   
   Add an engine-level schema-change drain protocol so that a schema change 
cannot be applied to sinks until previous-schema records have been drained 
through a checkpoint / flush boundary.
   
   A possible implementation direction:
   
   1. Treat every non-create `SchemaChangeEvent` as requiring a 
schema-change-before drain unless the event is already known to be inside a 
completed schema-change checkpoint phase.
   2. Reuse the existing schema-change checkpoint types instead of calling 
`SinkWriter.prepareCommit()` directly outside checkpoint context, because 
`prepareCommit()` may create 2PC committables that must be completed or aborted 
by the checkpoint lifecycle.
   3. Gate forwarding of `SchemaChangeEvent` to 
`SinkFlowLifeCycle.applySchemaChange(...)` until all relevant sink subtasks 
have acknowledged the schema-change-before checkpoint.
   4. Keep connector-specific compatibility checks in connectors. For example, 
Doris still needs to reject unsafe `sink.enable-2pc=true` with positional 
formats such as CSV because only the connector knows whether its load format is 
name-based or position-based.
   5. Add unit / integration coverage for the ordering:
   
   ```text
   old-schema records
     -> schema-change-before checkpoint
     -> sink prepareCommit / snapshotState
     -> checkpoint complete
     -> SchemaChangeEvent reaches sink writer
     -> sink applies DDL
     -> new-schema records
   ```
   
   ### Expected benefits
   
   - Prevents downstream DDL from racing ahead of old-schema buffered rows.
   - Gives schema evolution a single engine-level ordering contract instead of 
relying on each connector to rediscover the same drain requirement.
   - Keeps connector-specific transaction and format validation local to each 
connector.
   - Reduces the chance of data corruption for positional formats and schema 
changes such as drop / rename / reorder-sensitive changes.
   
   ### Related context
   
   - PR #11156: connector-level Doris fix for flushing before schema change and 
rejecting unsafe 2PC schema evolution formats.
   - Existing schema-change checkpoint flow: `SeaTunnelSourceCollector`, 
`SourceFlowLifeCycle`, `CheckpointType.SCHEMA_CHANGE_BEFORE_POINT_TYPE`, and 
`SinkFlowLifeCycle`.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to