private boolean checkNeedDbForRowMode(Pipeline pipeline, EventData eventData) { // 获取数据表信息 DataMedia dataMedia = ConfigHelper.findDataMedia(pipeline, eventData.getTableId()); DbDialect dbDialect = dbDialectFactory.getDbDialect(pipeline.getId(), (DbMediaSource) dataMedia.getSource()); Table table = dbDialect.findTable(eventData.getSchemaName(), eventData.getTableName()); if (table.getColumnCount() == eventData.getColumns().size() + eventData.getKeys().size()) { return false; } else { return true; } }
private List<String> select( DbDialect dbDialect, String schemaName, String tableName, TableData keyTableData, TableData columnTableData) throws InterruptedException { String selectSql = dbDialect .getSqlTemplate() .getSelectSql( schemaName, tableName, keyTableData.columnNames, columnTableData.columnNames); Exception exception = null; for (int i = 0; i < retryTimes; i++) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); // 退出 } try { List<List<String>> result = dbDialect .getJdbcTemplate() .query( selectSql, keyTableData.columnValues, keyTableData.columnTypes, new RowDataMapper(columnTableData.columnTypes)); if (CollectionUtils.isEmpty(result)) { logger.warn( "the mediaName = {}.{} not has rowdate in db \n {}", new Object[] {schemaName, tableName, dumpEventData(eventData, selectSql)}); return null; } else { return result.get(0); } } catch (Exception e) { exception = e; logger.warn("retry [" + (i + 1) + "] failed", e); } } throw new RuntimeException( "db extract failed , data:\n " + dumpEventData(eventData, selectSql), exception); }
public void run() { try { MDC.put(OtterConstants.splitPipelineLogFileKey, String.valueOf(pipeline.getId())); Thread.currentThread() .setName(String.format(WORKER_NAME_FORMAT, pipeline.getId(), pipeline.getName())); // 获取数据表信息 DataMedia dataMedia = ConfigHelper.findDataMedia(pipeline, eventData.getTableId()); DbDialect dbDialect = dbDialectFactory.getDbDialect(pipeline.getId(), (DbMediaSource) dataMedia.getSource()); Table table = dbDialect.findTable(eventData.getSchemaName(), eventData.getTableName()); TableData keyTableData = buildTableData(table, eventData.getKeys()); // oracle类型特殊处理下 if (dbDialect instanceof OracleDialect) { keyTableData.columnTypes = getOraclePkTypes(table, keyTableData.columnNames); } boolean needAll = pipeline.getParameters().getSyncMode().isRow() || (eventData.getSyncMode() != null && eventData.getSyncMode().isRow()); // 增加一种case, 针对oracle erosa有时侯结果记录只有主键,没有变更字段,需要做一次反查,获取所有字段 needAll |= CollectionUtils.isEmpty(eventData.getUpdatedColumns()) && dataMedia.getSource().getType().isOracle(); List<DataMediaPair> mediaParis = ConfigHelper.findDataMediaPairByMediaId(pipeline, dataMedia.getId()); List<String> viewColumnNames = buildMaxColumnsFromColumnPairs(mediaParis, eventData.getKeys()); // TODO 后续版本测试下 // if (needAll) { // boolean needDb = checkNeedDbForRowMode(table, // viewColumnNames, eventData); // if (needAll && !needDb) {// 不需要进行反查 // item.setFilter(false); // return; // } // } // modified by ljh at 2012-11-04 // 反查数据时只反查带update=true标识的数据,因为update=false的记录可能只是进行filter需要用到的数据,不需要反查 TableData columnTableData = buildTableData(table, eventData.getUpdatedColumns(), needAll, viewColumnNames); if (columnTableData.columnNames.length == 0) { // 全主键,不需要进行反查 } else { List<String> newColumnValues = select( dbDialect, eventData.getSchemaName(), eventData.getTableName(), keyTableData, columnTableData); if (newColumnValues == null) { // miss from db // 设置为filter=true,可能存在丢数据的风险. // 比如针对源库发生主备切换,otter反查的是备库,查询不到对应的记录 // item.setFilter(true); // 针对需要自定义反查数据库的,允许忽略 // a. 自由门触发的数据,不存在时可以忽略 // b. 回环补救算法触发的数据,不存在时可以忽略 boolean needFilter = eventData.isRemedy() || pipeline.getParameters().getSkipNoRow(); item.setFilter(needFilter); // 判断主键是否有变更,如果变更了,就原样返回item int index = 0; for (EventColumn oldKey : eventData.getOldKeys()) { if (!oldKey.equals(eventData.getKeys().get(index))) { item.setFilter(false); break; } } } else { // 构造反查的返回结果 List<EventColumn> newEventColumns = new ArrayList<EventColumn>(); for (int i = 0; i < newColumnValues.size(); i++) { EventColumn column = new EventColumn(); column.setIndex(columnTableData.indexs[i]); column.setColumnName(columnTableData.columnNames[i]); column.setColumnType(columnTableData.columnTypes[i]); column.setNull(newColumnValues.get(i) == null); column.setColumnValue(newColumnValues.get(i)); column.setUpdate(true); newEventColumns.add(column); } // 处理下columns中不在反查字段内的字段列表 for (EventColumn column : eventData.getColumns()) { boolean override = false; for (EventColumn newEventColumn : newEventColumns) { if (StringUtils.equalsIgnoreCase( newEventColumn.getColumnName(), column.getColumnName())) { override = true; break; } } if (!override) { // 针对newcolumns不存在的记录进行添加 newEventColumns.add(column); } } Collections.sort(newEventColumns, new EventColumnIndexComparable()); // 重新排个序 eventData.setColumns(newEventColumns); } } } catch (InterruptedException e) { // ignore } finally { Thread.currentThread().setName(WORKER_NAME); MDC.remove(OtterConstants.splitPipelineLogFileKey); } }