DanielLeens commented on issue #13105:
URL: https://github.com/apache/seatunnel/issues/13105#issuecomment-6595075066

   Thanks for splitting this out of #12983. I checked current `dev` and the 
ownership gap is not specific to the #11932 head:
   
   - `MultiTableSink#createWriter`/`#restoreWriter` give every table in replica 
`i` the same `SinkContextProxy` index (`subtaskIndex * replicaNum + i`, 
`MultiTableSink.java` L149-151 / L205-207).
   - `SemanticXidGenerator#belongsToSubtask` (L77-94) matches only format id, 
job id and that index.
   - `JdbcExactlyOnceSinkWriter#tryOpen` (L132-136) calls 
`XaGroupOpsImpl#recoverAndRollback` (L119-148), which excludes only 
`recoverStates.get(0)` and rolls back every other recovered XID that "belongs 
to the subtask".
   
   So a restored table writer can roll back a sibling table's prepared XID on 
the same resource manager. `MultiTableSinkWriter#prepareCommit` walks the 
tables of one queue sequentially (L743-773), so a sibling can prepare 
checkpoint N before the restored writer's first `tryOpen` sweep in the same 
barrier. Following the code (not reproduced on a full job here): the live 
commit of N then fails with `XAER_NOTA` (strict since #11569), and on the next 
restore `JdbcSinkAggregatedCommitter#replayRecoveredCheckpoint` (L207-216) 
treats an all-absent batch as already resolved. That would turn the failure 
into silently lost rows, so this is a data-correctness bug, not only a restart 
failure. The shared index dates back at least to #7243, so released versions 
with multi-table XA are probably affected too.
   
   #13109 is the fix PR, so further work should go there. For review, please 
cover:
   
   1. Compatibility: XIDs keep the same byte layout. State that a checkpoint 
from the latest release restores, and say what happens to orphans whose branch 
qualifier is not in the saved state (pre-upgrade attempts).
   2. `recoverAndRollback` now throws on rollback failure instead of logging. A 
transient RM error, or an XID another actor already resolved (`XAER_NOTA`), 
should not cause a permanent restart loop.
   3. Rescaling (`replicaNum` or parallelism change) with several restored 
owner tuples.
   4. A job-level E2E in `connector-jdbc-e2e`: two tables in one 
`MultiTableSink` with `is_exactly_once = true`, a failure after a sibling has 
prepared, restore, then exact row counts in both target tables. 
`XaGroupOpsImplIT` alone does not exercise the multi-table writer path.
   
   This stays separate from #12807/#13104, which cover committer routing, not 
writer-side cleanup.
   


-- 
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