Skip to content

oracledb_cdc: support controlling LogMiner session age - #4669

Draft
josephwoodward wants to merge 7 commits into
mainfrom
jw/oraclelm_session_ceiling
Draft

oracledb_cdc: support controlling LogMiner session age#4669
josephwoodward wants to merge 7 commits into
mainfrom
jw/oraclelm_session_ceiling

Conversation

@josephwoodward

Copy link
Copy Markdown
Contributor

No description provided.

Comment thread internal/impl/oracledb/input_oracledb_cdc.go
Comment thread internal/impl/oracledb/logminer/logminer.go
@josephwoodward
josephwoodward force-pushed the jw/oraclelm_session_ceiling branch from 96885e4 to f9f6bf7 Compare August 5, 2026 17:26
Comment thread internal/impl/oracledb/logminer/logminer.go Outdated
if cfg.SessionMaxAge, err = lmConf.FieldDuration(ociFieldSessionMaxAge); err != nil {
return nil, err
}
if cfg.SessionMaxAge < 0 {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This new validation branch has no test coverage. internal/impl/oracledb/config_test.go already has the natural home for it — the table-driven errContains pattern used by TestBuildConnectionURL (config_test.go#L21-L32) and the oracleDBStreamConfigSpec.ParseYAML setup in TestParseSnapshotMode (config_test.go#L219-L227).

Adding a case that parses logminer: {session_max_age: -5s} and asserts require.ErrorContains(t, err, "must be 0 or greater") (plus a positive case asserting the parsed duration reaches Config.SessionMaxAge) would cover both the guard and the field wiring. The new session_test.go tests exercise the LogMiner side of the feature but not the config path.

lm.log.Debugf("LogMiner session has been open for %s, exceeding session_max_age of %s — ending idle session to release accumulated session memory",
lm.sessionMgr.Age(), lm.cfg.SessionMaxAge)
if err := lm.sessionMgr.EndSession(ctx, conn); err != nil {
return fmt.Errorf("ending expired logminer session while idle: %w", err)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Idle END_LOGMNR failure now tears down the whole input, unlike the existing restart path.

endExpiredIdleSession propagates the EndSession error, and miningCycle returns it to ReadChanges, which aborts the streaming goroutine. In input_oracledb_cdc.go that error triggers o.stopSig.TriggerHasStopped(), so Read returns service.ErrNotConnected (L726-L730) and the connector performs a full reconnect/Connect() cycle.

The identical call in the age/log-switch restart path is deliberately non-fatal — it logs and continues:

// its maximum age — full reload required.
if lm.sessionMgr.IsActive() {
if err := lm.sessionMgr.EndSession(ctx, conn); err != nil {
lm.log.Errorf("Failed to end existing LogMiner session: %v", err)
}
}

Ending an idle session is purely a PGA-relief optimisation, so a transient END_LOGMNR failure shouldn't restart the input. Suggested fix: log at error/warn level and return nil here, matching the restart path. Retry is automatic — EndSession leaves active/sessionOpened untouched on failure, so IsExpired stays true and the next mining cycle tries again. This asymmetry between two invocations of the same operation is the kind of inconsistency CONTRIBUTING.md §3.1.5 (consistency with other connectors) and §3.2.2 (poor error handling) call out.

return nil, err
}
if cfg.SessionMaxAge < 0 {
return nil, fmt.Errorf("logminer.%s must be 0 or greater, got %s", ociFieldSessionMaxAge, cfg.SessionMaxAge)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New config validation branch has no test.

This is the only new user-facing validation added by the PR, and nothing exercises it. internal/impl/oracledb/config_test.go already has the table-driven ParseYAML + errContains harness this fits into (see TestBuildConnectionURL and TestParseSnapshotMode), so adding a parseLogMinerConfig case with logminer.session_max_age: -1s asserting must be 0 or greater is cheap.

Per the project test patterns, changed code should not land without tests; a session_max_age: 0s / omitted case would also pin the documented default (§1.2.4, strong config validation).

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.

1 participant