[ 
https://issues.apache.org/jira/browse/FLINK-41312?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

liting liu updated FLINK-41312:
-------------------------------
    Description: 
h2. Problem

When a partition is dropped or expires while a Fluss pipeline source is 
running, the logical table and other partitions can remain subscribed. The 
source can retain splits and SDK subscriptions for the absent partition, 
repeatedly request metadata for its old partition ID, and delay or stall 
consumption of surviving partitions while the job remains RUNNING.

This issue covers retirement of partitions that are already active in a running 
source. Filtering obsolete splits during whole-job checkpoint recovery is 
tracked separately by FLINK-41313.

h2. Reproduction

# Create a partitioned Fluss primary-key table with partitions P_old and P_live.
# Start a CDC pipeline for the table with periodic partition discovery enabled, 
write records into both partitions, and wait until both are consumed.
# Keep the pipeline running and drop P_old through the Fluss Admin API, leaving 
the logical table and P_live intact. Partition expiration can cause the same 
condition.
# Continue writing records into P_live.
# Observe the source's partition subscriptions, metadata requests, and 
consumption progress. The absent partition should be retired without 
interrupting the surviving partition.

h2. Root cause

* Dynamic subscription removal currently operates at logical-table granularity. 
A partition can disappear without removing its table from the subscribed table 
set.
* The reader therefore retains already-active partition splits, and the split 
reader's existing whole-table removal path does not unsubscribe those 
partition/bucket subscriptions.
* Missing-partition metadata retries in the shared fetching path can delay 
valid partitions. Refreshing metadata alone does not retire an obsolete 
subscription.

h2. Proposed fix

* Build on the complete partition inventory introduced by FLINK-41313 and 
compare it with the reader's active splits after a successful discovery.
* Route absent-partition cleanup through the fetcher thread. Unsubscribe the 
exact partition ID and buckets, and cancel their active or queued snapshot 
scans.
* Return removed split IDs through the normal finished-split path so reader 
checkpoint state is cleaned consistently.
* Preserve the logical table, schema state, and resources required by surviving 
partitions.
* Keep existing checkpoint serialization formats and split IDs. Same-name 
partition recreation with a different physical ID remains a separate concern.


  was:
h2. Motivation

For Fluss-to-Fluss replication, a missing sink table is created automatically. 
However, the source table's bucket keys are not carried in the CDC schema. 
Unless the user repeats them in the sink's bucket.key option, the new target 
can have a different bucket layout.

The example below uses an ordinary non-partitioned table.

h2. Minimal reproduction

# Create a non-partitioned Fluss source table cdc_repro.orders with the 
following definition:
{code}
Columns: id INT NOT NULL, tenant INT NOT NULL, marker STRING
Primary key: (id, tenant)
Bucket keys: (tenant)
Bucket count: 2
{code}
# Leave cdc_repro.orders absent in a second Fluss cluster.
# Start a Fluss-to-Fluss CDC pipeline for that table, without a sink bucket.key 
override.
# Inspect the bucket keys of the automatically created target table.

The current code derives target bucket keys (id, tenant), instead of preserving 
the source bucket keys (tenant). The columns and primary key can therefore 
match while the bucket layout differs.

h2. Current implementation

Reviewed Apache Flink CDC master at db45d06a1e35bc6be87f7b58913c768f8f299d3e:

* FlussMetadataAccessor.getTableSchema() passes only the Fluss schema and 
partition keys to FlussConversions.toCdcSchema(); source bucket keys are not 
propagated.
* FlussMetaDataApplier.applyCreateTable() gets bucket keys from the sink 
configuration.
* FlussConversions.toFlussTable() defaults unspecified bucket keys to primary 
keys minus partition keys.

Source references:
* 
https://github.com/apache/flink-cdc/blob/db45d06a1e35bc6be87f7b58913c768f8f299d3e/flink-cdc-connect/flink-cdc-pipeline-connectors/flink-cdc-pipeline-connector-fluss/src/main/java/org/apache/flink/cdc/connectors/fluss/source/FlussMetadataAccessor.java#L98-L104
* 
https://github.com/apache/flink-cdc/blob/db45d06a1e35bc6be87f7b58913c768f8f299d3e/flink-cdc-connect/flink-cdc-pipeline-connectors/flink-cdc-pipeline-connector-fluss/src/main/java/org/apache/flink/cdc/connectors/fluss/utils/FlussConversions.java#L169-L186

h2. Expected behavior / proposal

When automatically creating a Fluss sink table from a Fluss source, preserve 
the source bucket keys if no explicit sink bucket.key override is provided.

* Keep explicit sink overrides authoritative.
* Keep the current default for sources that do not provide Fluss bucket 
metadata.
* Preserve the existing target table's layout when the target already exists.

The current documentation describes the existing default, so this issue 
proposes improving the Fluss-to-Fluss auto-creation behavior rather than 
claiming the implementation violates that documented default.

h2. Related work and workaround

FLINK-40850 / PR #4564 fixes compatibility checks for pre-created primary-key 
tables with custom bucket keys. It explicitly leaves new-table creation 
unchanged, so it does not address this case.

The current workaround is to repeat the source bucket keys in the sink 
configuration:
{code:yaml}
sink:
  type: fluss
  bootstrap.servers: <target-bootstrap>
  bucket.key: cdc_repro.orders:tenant
{code}

h2. Validation scope

The metadata propagation and defaulting behavior above were confirmed by 
source-code inspection. A new upstream end-to-end reproduction has not been run 
for this report.

     Issue Type: Bug  (was: Improvement)
        Summary: Fluss pipeline source does not retire dropped or expired 
partitions while running  (was: Preserve source bucket keys when auto-creating 
Fluss-to-Fluss sink tables)

> Fluss pipeline source does not retire dropped or expired partitions while 
> running
> ---------------------------------------------------------------------------------
>
>                 Key: FLINK-41312
>                 URL: https://issues.apache.org/jira/browse/FLINK-41312
>             Project: Flink
>          Issue Type: Bug
>          Components: Flink CDC
>            Reporter: liting liu
>            Priority: Major
>
> h2. Problem
> When a partition is dropped or expires while a Fluss pipeline source is 
> running, the logical table and other partitions can remain subscribed. The 
> source can retain splits and SDK subscriptions for the absent partition, 
> repeatedly request metadata for its old partition ID, and delay or stall 
> consumption of surviving partitions while the job remains RUNNING.
> This issue covers retirement of partitions that are already active in a 
> running source. Filtering obsolete splits during whole-job checkpoint 
> recovery is tracked separately by FLINK-41313.
> h2. Reproduction
> # Create a partitioned Fluss primary-key table with partitions P_old and 
> P_live.
> # Start a CDC pipeline for the table with periodic partition discovery 
> enabled, write records into both partitions, and wait until both are consumed.
> # Keep the pipeline running and drop P_old through the Fluss Admin API, 
> leaving the logical table and P_live intact. Partition expiration can cause 
> the same condition.
> # Continue writing records into P_live.
> # Observe the source's partition subscriptions, metadata requests, and 
> consumption progress. The absent partition should be retired without 
> interrupting the surviving partition.
> h2. Root cause
> * Dynamic subscription removal currently operates at logical-table 
> granularity. A partition can disappear without removing its table from the 
> subscribed table set.
> * The reader therefore retains already-active partition splits, and the split 
> reader's existing whole-table removal path does not unsubscribe those 
> partition/bucket subscriptions.
> * Missing-partition metadata retries in the shared fetching path can delay 
> valid partitions. Refreshing metadata alone does not retire an obsolete 
> subscription.
> h2. Proposed fix
> * Build on the complete partition inventory introduced by FLINK-41313 and 
> compare it with the reader's active splits after a successful discovery.
> * Route absent-partition cleanup through the fetcher thread. Unsubscribe the 
> exact partition ID and buckets, and cancel their active or queued snapshot 
> scans.
> * Return removed split IDs through the normal finished-split path so reader 
> checkpoint state is cleaned consistently.
> * Preserve the logical table, schema state, and resources required by 
> surviving partitions.
> * Keep existing checkpoint serialization formats and split IDs. Same-name 
> partition recreation with a different physical ID remains a separate concern.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to