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

Reply via email to