[
https://issues.apache.org/jira/browse/FLINK-41101?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Martijn Visser updated FLINK-41101:
-----------------------------------
Description:
Since FLINK-41060 a restarted exactly-once JdbcSink rolls back the prepared
transactions of its own job. Those of an earlier job, after a restore from a
savepoint or a retained checkpoint into a new job, stay prepared and keep their
locks until someone rolls them back by hand. So do those of the same job at
another parallelism.
discoverAndRollbackOnRecovery was meant for this, but TransactionId.belongsTo()
only matches TransactionId instances and drivers return their own Xid, so it
never rolls anything back. Fixing that isn't enough: a transaction id doesn't
name the sink, so a wider match also rolls back the transactions of another
sink, or of a job that still runs.
A restore at a lower parallelism doesn't get that far: it has failed with "more
than one state to recover" since FLINK-25421 (3.2.0).
We should add an optional transaction id prefix, as the KafkaSink has, and roll
back the leftovers under it.
was:
XaTransaction.recoverAndRollback() filters the xids from XAResource.recover()
with TransactionId.belongsTo(xid), which returns false unless the xid is a
TransactionId. Drivers return their own Xid class, so with
JdbcExactlyOnceOptions.isDiscoverAndRollbackOnRecovery() (the default) nothing
is ever rolled back. The downscale check in belongsTo ({{numberOfSubtasks <
tXid.subtaskId}}) also looks off by one.
When fixing it, the rollback must skip the transactions of checkpoints before
the restored one: since FLINK-41060 the committer commits a transaction after
the next checkpoint completed, and the CommitterOperator restores and commits
those. Rolling them back on writer restore would lose their data. Only
transactions with a checkpoint id at or above the restored checkpoint id belong
to the writer.
> discoverAndRollbackOnRecovery never rolls back a transaction against a real
> driver
> ----------------------------------------------------------------------------------
>
> Key: FLINK-41101
> URL: https://issues.apache.org/jira/browse/FLINK-41101
> Project: Flink
> Issue Type: Bug
> Components: Connectors / JDBC
> Reporter: Martijn Visser
> Assignee: Martijn Visser
> Priority: Blocker
> Fix For: jdbc-5.0.0
>
>
> Since FLINK-41060 a restarted exactly-once JdbcSink rolls back the prepared
> transactions of its own job. Those of an earlier job, after a restore from a
> savepoint or a retained checkpoint into a new job, stay prepared and keep
> their locks until someone rolls them back by hand. So do those of the same
> job at another parallelism.
> discoverAndRollbackOnRecovery was meant for this, but
> TransactionId.belongsTo() only matches TransactionId instances and drivers
> return their own Xid, so it never rolls anything back. Fixing that isn't
> enough: a transaction id doesn't name the sink, so a wider match also rolls
> back the transactions of another sink, or of a job that still runs.
> A restore at a lower parallelism doesn't get that far: it has failed with
> "more than one state to recover" since FLINK-25421 (3.2.0).
> We should add an optional transaction id prefix, as the KafkaSink has, and
> roll back the leftovers under it.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)