Exemple #1
0
  public long getMinOffset() {
    MapedFile mapedFile = this.mapedFileQueue.getFirstMapedFileOnLock();
    if (mapedFile != null) {
      if (mapedFile.isAvailable()) {
        return mapedFile.getFileFromOffset();
      } else {
        return this.rollNextFile(mapedFile.getFileFromOffset());
      }
    }

    return -1;
  }
Exemple #2
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);
    }
  }
Exemple #3
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();
    }
  }
  @Test
  public void test_findMapedFileByOffset() {
    final String fixedMsg = "abcd";
    System.out.println("================================================================");
    AllocateMapedFileService allocateMapedFileService = new AllocateMapedFileService();
    allocateMapedFileService.start();
    MapedFileQueue mapedFileQueue =
        new MapedFileQueue("./unit_test_store/b/", 1024, allocateMapedFileService);

    for (int i = 0; i < 1024; i++) {
      MapedFile mapedFile = mapedFileQueue.getLastMapedFile();
      assertTrue(mapedFile != null);
      boolean result = mapedFile.appendMessage(fixedMsg.getBytes());
      // System.out.println("appendMessage " + bytes);
      assertTrue(result);
    }

    MapedFile mapedFile = mapedFileQueue.findMapedFileByOffset(0);
    assertTrue(mapedFile != null);
    assertEquals(mapedFile.getFileFromOffset(), 0);
    System.out.println(mapedFile.getFileFromOffset());

    mapedFile = mapedFileQueue.findMapedFileByOffset(100);
    assertTrue(mapedFile != null);
    assertEquals(mapedFile.getFileFromOffset(), 0);
    System.out.println(mapedFile.getFileFromOffset());

    mapedFile = mapedFileQueue.findMapedFileByOffset(1024);
    assertTrue(mapedFile != null);
    assertEquals(mapedFile.getFileFromOffset(), 1024);
    System.out.println(mapedFile.getFileFromOffset());

    mapedFile = mapedFileQueue.findMapedFileByOffset(1024 + 100);
    assertTrue(mapedFile != null);
    assertEquals(mapedFile.getFileFromOffset(), 1024);
    System.out.println(mapedFile.getFileFromOffset());

    mapedFile = mapedFileQueue.findMapedFileByOffset(1024 * 2);
    assertTrue(mapedFile != null);
    assertEquals(mapedFile.getFileFromOffset(), 1024 * 2);
    System.out.println(mapedFile.getFileFromOffset());

    mapedFile = mapedFileQueue.findMapedFileByOffset(1024 * 2 + 100);
    assertTrue(mapedFile != null);
    assertEquals(mapedFile.getFileFromOffset(), 1024 * 2);
    System.out.println(mapedFile.getFileFromOffset());

    mapedFile = mapedFileQueue.findMapedFileByOffset(1024 * 4);
    assertTrue(mapedFile == null);

    mapedFile = mapedFileQueue.findMapedFileByOffset(1024 * 4 + 100);
    assertTrue(mapedFile == null);

    mapedFileQueue.shutdown(1000);
    mapedFileQueue.destroy();
    allocateMapedFileService.shutdown();
    System.out.println("MapedFileQueue.findMapedFileByOffset() OK");
  }