@Test public void performHardDeleteAndRecoveryFailureTest() throws Exception { MockId blobId01 = new MockId("id01"); MockId blobId02 = new MockId("id02"); MockId blobId03 = new MockId("id03"); MockId blobId04 = new MockId("id04"); helper.add(blobId01); helper.add(blobId02); helper.add(blobId03); helper.add(blobId04); helper.delete(blobId03); time.sleep(TimeUnit.DAYS.toMillis(2)); helper.exception = new IOException(StoreException.IO_ERROR_STR); try { index.hardDelete(); index.persistAndAdvanceStartTokenSafeToPersist(); index.hardDelete(); index.hardDelete(); fail("Hard delete should fail due to I/O error"); } catch (StoreException e) { assertEquals("Mismatch in error code", StoreErrorCodes.IOError, e.getErrorCode()); } helper.exception = null; index.hardDelete(); helper.exception = new IOException(StoreException.IO_ERROR_STR); try { index.performHardDeleteRecovery(); fail("Recovery should fail due to I/O error"); } catch (StoreException e) { assertEquals("Mismatch in error code", StoreErrorCodes.IOError, e.getErrorCode()); } }
boolean hardDelete() throws StoreException { if (index.getCurrentEndOffset().compareTo(index.getStartOffset()) > 0) { final Timer.Context context = metrics.hardDeleteTime.time(); try { FindInfo info = index.findDeletedEntriesSince(startToken, scanSizeInBytes, time.seconds() - messageRetentionSeconds); endToken = info.getFindToken(); logger.trace("New range for hard deletes : startToken {}, endToken {} for {}", startToken, info.getFindToken(), dataDir); if (!endToken.equals(startToken)) { if (!info.getMessageEntries().isEmpty()) { if (injectedBeforeHardDeleteSupplier != null) { injectedBeforeHardDeleteSupplier.get(); } performHardDeletes(info.getMessageEntries()); } startToken = endToken; return true; } } catch (StoreException e) { if (e.getErrorCode() != StoreErrorCodes.Store_Shutting_Down) { metrics.hardDeleteExceptionsCount.inc(); } throw e; } finally { context.stop(); } } return false; }
HardDeleter implements Runnable { boolean hardDelete() throws StoreException { if (index.getCurrentEndOffset().compareTo(index.getStartOffset()) > 0) { final Timer.Context context = metrics.hardDeleteTime.time(); try { FindInfo info = index.findDeletedEntriesSince(startToken, scanSizeInBytes, time.seconds() - messageRetentionSeconds); endToken = info.getFindToken(); logger.trace("New range for hard deletes : startToken {}, endToken {} for {}", startToken, info.getFindToken(), dataDir); if (!endToken.equals(startToken)) { if (!info.getMessageEntries().isEmpty()) { if (injectedBeforeHardDeleteSupplier != null) { injectedBeforeHardDeleteSupplier.get(); } performHardDeletes(info.getMessageEntries()); } startToken = endToken; return true; } } catch (StoreException e) { if (e.getErrorCode() != StoreErrorCodes.Store_Shutting_Down) { metrics.hardDeleteExceptionsCount.inc(); } throw e; } finally { context.stop(); } } return false; } }
HardDeleter implements Runnable { boolean hardDelete() throws StoreException { if (index.getCurrentEndOffset().compareTo(index.getStartOffset()) > 0) { final Timer.Context context = metrics.hardDeleteTime.time(); try { FindInfo info = index.findDeletedEntriesSince(startToken, scanSizeInBytes, time.seconds() - messageRetentionSeconds); endToken = info.getFindToken(); logger.trace("New range for hard deletes : startToken {}, endToken {} for {}", startToken, info.getFindToken(), dataDir); if (!endToken.equals(startToken)) { if (!info.getMessageEntries().isEmpty()) { if (injectedBeforeHardDeleteSupplier != null) { injectedBeforeHardDeleteSupplier.get(); } performHardDeletes(info.getMessageEntries()); } startToken = endToken; return true; } } catch (StoreException e) { if (e.getErrorCode() != StoreErrorCodes.Store_Shutting_Down) { metrics.hardDeleteExceptionsCount.inc(); } throw e; } finally { context.stop(); } } return false; } HardDeleter(StoreConfig config, StoreMetrics metrics, String dataDir, Log log, PersistentIndex index,
      MessageStoreHardDelete hardDelete, StoreKeyFactory factory, DiskIOScheduler diskIOScheduler, Time time); }
HardDeleter implements Runnable { boolean hardDelete() throws StoreException { if (index.getCurrentEndOffset().compareTo(index.getStartOffset()) > 0) { final Timer.Context context = metrics.hardDeleteTime.time(); try { FindInfo info = index.findDeletedEntriesSince(startToken, scanSizeInBytes, time.seconds() - messageRetentionSeconds); endToken = info.getFindToken(); logger.trace("New range for hard deletes : startToken {}, endToken {} for {}", startToken, info.getFindToken(), dataDir); if (!endToken.equals(startToken)) { if (!info.getMessageEntries().isEmpty()) { if (injectedBeforeHardDeleteSupplier != null) { injectedBeforeHardDeleteSupplier.get(); } performHardDeletes(info.getMessageEntries()); } startToken = endToken; return true; } } catch (StoreException e) { if (e.getErrorCode() != StoreErrorCodes.Store_Shutting_Down) { metrics.hardDeleteExceptionsCount.inc(); } throw e; } finally { context.stop(); } } return false; } HardDeleter(StoreConfig config, StoreMetrics metrics, String dataDir, Log log, PersistentIndex index,
      MessageStoreHardDelete hardDelete, StoreKeyFactory factory, DiskIOScheduler diskIOScheduler, Time time); @Override void run(); }
HardDeleter implements Runnable { boolean hardDelete() throws StoreException { if (index.getCurrentEndOffset().compareTo(index.getStartOffset()) > 0) { final Timer.Context context = metrics.hardDeleteTime.time(); try { FindInfo info = index.findDeletedEntriesSince(startToken, scanSizeInBytes, time.seconds() - messageRetentionSeconds); endToken = info.getFindToken(); logger.trace("New range for hard deletes : startToken {}, endToken {} for {}", startToken, info.getFindToken(), dataDir); if (!endToken.equals(startToken)) { if (!info.getMessageEntries().isEmpty()) { if (injectedBeforeHardDeleteSupplier != null) { injectedBeforeHardDeleteSupplier.get(); } performHardDeletes(info.getMessageEntries()); } startToken = endToken; return true; } } catch (StoreException e) { if (e.getErrorCode() != StoreErrorCodes.Store_Shutting_Down) { metrics.hardDeleteExceptionsCount.inc(); } throw e; } finally { context.stop(); } } return false; } HardDeleter(StoreConfig config, StoreMetrics metrics, String dataDir, Log log, PersistentIndex index,
      MessageStoreHardDelete hardDelete, StoreKeyFactory factory, DiskIOScheduler diskIOScheduler, Time time); @Override void run(); static final short Cleanup_Token_Version_V0; static final short Cleanup_Token_Version_V1; }