Class LogMinerStreamingChangeEventSource
java.lang.Object
io.debezium.connector.oracle.logminer.LogMinerStreamingChangeEventSource
- All Implemented Interfaces:
ChangeEventSource,StreamingChangeEventSource<OraclePartition,OracleOffsetContext>
public class LogMinerStreamingChangeEventSource
extends Object
implements StreamingChangeEventSource<OraclePartition,OracleOffsetContext>
A
StreamingChangeEventSource based on Oracle's LogMiner utility.
The event handler loop is executed in a separate executor.-
Nested Class Summary
Nested classes/interfaces inherited from interface io.debezium.pipeline.source.spi.ChangeEventSource
ChangeEventSource.ChangeEventSourceContext -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final Stringprivate final Stringprivate final booleanprivate final Durationprivate final Clockprivate final OracleConnectorConfigprivate List<BigInteger>private final EventDispatcher<OraclePartition,TableId> private OracleOffsetContextprivate Scnprivate final ErrorHandlerprivate final Durationprivate final booleanprivate final JdbcConfigurationprivate final OracleConnectionprivate final intprivate static final org.slf4j.Loggerprivate final Durationprivate static final intprivate static final intprivate final OracleDatabaseSchemaprivate static final Longprivate Scnprivate Scnprivate final OracleConnectorConfig.LogMiningStrategyprivate final OracleStreamingChangeEventSourceMetrics -
Constructor Summary
ConstructorsConstructorDescriptionLogMinerStreamingChangeEventSource(OracleConnectorConfig connectorConfig, OracleConnection jdbcConnection, EventDispatcher<OraclePartition, TableId> dispatcher, ErrorHandler errorHandler, Clock clock, OracleDatabaseSchema schema, Configuration jdbcConfig, OracleStreamingChangeEventSourceMetrics streamingMetrics) -
Method Summary
Modifier and TypeMethodDescriptionprivate voidbuildDataDictionary(OracleConnection connection) Requests Oracle to build the data dictionary.calculateDeviatedEndScn(Scn lowerboundsScn, Scn upperboundsScn, Duration deviation) Calculates the deviated end scn based on the scn range and deviation.private ScncalculateEndScn(OracleConnection connection, Scn startScn, Scn prevEndScn) Calculates the mining session's end system change number.private voidcaptureSessionMemoryStatistics(OracleConnection connection) private voidcheckDatabaseAndTableState(OracleConnection connection, String pdbName, OracleDatabaseSchema schema) Checks and validates the database's supplemental logging configuration as well as the lengths of the table and column names that are part of the database schema.private voidcheckTableColumnNameLengths(Table table) Examines the table and column names and logs a warning if any name exceedsMAXIMUM_NAME_LENGTH.voidcommitOffset(Map<String, ?> partition, Map<String, ?> offset) private voidcomputeStartScnForFirstMiningSession(OracleOffsetContext offsetContext, Scn firstScn) Computes the start SCN for the first mining session.private LogMinerEventProcessorcreateProcessor(ChangeEventSource.ChangeEventSourceContext context, OraclePartition partition, OracleOffsetContext offsetContext) private OracleOffsetContextvoidendMiningSession(OracleConnection connection, OracleOffsetContext offsetContext) End the current Oracle LogMiner session, if one is in progress.voidexecute(ChangeEventSource.ChangeEventSourceContext context, OraclePartition partition, OracleOffsetContext offsetContext) This is the loop to get changes from LogMinerprivate List<BigInteger>getCurrentLogFileSequences(List<LogFile> logFiles) Get the current log file sequences from the supplied list of log files.getCurrentRedoLogFiles(OracleConnection connection) Get a list of all the CURRENT redo log file names.private List<BigInteger>Get the current redo log sequence(s).private OffsetDateTimegetDatabaseSystemTime(OracleConnection connection) Get the database system time in the database system's time zone.getDeviatedMaxScn(Scn upperboundsScn, Duration deviation) Uses the provided Upperbound SCN and deviation to calculate an SCN that happened in the past at a time based on Oracle'sTIMESTAMP_TO_SCNandSCN_TO_TIMESTAMPfunctions.private ScngetFirstScnInLogs(OracleConnection connection) Gets the first system change number in both archive and redo logs.private ScngetMaxArchiveLogScn(List<LogFile> logFiles) Get the maximum archive log SCNprivate booleanChecks whether a database log switch has occurred and updates metrics if so.voidinit(OracleOffsetContext offsetContext) private voidinitializeRedoLogsForMining(OracleConnection connection, boolean postEndMiningSession, Scn startScn) private booleanReturns whether the database is configured with ALL supplemental logging.private booleanReturns whether the database is configured with MIN supplemental logging.private booleanisStartScnInArchiveLogs(Scn startScn) Returns whether the starting system change number is in the archive logs.private booleanisTableAllColumnsSupplementalLoggingEnabled(OracleConnection connection, TableId tableId) Return whether the table is configured with ALL COLUMN supplemental logging.private voidprivate voidprivate voidprepareConnection(boolean closeAndReconnect) private LogWriterFlushStrategyResolves the Oracle LGWR buffer flushing strategy.private voidsetNlsSessionParameters(OracleConnection connection) Sets the NLS parameters for the mining session.booleanstartMiningSession(OracleConnection connection, Scn startScn, Scn endScn, int attempts) Starts a new Oracle LogMiner session.private voidUpdates the redo log names and statues in the streaming metrics.private booleanwaitForStartScnInArchiveLogs(ChangeEventSource.ChangeEventSourceContext context, Scn startScn) Waits for the starting system change number to exist in the archive logs before returning.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface io.debezium.pipeline.source.spi.StreamingChangeEventSource
executeIteration
-
Field Details
-
LOGGER
private static final org.slf4j.Logger LOGGER -
MAXIMUM_NAME_LENGTH
private static final int MAXIMUM_NAME_LENGTH- See Also:
-
ALL_COLUMN_LOGGING
- See Also:
-
MINING_START_RETRIES
private static final int MINING_START_RETRIES- See Also:
-
SMALL_REDO_LOG_WARNING
-
jdbcConnection
-
dispatcher
-
clock
-
schema
-
jdbcConfiguration
-
strategy
-
errorHandler
-
isContinuousMining
private final boolean isContinuousMining -
streamingMetrics
-
connectorConfig
-
archiveLogRetention
-
archiveLogOnlyMode
private final boolean archiveLogOnlyMode -
archiveDestinationName
-
logFileQueryMaxRetries
private final int logFileQueryMaxRetries -
initialDelay
-
maxDelay
-
startScn
-
endScn
-
snapshotScn
-
currentLogFiles
-
currentRedoLogSequences
-
effectiveOffset
-
-
Constructor Details
-
LogMinerStreamingChangeEventSource
public LogMinerStreamingChangeEventSource(OracleConnectorConfig connectorConfig, OracleConnection jdbcConnection, EventDispatcher<OraclePartition, TableId> dispatcher, ErrorHandler errorHandler, Clock clock, OracleDatabaseSchema schema, Configuration jdbcConfig, OracleStreamingChangeEventSourceMetrics streamingMetrics)
-
-
Method Details
-
init
- Specified by:
initin interfaceStreamingChangeEventSource<OraclePartition,OracleOffsetContext> - Throws:
InterruptedException
-
emptyContext
-
execute
public void execute(ChangeEventSource.ChangeEventSourceContext context, OraclePartition partition, OracleOffsetContext offsetContext) This is the loop to get changes from LogMiner- Specified by:
executein interfaceStreamingChangeEventSource<OraclePartition,OracleOffsetContext> - Parameters:
context- change event source context
-
prepareConnection
- Throws:
SQLException
-
logOnlineRedoLogSizes
- Throws:
SQLException
-
computeStartScnForFirstMiningSession
Computes the start SCN for the first mining session. Normally, this would be the snapshot SCN, but if there were pending transactions at the time the snapshot was taken, we'd miss the events in those transactions that have an SCN smaller than the snapshot SCN.- Parameters:
offsetContext- the offset contextfirstScn- the oldest SCN still available in the REDO logs
-
captureSessionMemoryStatistics
- Throws:
SQLException
-
createProcessor
private LogMinerEventProcessor createProcessor(ChangeEventSource.ChangeEventSourceContext context, OraclePartition partition, OracleOffsetContext offsetContext) -
getFirstScnInLogs
Gets the first system change number in both archive and redo logs.- Parameters:
connection- database connection, should not benull- Returns:
- the oldest system change number
- Throws:
SQLException- if a database exception occurredio.debezium.DebeziumException- if the oldest system change number cannot be found due to no logs available
-
initializeRedoLogsForMining
private void initializeRedoLogsForMining(OracleConnection connection, boolean postEndMiningSession, Scn startScn) throws SQLException - Throws:
SQLException
-
getCurrentLogFileSequences
Get the current log file sequences from the supplied list of log files.- Parameters:
logFiles- list of log files- Returns:
- list of sequences for the logs that are marked "current" in the database.
-
getMaxArchiveLogScn
Get the maximum archive log SCN- Parameters:
logFiles- the current logs that are part of the mining session- Returns:
- the maximum system change number from the archive logs
- Throws:
io.debezium.DebeziumException- if no logs are provided or if the provided logs has no archive log types
-
buildDataDictionary
Requests Oracle to build the data dictionary. During the build step, Oracle will perform an additional series of redo log switches. Additionally, this call may introduce a delay in delivering incremental changes since the dictionary will need to have statistics gathered, analyzed, and prepared by LogMiner before any redo entries can be mined. This should only be used in conjunction with the mining strategyOracleConnectorConfig.LogMiningStrategy.CATALOG_IN_REDO.- Parameters:
connection- database connection- Throws:
SQLException- if a database exception occurred
-
hasLogSwitchOccurred
Checks whether a database log switch has occurred and updates metrics if so.- Returns:
trueif a log switch was detected, otherwisefalse- Throws:
SQLException- if a database exception occurred
-
updateRedoLogMetrics
Updates the redo log names and statues in the streaming metrics.- Throws:
SQLException- if a database exception occurred
-
getCurrentRedoLogFiles
Get a list of all the CURRENT redo log file names. For Oracle RAC clusters, multiple filenames will be returned, one for each node that participates in the cluster.- Parameters:
connection- database connection, should not benull- Returns:
- unique set of all current redo log file names, with full paths, never
null - Throws:
SQLException- if a database exception occurred
-
getCurrentRedoLogSequences
Get the current redo log sequence(s). In an Oracle RAC environment, there are multiple current redo logs and therefore this method returns multiple values, each relating to a single RAC node in the Oracle cluster.- Returns:
- list of sequence numbers
- Throws:
SQLException- if a database exception occurred
-
pauseBetweenMiningSessions
- Throws:
InterruptedException
-
setNlsSessionParameters
Sets the NLS parameters for the mining session.- Parameters:
connection- database connection, should not benull- Throws:
SQLException- if a database exception occurred
-
getDatabaseSystemTime
Get the database system time in the database system's time zone.- Parameters:
connection- database connection, should not benull- Returns:
- the database system time
- Throws:
SQLException- if a database exception occurred
-
startMiningSession
public boolean startMiningSession(OracleConnection connection, Scn startScn, Scn endScn, int attempts) throws SQLException Starts a new Oracle LogMiner session. When this is called, LogMiner prepares all the necessary state for an upcoming LogMiner view query. If the mining statement defines using DDL tracking, the data dictionary will be mined as a part of this call to prepare DDL tracking state for the upcoming LogMiner view query.- Parameters:
connection- database connection, should not benullstartScn- mining session's starting system change number (exclusive), should not benullendScn- mining session's ending system change number (inclusive), can benullattempts- the number of mining start attempts- Returns:
- true if the session was started successfully, false if it should be retried
- Throws:
SQLException- if mining session failed to start
-
endMiningSession
public void endMiningSession(OracleConnection connection, OracleOffsetContext offsetContext) throws SQLException End the current Oracle LogMiner session, if one is in progress. If the current session does not have an active mining session, a log message is recorded and the method is a no-op.- Parameters:
connection- database connection, should not benulloffsetContext- connector offset context, should not benull- Throws:
SQLException- if the current mining session cannot be ended gracefully
-
calculateEndScn
private Scn calculateEndScn(OracleConnection connection, Scn startScn, Scn prevEndScn) throws SQLException Calculates the mining session's end system change number. This calculation is based upon a sliding window algorithm to where if the connector is falling behind, the mining session's end point will be calculated based on the batch size and either be increased up to the maximum batch size or reduced to as low as the minimum batch size. Additionally, this method calculates and maintains a sliding algorithm for the sleep time between the mining sessions, increasing the pause up to the maximum sleep time if the connector is not behind or is mining too quick and reducing the pause down to the mimum sleep time if the connector has fallen behind and needs to catch-up faster.- Parameters:
connection- database connection, should not benullstartScn- upcoming mining session's starting change number, should not benullprevEndScn- last mining session's ending system change number, can benull- Returns:
- the ending system change number to be used for the upcoming mining session, never
null - Throws:
SQLException- if the current max system change number cannot be obtained from the database
-
calculateDeviatedEndScn
private Optional<Scn> calculateDeviatedEndScn(Scn lowerboundsScn, Scn upperboundsScn, Duration deviation) Calculates the deviated end scn based on the scn range and deviation.- Parameters:
lowerboundsScn- the mining range's lower boundsupperboundsScn- the mining range's upper boundsdeviation- the time deviation- Returns:
- an optional that contains the deviated scn or empty if the operation should be performed again
-
getDeviatedMaxScn
Uses the provided Upperbound SCN and deviation to calculate an SCN that happened in the past at a time based on Oracle'sTIMESTAMP_TO_SCNandSCN_TO_TIMESTAMPfunctions.- Parameters:
upperboundsScn- the upper bound system change number, should not benulldeviation- the time deviation to be applied, should not benull- Returns:
- the newly calculated Scn
-
checkDatabaseAndTableState
private void checkDatabaseAndTableState(OracleConnection connection, String pdbName, OracleDatabaseSchema schema) throws SQLException Checks and validates the database's supplemental logging configuration as well as the lengths of the table and column names that are part of the database schema.- Parameters:
connection- database connection, should not benullpdbName- pluggable database name, can benullwhen not using pluggable databasesschema- connector's database schema, should not benull- Throws:
SQLException- if a database exception occurred
-
checkTableColumnNameLengths
Examines the table and column names and logs a warning if any name exceedsMAXIMUM_NAME_LENGTH.- Parameters:
table- the table, should not benull
-
isDatabaseAllSupplementalLoggingEnabled
private boolean isDatabaseAllSupplementalLoggingEnabled(OracleConnection connection) throws SQLException Returns whether the database is configured with ALL supplemental logging.- Parameters:
connection- database connection, must not benull- Returns:
- true if all supplemental logging is enabled, false otherwise
- Throws:
SQLException- if a database exception occurred
-
isDatabaseMinSupplementalLoggingEnabled
private boolean isDatabaseMinSupplementalLoggingEnabled(OracleConnection connection) throws SQLException Returns whether the database is configured with MIN supplemental logging.- Parameters:
connection- database connection, must not benull- Returns:
- true if min supplemental logging is enabled, false otherwise
- Throws:
SQLException- if a database exception occurred
-
isTableAllColumnsSupplementalLoggingEnabled
private boolean isTableAllColumnsSupplementalLoggingEnabled(OracleConnection connection, TableId tableId) throws SQLException Return whether the table is configured with ALL COLUMN supplemental logging.- Parameters:
connection- database connection, must not benulltableId- table identifier, must not benull- Returns:
- true if all column supplemental logging is enabled, false otherwise
- Throws:
SQLException- if a database exception occurred
-
resolveFlushStrategy
Resolves the Oracle LGWR buffer flushing strategy.- Returns:
- the strategy to be used to flush Oracle's LGWR process, never
null.
-
waitForStartScnInArchiveLogs
private boolean waitForStartScnInArchiveLogs(ChangeEventSource.ChangeEventSourceContext context, Scn startScn) throws SQLException, InterruptedException Waits for the starting system change number to exist in the archive logs before returning.- Parameters:
context- the change event source contextstartScn- the starting system change number- Returns:
- true if the code should continue, false if the code should end.
- Throws:
SQLException- if a database exception occurredInterruptedException- if the pause between checks is interrupted
-
isStartScnInArchiveLogs
Returns whether the starting system change number is in the archive logs.- Parameters:
startScn- the starting system change number- Returns:
- true if the starting system change number is in the archive logs; false otherwise.
- Throws:
SQLException- if a database exception occurred
-
commitOffset
- Specified by:
commitOffsetin interfaceStreamingChangeEventSource<OraclePartition,OracleOffsetContext>
-
getOffsetContext
- Specified by:
getOffsetContextin interfaceStreamingChangeEventSource<OraclePartition,OracleOffsetContext>
-