public long compareKey(PrimaryKeyTxn key2) { if (this.keyType == KeyType.LONG) { return this.key - key2.getKey(); } else { return this.keyStr.compareTo(key2.getKeyStr()); } }
private void dedupe(String file, String tmpFile, KeyType type) throws Exception { BufferedReader reader = null; BufferedWriter writer = null; PrimaryKeyTxn keyTxn = null; PrimaryKeyTxn oldKeyTxn = null; try { reader = new BufferedReader(new FileReader(file)); writer = new BufferedWriter(new FileWriter(tmpFile)); keyTxn = new PrimaryKeyTxn(Long.MIN_VALUE); oldKeyTxn = new PrimaryKeyTxn(Long.MIN_VALUE); keyTxn.setType(type); oldKeyTxn.setType(type); boolean first = true; while (true) { String line = reader.readLine(); if (null == line) break; keyTxn.readFrom(line); long cmp = keyTxn.compareKey(oldKeyTxn); if (cmp != 0) { if (!first) { oldKeyTxn.writeTo(writer); } oldKeyTxn.copyFrom(keyTxn); } first = false; } oldKeyTxn.writeTo(writer); } catch (Exception ex) { LOG.error("Got exception while deduping key_txns", ex); } finally { if (null != reader) reader.close(); if (null != writer) writer.close(); } }
private EventReaderSummary readEventsForSource( OracleTriggerMonitoredSourceInfo sourceInfo, long maxScn) throws DatabusException, EventCreationException, UnsupportedKeyException, SQLException, IOException { int retryMax = _numRetries; int numRetry = 0; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; KeyType keyType = _pKeyTypeMap.get(sourceInfo.getEventView()); String keyName = _pKeyNameMap.get(sourceInfo.getEventView()); String sql = _eventQueryMap.get(sourceInfo.getEventView()); String beginSrcKey = _beginSrcKeyMap.get(sourceInfo.getEventView()); String endSrcKey = _endSrcKeyMap.get(sourceInfo.getEventView()); if (sql == null) { sql = generateEventQuery2( sourceInfo, keyName, keyType, getPKIndex(sourceInfo), getQueryHint(sourceInfo)); } LOG.info("Chunked Query for Source (" + sourceInfo + ") is :" + sql); LOG.info("EndSrcKey for source (" + sourceInfo + ") is :" + endSrcKey); PrimaryKeyTxn endKeyTxn = null; if ((null != endSrcKey) && (!endSrcKey.trim().isEmpty())) { if (KeyType.LONG == keyType) endKeyTxn = new PrimaryKeyTxn(new Long(endSrcKey)); else endKeyTxn = new PrimaryKeyTxn(endSrcKey); } long timestamp = System.currentTimeMillis(); int numRowsFetched = 0; long totalEventSize = 0; long timeStart = System.currentTimeMillis(); long checkpointInterval = _commitInterval; boolean done = false; long lastTime = timeStart; long numRows = 0; PrimaryKeyTxn pKey = null; String minKeySQL = generateMinKeyQuery(sourceInfo, keyName); String srcName = sourceInfo.getEventView(); LOG.info("Bootstrapping for Source :" + srcName); String lastKey = _lastKeys.get(sourceInfo.getEventView()); File f = _keyTxnFilesMap.get(srcName); FileWriter oStream = new FileWriter(f, f.exists()); BufferedWriter keyTxnWriter = new BufferedWriter(oStream, _keyTxnBufferSizeMap.get(srcName)); _bootstrapSeedWriter.startEvents(); RateMonitor seedingRate = new RateMonitor("Seeding Rate"); RateMonitor queryRate = new RateMonitor("Query Rate"); seedingRate.start(); seedingRate.suspend(); queryRate.start(); queryRate.suspend(); boolean isException = false; long totProcessTime = 0; try { conn = _dataSource.getConnection(); pstmt = conn.prepareStatement(sql); if (_enableNumRowsQuery) numRows = getNumRows(conn, getTableName(sourceInfo)); else numRows = -1; long currRowId = _lastRows.get(sourceInfo.getEventView()); /** * First Key to be seeded will be decided in the following order: 1. Use * bootstrap_seeder_state's last srcKey as the key for the first chunk. 2. If (1) is empty, * use passed-in begin srcKey. 3. If (2) is also empty, use Oracle's minKey as the first Chunk * Key. */ if (null == lastKey) { lastKey = _beginSrcKeyMap.get(sourceInfo.getEventView()); LOG.info( "No last Src Key available in bootstrap_seeder_state for source (" + sourceInfo + ". Trying beginSrc Key from config :" + lastKey); } if ((null == lastKey) || (lastKey.trim().isEmpty())) { if (KeyType.LONG == keyType) pKey = new PrimaryKeyTxn(executeAndGetLong(minKeySQL)); else pKey = new PrimaryKeyTxn(executeAndGetString(minKeySQL)); } else { if (KeyType.LONG == keyType) pKey = new PrimaryKeyTxn(Long.parseLong(lastKey)); else pKey = new PrimaryKeyTxn(lastKey); } PrimaryKeyTxn lastRoundKeyTxn = new PrimaryKeyTxn(pKey); PrimaryKeyTxn lastKeyTxn = new PrimaryKeyTxn(pKey); long numUniqueKeysThisRound = 0; boolean first = true; _rate.resume(); while (!done) { LOG.info("MinKey being used for this round:" + pKey); numUniqueKeysThisRound = 0; try { lastRoundKeyTxn.copyFrom(pKey); if (KeyType.LONG == keyType) { pstmt.setLong(1, pKey.getKey()); } else { String key = pKey.getKeyStr(); pstmt.setString(1, key); } pstmt.setLong(2, _numRowsPerQuery); pstmt.setFetchSize(_numRowsPrefetch); if (_oraclePreparedStatementClass.isInstance(pstmt)) { try { _setLobPrefetchSizeMethod.invoke(pstmt, _LOBPrefetchSize); } catch (Exception e) { throw new EventCreationException("Unable to set Lob Prefetch size" + e.getMessage()); } } LOG.info( "Executing Oracle Query :" + sql + ". Key: " + pKey + ",NumRows: " + _numRowsPerQuery); queryRate.resume(); rs = pstmt.executeQuery(); queryRate.suspend(); LOG.info("Total Query Latency :" + queryRate.getDuration() / 1000000000L); long totLatency = 0; long txnId = 0; int numRowsThisRound = 0; seedingRate.resume(); while (rs.next()) { _rate.tick(); seedingRate.tick(); currRowId++; txnId = rs.getLong(2); if (KeyType.LONG == keyType) { pKey.setKeyTxn(rs.getLong(1), txnId); } else { String key = rs.getString(1); pKey.setKeyStrTxn(key, txnId); } // Write TXN to file pKey.writeTo(keyTxnWriter); // LOG.info("TXNId is :" + txnId + ",RowId is :" + currRowId); long start = System.nanoTime(); long eventSize = sourceInfo .getFactory() .createAndAppendEvent(maxScn, timestamp, rs, _bootstrapSeedWriter, false, null); long latency = System.nanoTime() - start; totLatency += latency; totalEventSize += eventSize; totProcessTime += (totLatency / 1000 * 1000); numRowsFetched++; numRowsThisRound++; if (lastKeyTxn.compareKey(pKey) != 0) { numUniqueKeysThisRound++; lastKeyTxn.copyFrom(pKey); } if (numRowsFetched % checkpointInterval == 0) { // Commit this batch and reinit _bootstrapSeedWriter.endEvents(currRowId, timestamp, null); keyTxnWriter.flush(); _bootstrapSeedWriter.startEvents(); long procTime = totLatency / 1000000000; long currTime = System.currentTimeMillis(); long diff = (currTime - lastTime) / 1000; long timeSinceStart = (currTime - timeStart) / 1000; double currRate = _rate.getRate(); currRate = (currRate <= 0) ? 1 : currRate; if (_enableNumRowsQuery) { double remTime = (numRows - currRowId) / (currRate); LOG.info( "Processed " + checkpointInterval + " rows in " + diff + " seconds, Processing Time (seconds) so far :" + (procTime) + ",Seconds elapsed since start :" + (timeSinceStart) + ",Approx Seconds remaining :" + remTime + ",Overall Row Rate:" + _rate.getRate() + "(" + seedingRate.getRate() + ")" + ",NumRows Fetched so far:" + numRowsFetched + ". TotalEventSize :" + totalEventSize); } else { LOG.info( "Processed " + checkpointInterval + " rows in " + diff + " seconds, Processing Time (seconds) so far :" + (procTime) + ",Seconds elapsed since start :" + (timeSinceStart) + ",Overall Row Rate:" + _rate.getRate() + "(" + seedingRate.getRate() + ")" + ",NumRows Fetched so far:" + numRowsFetched + ". TotalEventSize :" + totalEventSize); } lastTime = currTime; } if ((null != endKeyTxn) && (endKeyTxn.compareKey(lastKeyTxn) < 0)) { LOG.info( "Seeding to be stopped for current source as it has completed seeding upto endSrckey :" + endKeyTxn + ", Current SrcKey :" + lastKeyTxn); break; } } seedingRate.suspend(); if ((numRowsThisRound <= 1) || ((numRowsThisRound < _numRowsPerQuery) && (numUniqueKeysThisRound <= 1))) { LOG.info( "Seeding Done for source :" + sourceInfo.getEventView() + ", numRowsThisRound :" + numRowsThisRound + ", _numRowsPerQuery :" + _numRowsPerQuery + ", numUniqueKeys :" + numUniqueKeysThisRound); done = true; } else if ((numRowsThisRound == _numRowsPerQuery) && (numUniqueKeysThisRound <= 1)) { String msg = "Seeding stuck at infinte loop for source : " + sourceInfo.getEventView() + ", numRowsThisRound :" + numRowsThisRound + ", _numRowsPerQuery :" + _numRowsPerQuery + ", numUniqueKeys :" + numUniqueKeysThisRound + ", lastChunkKey :" + lastRoundKeyTxn; LOG.error(msg); throw new DatabusException(msg); } else if (null != endKeyTxn) { if (endKeyTxn.compareKey(lastKeyTxn) < 0) { LOG.info( "Seeding stopped for source :" + sourceInfo.getEventView() + ", as it has completed seeding upto the endSrckey :" + endKeyTxn + ", numRowsThisRound :" + numRowsThisRound + ", _numRowsPerQuery :" + _numRowsPerQuery + ", numUniqueKeys :" + numUniqueKeysThisRound + " , Current SrcKey :" + lastKeyTxn); done = true; } } if (currRowId > 0 && (!first || done)) { currRowId--; // Since next time, we will read the last seen record again } LOG.info("about to call end events with currRowId = " + currRowId); first = false; _bootstrapSeedWriter.endEvents(currRowId, timestamp, null); isException = false; } catch (SQLException ex) { LOG.error("Got SQLException for source (" + sourceInfo + ")", ex); _bootstrapSeedWriter.rollbackEvents(); numRetry++; isException = true; if (numRetry >= retryMax) { throw new DatabusException( "Error: Reached max retries for reading/processing bootstrap", ex); } } finally { DBHelper.close(rs); rs = null; } } } catch (DatabusException ex) { isException = true; throw ex; } finally { DBHelper.close(rs, pstmt, conn); keyTxnWriter.close(); rs = null; _rate.suspend(); if (!isException) { dedupeKeyTxnFile(_keyTxnFilesMap.get(srcName), keyType); } } long timeEnd = System.currentTimeMillis(); long elapsedMin = (timeEnd - timeStart) / (MILLISEC_TO_MIN); LOG.info( "Processed " + numRowsFetched + " rows of Source: " + sourceInfo.getSourceName() + " in " + elapsedMin + " minutes"); return new EventReaderSummary( sourceInfo.getSourceId(), sourceInfo.getSourceName(), -1, numRowsFetched, totalEventSize, (timeEnd - timeStart), totProcessTime, 0, 0, 0); }
public long compareTxn(PrimaryKeyTxn txn) { return this.txn - txn.getTxn(); }
public void copyFrom(PrimaryKeyTxn entry) { keyType = entry.getKeyType(); key = entry.getKey(); keyStr = entry.getKeyStr(); txn = entry.getTxn(); }