Example #1
0
  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>();
    }
  }