示例#1
0
  /** 正常退出时,数据恢复,所有内存数据都已经刷盘 */
  public void recoverNormally() {
    boolean checkCRCOnRecover =
        this.defaultMessageStore.getMessageStoreConfig().isCheckCRCOnRecover();
    final List<MapedFile> mapedFiles = this.mapedFileQueue.getMapedFiles();
    if (!mapedFiles.isEmpty()) {
      // 从倒数第三个文件开始恢复
      int index = mapedFiles.size() - 3;
      if (index < 0) index = 0;

      MapedFile mapedFile = mapedFiles.get(index);
      ByteBuffer byteBuffer = mapedFile.sliceByteBuffer();
      long processOffset = mapedFile.getFileFromOffset();
      long mapedFileOffset = 0;
      while (true) {
        DispatchRequest dispatchRequest =
            this.checkMessageAndReturnSize(byteBuffer, checkCRCOnRecover);
        int size = dispatchRequest.getMsgSize();
        // 正常数据
        if (size > 0) {
          mapedFileOffset += size;
        }
        // 文件中间读到错误
        else if (size == -1) {
          log.info("recover physics file end, " + mapedFile.getFileName());
          break;
        }
        // 走到文件末尾,切换至下一个文件
        // 由于返回0代表是遇到了最后的空洞,这个可以不计入truncate offset中
        else if (size == 0) {
          index++;
          if (index >= mapedFiles.size()) {
            // 当前条件分支不可能发生
            log.info(
                "recover last 3 physics file over, last maped file " + mapedFile.getFileName());
            break;
          } else {
            mapedFile = mapedFiles.get(index);
            byteBuffer = mapedFile.sliceByteBuffer();
            processOffset = mapedFile.getFileFromOffset();
            mapedFileOffset = 0;
            log.info("recover next physics file, " + mapedFile.getFileName());
          }
        }
      }

      processOffset += mapedFileOffset;
      this.mapedFileQueue.setCommittedWhere(processOffset);
      this.mapedFileQueue.truncateDirtyFiles(processOffset);
    }
  }
示例#2
0
  public void recoverAbnormally() {
    // 根据最小时间戳来恢复
    boolean checkCRCOnRecover =
        this.defaultMessageStore.getMessageStoreConfig().isCheckCRCOnRecover();
    final List<MapedFile> mapedFiles = this.mapedFileQueue.getMapedFiles();
    if (!mapedFiles.isEmpty()) {
      // 寻找从哪个文件开始恢复
      int index = mapedFiles.size() - 1;
      MapedFile mapedFile = null;
      for (; index >= 0; index--) {
        mapedFile = mapedFiles.get(index);
        if (this.isMapedFileMatchedRecover(mapedFile)) {
          log.info("recover from this maped file " + mapedFile.getFileName());
          break;
        }
      }

      if (index < 0) {
        index = 0;
        mapedFile = mapedFiles.get(index);
      }

      ByteBuffer byteBuffer = mapedFile.sliceByteBuffer();
      long processOffset = mapedFile.getFileFromOffset();
      long mapedFileOffset = 0;
      while (true) {
        DispatchRequest dispatchRequest =
            this.checkMessageAndReturnSize(byteBuffer, checkCRCOnRecover);
        int size = dispatchRequest.getMsgSize();
        // 正常数据
        if (size > 0) {
          mapedFileOffset += size;
          this.defaultMessageStore.putDispatchRequest(dispatchRequest);
        }
        // 文件中间读到错误
        else if (size == -1) {
          log.info("recover physics file end, " + mapedFile.getFileName());
          break;
        }
        // 走到文件末尾,切换至下一个文件
        // 由于返回0代表是遇到了最后的空洞,这个可以不计入truncate offset中
        else if (size == 0) {
          index++;
          if (index >= mapedFiles.size()) {
            // 当前条件分支正常情况下不应该发生
            log.info("recover physics file over, last maped file " + mapedFile.getFileName());
            break;
          } else {
            mapedFile = mapedFiles.get(index);
            byteBuffer = mapedFile.sliceByteBuffer();
            processOffset = mapedFile.getFileFromOffset();
            mapedFileOffset = 0;
            log.info("recover next physics file, " + mapedFile.getFileName());
          }
        }
      }

      processOffset += mapedFileOffset;
      this.mapedFileQueue.setCommittedWhere(processOffset);
      this.mapedFileQueue.truncateDirtyFiles(processOffset);

      // 清除ConsumeQueue的多余数据
      this.defaultMessageStore.truncateDirtyLogicFiles(processOffset);
    }
    // 物理文件都被删除情况下
    else {
      this.mapedFileQueue.setCommittedWhere(0);
      this.defaultMessageStore.destroyLogics();
    }
  }