/** 正常退出时,数据恢复,所有内存数据都已经刷盘 */ 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); } }
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(); } }