Skip to content

[FLINK-39975][jdbc] Recover JdbcSourceSplitReader from a connection closed during cancellation#200

Merged
RocMarshal merged 1 commit into
apache:mainfrom
laughingman7743:fix/jdbc-source-reader-cancellation
Jun 23, 2026
Merged

[FLINK-39975][jdbc] Recover JdbcSourceSplitReader from a connection closed during cancellation#200
RocMarshal merged 1 commit into
apache:mainfrom
laughingman7743:fix/jdbc-source-reader-cancellation

Conversation

@laughingman7743

Copy link
Copy Markdown
Contributor

What is the purpose of the change

Fix the flaky DerbyDynamicTableSourceITCase.testLimit (and occasionally testProject). When a bounded query (e.g. LIMIT) finishes the job early, the source is cancelled while the split fetcher is still opening the next split; the
JDBC connection validated by the provider is torn down before the statement is prepared/executed, so Derby raises 08003: No current connection and the fatal SQLException fails the whole job (the test runs under
NoRestartBackoffTimeStrategy). See FLINK-39975 for the full analysis.

Brief change log

  • JdbcSourceSplitReader now opens a split via openResultSetForSplitWithReconnect, a bounded retry (MAX_CONNECTION_RETRIES = 3).
  • It retries only when the connection is actually closed (connection.isClosed()); before retrying it drops the dead connection and the stale statement/result set and re-establishes via the provider. A query error on a healthy
    connection is rethrown immediately, and an unreachable database still fails after the retry budget — real errors are not masked.
  • wakeUp() / fetch() are unchanged.

Verifying this change

  • Added JdbcSourceSplitReaderTest#testFetchReconnectsWhenConnectionClosedWhileOpeningSplit, a deterministic regression test that injects an already-closed connection, reproducing the exact 08003 error (it fails without this
    change) and asserting the reader re-establishes the connection and reads the whole split.
  • Added testFetchRethrowsImmediatelyWhenConnectionStaysOpen (a query error on a healthy connection is rethrown without reconnect) and testFetchFailsAfterExhaustingReconnectRetries (gives up after the retry budget instead of
    looping forever).
  • DerbyDynamicTableSourceITCase passes repeated runs.

Does this pull request potentially affect one of the following parts:

  • Dependencies (does it add or upgrade a dependency): no
  • The public API, i.e., is any changed class annotated with @Public(Evolving): no
  • The serializers: no
  • The runtime per-record code paths (performance sensitive): no — the retry only triggers on a closed-connection error while opening a split
  • Anything that affects deployment or recovery: no
  • The S3 file system connector: no

Documentation

  • Does this pull request introduce a new feature? no
  • If yes, how is the feature documented? not applicable

@RocMarshal RocMarshal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM +1.
Thanks @laughingman7743

…losed during cancellation

When a bounded query (e.g. LIMIT) finishes the job early, the source is
cancelled while the split fetcher is still opening the next split. The
JDBC connection validated by the provider is torn down before the
statement is prepared/executed, so Derby raises "08003: No current
connection"; the fatal SQLException fails the whole job and makes
DerbyDynamicTableSourceITCase.testLimit flaky.

Wrap the split-open in a bounded retry: when the connection is found
closed, drop it together with the stale statement/result set and
re-establish it via the provider, retrying up to MAX_CONNECTION_RETRIES.
A genuine query error on a healthy connection is rethrown immediately,
and an unreachable database still fails the job after the retry budget,
so real errors are not masked. wakeUp()/fetch() are left unchanged.

Add a deterministic regression test that injects an already-closed
connection (reproducing the exact 08003 and failing without the fix),
plus tests for the immediate-rethrow and retry-exhaustion branches.
@laughingman7743 laughingman7743 force-pushed the fix/jdbc-source-reader-cancellation branch from fc2003d to 76593c8 Compare June 23, 2026 13:49
@RocMarshal RocMarshal merged commit f8f84a4 into apache:main Jun 23, 2026
5 checks passed
@boring-cyborg

boring-cyborg Bot commented Jun 23, 2026

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants