Class TransactionalBuffer
- java.lang.Object
-
- io.debezium.connector.oracle.logminer.TransactionalBuffer
-
- All Implemented Interfaces:
AutoCloseable
@NotThreadSafe public final class TransactionalBuffer extends Object implements AutoCloseable
Buffer that stores transactions and related callbacks that will be executed when a transaction commits or discarded when a transaction has been rolled back.- Author:
- Andrey Pustovetov
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static classTransactionalBuffer.DmlEventRepresents a DML event for a given table row.private static classTransactionalBuffer.LobEraseEventRepresents a LOB_ERASE eventprivate static classTransactionalBuffer.LobWriteEventRepresents a LOB_WRITE eventprivate static classTransactionalBuffer.LogMinerEventBase class for all possible LogMiner eventsprivate static classTransactionalBuffer.RecentlyCommittedTransactionRepresents a transaction boundary that was recently committed.private static classTransactionalBuffer.SelectLobLocatorEventRepresents a SELECT_LOB_LOCATOR eventprivate static classTransactionalBuffer.TransactionRepresents a logical database transaction
-
Field Summary
Fields Modifier and Type Field Description private Set<String>abandonedTransactionIdsprivate Clockclockprivate OracleConnectorConfigconnectorConfigprivate ErrorHandlererrorHandlerprivate ScnlastCommittedScnprivate static org.slf4j.LoggerLOGGERprivate ScnmaxCommittedScnprivate Set<TransactionalBuffer.RecentlyCommittedTransaction>recentlyCommittedTransactionIdsprivate Set<Scn>recentlyEmittedDdlsprivate Set<String>rolledBackTransactionIdsprivate OracleDatabaseSchemaschemaprivate OracleStreamingChangeEventSourceMetricsstreamingMetricsprivate Map<String,TransactionalBuffer.Transaction>transactions
-
Constructor Summary
Constructors Constructor Description TransactionalBuffer(OracleConnectorConfig connectorConfig, OracleDatabaseSchema schema, Clock clock, ErrorHandler errorHandler, OracleStreamingChangeEventSourceMetrics streamingMetrics)Constructor to create a new instance.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) voidabandonLongTransactions(Scn thresholdScn, OracleOffsetContext offsetContext)If for some reason the connector got restarted, the offset will point to the beginning of the oldest captured transaction.private ScncalculateSmallestScn()voidclose()(package private) booleancommit(String transactionId, Scn scn, OracleOffsetContext offsetContext, Timestamp timestamp, ChangeEventSource.ChangeEventSourceContext context, String debugMessage, EventDispatcher<TableId> dispatcher)Commits a transaction by looking up the transaction in the buffer and if exists, all registered callbacks will be executed in chronological order, emitting events for each followed by a transaction commit event.(package private) ScngetMinimumScn()(package private) Set<String>getRolledBackTransactionIds()(package private) booleanisDdlOperationRegistered(Scn scn)Returns whether the ddl operation has been registered.(package private) booleanisEmpty()Returnstrueif buffer is empty, otherwisefalse.private booleanisForSameTableOrScn(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Checks whether the two events are for the same table or participate in the same system change.private booleanisRecentlyCommitted(String transactionId)Returns whether the specified transaction has recently been committed.private booleanisSameTableRow(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Checks whether the two events are for the same table row.(package private) booleanisTransactionRegistered(String txId)private voidmergeNewColumns(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Merge column values fromeventwithprevEvent.private StringparseLobWriteSql(String sql)Parses aLOB_WRITEoperation SQL fragment.private List<String>readAndCombineLobWriteEvents(TransactionalBuffer.Transaction transaction, int index, boolean binaryData)Reads the transaction event queue and combines all LOB_WRITE events starting at the provided index.private intreadAndConsumeLobEraseEvents(TransactionalBuffer.Transaction transaction, int index)Read and remove all LobErase events detected in the transaction event queue.private voidreconcileTransaction(TransactionalBuffer.Transaction transaction)Reconcile the specified transaction by merging multiple events that should be emitted as a single logical event, such as changes made to LOB column types that involve multiple events.(package private) voidregisterDdlOperation(Scn scn)Registers a DDL operation with the buffer.(package private) voidregisterDmlOperation(int operation, String transactionId, Scn scn, TableId tableId, Supplier<LogMinerDmlEntry> entrySupplier, Instant changeTime, String rowId, Object rsId)Register a DML operation with the transaction buffer.private booleanregisterEvent(String transactionId, Scn scn, Instant changeTime, Supplier<TransactionalBuffer.LogMinerEvent> supplier)Helper method to register a givenTransactionalBuffer.LogMinerEventimplementation with the buffer.(package private) voidregisterLobEraseOperation(int operation, String transactionId, Scn scn, TableId tableId, Instant changeTime, String rowId, Object rsId)Register aLOB_ERASEoperation with the transction buffer.(package private) voidregisterLobWriteOperation(int operation, String transactionId, Scn scn, TableId tableId, String data, Instant changeTime, String rowId, Object rsId)Register aLOB_WRITEoperation with the transaction buffer.(package private) voidregisterSelectLobOperation(int operation, String transactionId, Scn scn, TableId tableId, Instant changeTime, String rowId, Object rsId, String segOwner, String tableName, String redoSql, Table table, SelectLobParser selectLobParser)Register aSEL_LOB_LOCATORoperation with the transaction buffer.(package private) voidregisterTransaction(String transactionId, Scn scn)Register a new transaction with the transaction buffer.(package private) booleanrollback(String transactionId, String debugMessage)Clears registered callbacks for given transaction identifier.private booleanshouldMergeDmlEvent(TransactionalBuffer.Transaction transaction, int index, TransactionalBuffer.DmlEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Attempts to merge the provided DML event with the previous event in the transaction.private booleanshouldMergeSelectLobLocatorEvent(TransactionalBuffer.Transaction transaction, int index, TransactionalBuffer.SelectLobLocatorEvent event, TransactionalBuffer.LogMinerEvent prevEvent)Attempts to merge the provided SEL_LOB_LOCATOR event with the previous event in the transaction.StringtoString()(package private) voidundoDmlOperation(String transactionId, String undoRowId, TableId tableId)Undo a staged DML operation in the transaction buffer.(package private) ScnupdateOffsetContext(OracleOffsetContext offsetContext, EventDispatcher<TableId> dispatcher)Update the offset context based on the current state of the transaction buffer.
-
-
-
Field Detail
-
LOGGER
private static final org.slf4j.Logger LOGGER
-
connectorConfig
private final OracleConnectorConfig connectorConfig
-
transactions
private final Map<String,TransactionalBuffer.Transaction> transactions
-
schema
private final OracleDatabaseSchema schema
-
clock
private final Clock clock
-
errorHandler
private final ErrorHandler errorHandler
-
recentlyCommittedTransactionIds
private final Set<TransactionalBuffer.RecentlyCommittedTransaction> recentlyCommittedTransactionIds
-
streamingMetrics
private final OracleStreamingChangeEventSourceMetrics streamingMetrics
-
lastCommittedScn
private Scn lastCommittedScn
-
maxCommittedScn
private Scn maxCommittedScn
-
-
Constructor Detail
-
TransactionalBuffer
TransactionalBuffer(OracleConnectorConfig connectorConfig, OracleDatabaseSchema schema, Clock clock, ErrorHandler errorHandler, OracleStreamingChangeEventSourceMetrics streamingMetrics)
Constructor to create a new instance.- Parameters:
connectorConfig- connector configuration, should not benullschema- database schemaclock- system clockerrorHandler- the connector error handlerstreamingMetrics- the streaming metrics
-
-
Method Detail
-
getRolledBackTransactionIds
Set<String> getRolledBackTransactionIds()
- Returns:
- rolled back transactions
-
registerDdlOperation
void registerDdlOperation(Scn scn)
Registers a DDL operation with the buffer.- Parameters:
scn- the system change number
-
isDdlOperationRegistered
boolean isDdlOperationRegistered(Scn scn)
Returns whether the ddl operation has been registered.- Parameters:
scn- the system change number- Returns:
- true if the ddl operation has been seen and processed, false otherwise.
-
registerDmlOperation
void registerDmlOperation(int operation, String transactionId, Scn scn, TableId tableId, Supplier<LogMinerDmlEntry> entrySupplier, Instant changeTime, String rowId, Object rsId)Register a DML operation with the transaction buffer.- Parameters:
operation- operation typetransactionId- unique transaction identifierscn- system change numbertableId- table identifierentrySupplier- parser entry providerchangeTime- time the DML operation occurredrowId- unique row identifierrsId- rollback sequence identifier
-
registerSelectLobOperation
void registerSelectLobOperation(int operation, String transactionId, Scn scn, TableId tableId, Instant changeTime, String rowId, Object rsId, String segOwner, String tableName, String redoSql, Table table, SelectLobParser selectLobParser)Register aSEL_LOB_LOCATORoperation with the transaction buffer.- Parameters:
operation- operation typetransactionId- unique transaction identifierscn- system change numbertableId- table identifierchangeTime- time the operation occurredrowId- unique row identifierrsId- rollback sequence identifiersegOwner- table ownertableName- table nameredoSql- the redo sql statementtable- the relational tableselectLobParser- the select LOB parser
-
registerLobWriteOperation
void registerLobWriteOperation(int operation, String transactionId, Scn scn, TableId tableId, String data, Instant changeTime, String rowId, Object rsId)Register aLOB_WRITEoperation with the transaction buffer.- Parameters:
operation- operation typetransactionId- unique transaction identifierscn- system change numbertableId- table identifierdata- data written by the LOB operationchangeTime- time the operation occurredrowId- unique row identifierrsId- rollback sequence identifier
-
registerLobEraseOperation
void registerLobEraseOperation(int operation, String transactionId, Scn scn, TableId tableId, Instant changeTime, String rowId, Object rsId)Register aLOB_ERASEoperation with the transction buffer.- Parameters:
operation- operation typetransactionId- unique transaction identifierscn- system change numbertableId- table identifierchangeTime- time the operation occurredrowId- unique row identifierrsId- rollback sequence identifier
-
undoDmlOperation
void undoDmlOperation(String transactionId, String undoRowId, TableId tableId)
Undo a staged DML operation in the transaction buffer.- Parameters:
transactionId- unique transaction identifierundoRowId- unique row identifier to be undonetableId- table identifier
-
registerTransaction
void registerTransaction(String transactionId, Scn scn)
Register a new transaction with the transaction buffer.- Parameters:
transactionId- unique transaction identifierscn- starting SCN of the transaction
-
commit
boolean commit(String transactionId, Scn scn, OracleOffsetContext offsetContext, Timestamp timestamp, ChangeEventSource.ChangeEventSourceContext context, String debugMessage, EventDispatcher<TableId> dispatcher)
Commits a transaction by looking up the transaction in the buffer and if exists, all registered callbacks will be executed in chronological order, emitting events for each followed by a transaction commit event.- Parameters:
transactionId- transaction identifierscn- SCN of the commit.offsetContext- Oracle offsettimestamp- commit timestampcontext- context to check that source is runningdebugMessage- messagedispatcher- event dispatcher- Returns:
- true if committed transaction is in the buffer, was not processed yet and processed now
-
updateOffsetContext
Scn updateOffsetContext(OracleOffsetContext offsetContext, EventDispatcher<TableId> dispatcher) throws InterruptedException
Update the offset context based on the current state of the transaction buffer.- Parameters:
offsetContext- offset context, should not benulldispatcher- event dispatcher, should not benull- Returns:
- offset context SCN, never
null - Throws:
InterruptedException- thrown if dispatch of heartbeat event fails
-
getMinimumScn
Scn getMinimumScn()
-
rollback
boolean rollback(String transactionId, String debugMessage)
Clears registered callbacks for given transaction identifier.- Parameters:
transactionId- transaction iddebugMessage- message- Returns:
- true if the rollback is for a transaction in the buffer
-
abandonLongTransactions
void abandonLongTransactions(Scn thresholdScn, OracleOffsetContext offsetContext)
If for some reason the connector got restarted, the offset will point to the beginning of the oldest captured transaction. If that transaction was lasted for a long time, let say > 4 hours, the offset might be not accessible after restart, Hence we have to address these cases manually.In case of an abandonment, all DMLs/Commits/Rollbacks for this transaction will be ignored
- Parameters:
thresholdScn- the smallest SVN of any transaction to keep in the buffer. All others will be removed.offsetContext- the offset context
-
isTransactionRegistered
boolean isTransactionRegistered(String txId)
-
calculateSmallestScn
private Scn calculateSmallestScn()
-
isEmpty
boolean isEmpty()
Returnstrueif buffer is empty, otherwisefalse.- Returns:
trueif buffer is empty, otherwisefalse
-
close
public void close()
- Specified by:
closein interfaceAutoCloseable
-
registerEvent
private boolean registerEvent(String transactionId, Scn scn, Instant changeTime, Supplier<TransactionalBuffer.LogMinerEvent> supplier)
Helper method to register a givenTransactionalBuffer.LogMinerEventimplementation with the buffer. If the event is registered, the underlying metrics active transactions and lag will be re-calculated.- Parameters:
transactionId- transaction id that contained the given eventscn- system change number for the eventchangeTime- the time the event occurredsupplier- supplier function to generate the event if validity checks pass- Returns:
- true if the event was registered, false otherwise
-
isRecentlyCommitted
private boolean isRecentlyCommitted(String transactionId)
Returns whether the specified transaction has recently been committed.- Parameters:
transactionId- the transaction identifier- Returns:
- true if the transaction has been recently committed (seen by the connector), otherwise false.
-
parseLobWriteSql
private String parseLobWriteSql(String sql)
Parses aLOB_WRITEoperation SQL fragment.- Parameters:
sql- sql statement- Returns:
- the parsed statement
- Throws:
io.debezium.DebeziumException- if an unexpected SQL fragment is provided that cannot be parsed
-
reconcileTransaction
private void reconcileTransaction(TransactionalBuffer.Transaction transaction)
Reconcile the specified transaction by merging multiple events that should be emitted as a single logical event, such as changes made to LOB column types that involve multiple events.- Parameters:
transaction- transaction to be reconciled, nevernull
-
shouldMergeSelectLobLocatorEvent
private boolean shouldMergeSelectLobLocatorEvent(TransactionalBuffer.Transaction transaction, int index, TransactionalBuffer.SelectLobLocatorEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Attempts to merge the provided SEL_LOB_LOCATOR event with the previous event in the transaction.- Parameters:
transaction- transaction being processed, nevernullindex- event index being processedevent- event being processed, nevernullprevEvent- previous event in the transaction, can benull- Returns:
- true if the event is merged, false if the event was not merged.
-
shouldMergeDmlEvent
private boolean shouldMergeDmlEvent(TransactionalBuffer.Transaction transaction, int index, TransactionalBuffer.DmlEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Attempts to merge the provided DML event with the previous event in the transaction.- Parameters:
transaction- transaction being processed, nevernullindex- event index being processedevent- event being processed, nevernullprevEvent- previous event in the transaction, can benull- Returns:
- true if the event is merged, false if the event was not merged
-
readAndCombineLobWriteEvents
private List<String> readAndCombineLobWriteEvents(TransactionalBuffer.Transaction transaction, int index, boolean binaryData)
Reads the transaction event queue and combines all LOB_WRITE events starting at the provided index. for a SEL_LOB_LOCATOR event which is for binary data (BLOB) data types.- Parameters:
transaction- transaction being processed, nevernullindex- index to the first LOB_WRITE operation- Returns:
- list of string-based values for each LOB_WRITE operation
-
readAndConsumeLobEraseEvents
private int readAndConsumeLobEraseEvents(TransactionalBuffer.Transaction transaction, int index)
Read and remove all LobErase events detected in the transaction event queue.- Parameters:
transaction- transaction being processed, nevernullindex- index to the first LOB_ERASE operation- Returns:
- number of LOB_ERASE events consumed and removed from the event queue
-
isForSameTableOrScn
private boolean isForSameTableOrScn(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Checks whether the two events are for the same table or participate in the same system change.- Parameters:
event- current event being processed, nevernullprevEvent- previous/parent event that has been processed, may benull- Returns:
- true if the two events are for the same table or system change number, false otherwise
-
isSameTableRow
private boolean isSameTableRow(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Checks whether the two events are for the same table row.- Parameters:
event- current event being processed, nevernullprevEvent- previous/parent event that has been processed, nevernull- Returns:
- true if the two events are for the same table row, false otherwise
-
mergeNewColumns
private void mergeNewColumns(TransactionalBuffer.LogMinerEvent event, TransactionalBuffer.LogMinerEvent prevEvent)
Merge column values fromeventwithprevEvent.- Parameters:
event- current event being processed, nevernullprevEvent- previous/parent parent that has been processed, nevernull
-
-