protected boolean doFilter(Event event) { if (filter != null && event.getEntry().getEntryType() == EntryType.ROWDATA) { String name = getSchemaNameAndTableName(event.getEntry()); boolean need = filter.filter(name); if (!need) { logger.debug( "filter name[{}] entry : {}:{}", name, event.getEntry().getHeader().getLogfileName(), event.getEntry().getHeader().getLogfileOffset()); } return need; } else { return true; } }
private long calculateSize(Event event) { // 直接返回binlog中的事件大小 return event.getEntry().getHeader().getEventLength(); }
private Events<Event> doGet(Position start, int batchSize) throws CanalStoreException { LogPosition startPosition = (LogPosition) start; long current = getSequence.get(); long maxAbleSequence = putSequence.get(); long next = current; long end = current; // 如果startPosition为null,说明是第一次,默认+1处理 if (startPosition == null || !startPosition.getPostion().isIncluded()) { // 第一次订阅之后,需要包含一下start位置,防止丢失第一条记录 next = next + 1; } if (current >= maxAbleSequence) { return new Events<Event>(); } Events<Event> result = new Events<Event>(); List<Event> entrys = result.getEvents(); long memsize = 0; if (batchMode.isItemSize()) { end = (next + batchSize - 1) < maxAbleSequence ? (next + batchSize - 1) : maxAbleSequence; // 提取数据并返回 for (; next <= end; next++) { Event event = entries[getIndex(next)]; if (ddlIsolation && isDdl(event.getEntry().getHeader().getEventType())) { // 如果是ddl隔离,直接返回 if (entrys.size() == 0) { entrys.add(event); // 如果没有DML事件,加入当前的DDL事件 end = next; // 更新end为当前 } else { // 如果之前已经有DML事件,直接返回了,因为不包含当前next这记录,需要回退一个位置 end = next - 1; // next-1一定大于current,不需要判断 } break; } else { entrys.add(event); } } } else { long maxMemSize = batchSize * bufferMemUnit; for (; memsize <= maxMemSize && next <= maxAbleSequence; next++) { // 永远保证可以取出第一条的记录,避免死锁 Event event = entries[getIndex(next)]; if (ddlIsolation && isDdl(event.getEntry().getHeader().getEventType())) { // 如果是ddl隔离,直接返回 if (entrys.size() == 0) { entrys.add(event); // 如果没有DML事件,加入当前的DDL事件 end = next; // 更新end为当前 } else { // 如果之前已经有DML事件,直接返回了,因为不包含当前next这记录,需要回退一个位置 end = next - 1; // next-1一定大于current,不需要判断 } break; } else { entrys.add(event); memsize += calculateSize(event); end = next; // 记录end位点 } } } PositionRange<LogPosition> range = new PositionRange<LogPosition>(); result.setPositionRange(range); range.setStart(CanalEventUtils.createPosition(entrys.get(0))); range.setEnd(CanalEventUtils.createPosition(entrys.get(result.getEvents().size() - 1))); // 记录一下是否存在可以被ack的点 for (int i = entrys.size() - 1; i >= 0; i--) { Event event = entrys.get(i); if (CanalEntry.EntryType.TRANSACTIONBEGIN == event.getEntry().getEntryType() || CanalEntry.EntryType.TRANSACTIONEND == event.getEntry().getEntryType() || isDdl(event.getEntry().getHeader().getEventType())) { // 将事务头/尾设置可被为ack的点 range.setAck(CanalEventUtils.createPosition(event)); break; } } if (getSequence.compareAndSet(current, end)) { getMemSize.addAndGet(memsize); notFull.signal(); return result; } else { return new Events<Event>(); } }