You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ignite.apache.org by "rpuch (via GitHub)" <gi...@apache.org> on 2023/01/26 14:28:48 UTC

[GitHub] [ignite-3] rpuch commented on a diff in pull request #1578: IGNITE-18603 Clear all storages of a partition if one of the storages did not have time to rebalance

rpuch commented on code in PR #1578:
URL: https://github.com/apache/ignite-3/pull/1578#discussion_r1087752337


##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/MvTableStorage.java:
##########
@@ -257,4 +258,27 @@ CompletableFuture<Void> finishRebalancePartition(
             long lastAppliedTerm,
             RaftGroupConfiguration raftGroupConfig
     );
+
+    /**
+     * Clears a partition and all associated indices.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) of a {@link MvPartitionStorage multi-version partition storage} and its
+     *     associated indexes ({@link HashIndexStorage} and {@link SortedIndexStorage}) and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) of a multi-version partition storage and its indexes

Review Comment:
   ```suggestion
        *     <li>Does not allow operations on a multi-version partition storage and its indexes to be performed (exceptions will be thrown)
   ```



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/MvTableStorage.java:
##########
@@ -257,4 +258,27 @@ CompletableFuture<Void> finishRebalancePartition(
             long lastAppliedTerm,
             RaftGroupConfiguration raftGroupConfig
     );
+
+    /**
+     * Clears a partition and all associated indices.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) of a {@link MvPartitionStorage multi-version partition storage} and its
+     *     associated indexes ({@link HashIndexStorage} and {@link SortedIndexStorage}) and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) of a multi-version partition storage and its indexes
+     *     until the cleaning is completed;</li>
+     *     <li>Clear a multi-version partition storage and its indexes;</li>
+     *     <li>Sets {@link MvPartitionStorage#lastAppliedIndex()}, {@link MvPartitionStorage#lastAppliedTerm()},
+     *     {@link MvPartitionStorage#persistedIndex()} to {@code 0} and {@link MvPartitionStorage#committedGroupConfiguration()} to
+     *     {@code null};</li>
+     *     <li>Once cleanup a multi-version partition storage and its indexes is complete (success or error), allows to perform all with a
+     *     multi-version partition storage and its indexes.</li>
+     * </ul>
+     *
+     * @return Future of cleanup a multi-version partition storage and its indexes.

Review Comment:
   ```suggestion
        * @return Future of cleanup of a multi-version partition storage and its indexes.
   ```



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/MvTableStorage.java:
##########
@@ -257,4 +258,27 @@ CompletableFuture<Void> finishRebalancePartition(
             long lastAppliedTerm,
             RaftGroupConfiguration raftGroupConfig
     );
+
+    /**
+     * Clears a partition and all associated indices.

Review Comment:
   Let's also add to this sentence information that, as a result, the partition remains alive and functioning. This is clear from the items that follow, but people often tend to overlook the details buried in lengthy explanations, and this seems to be a very important property of the method (for instance, this immediately answers a question like 'how is this method different from `destroyPartition()`?)



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/util/StorageUtils.java:
##########
@@ -109,4 +156,8 @@ private static String createUnexpectedStorageStateErrorMessage(StorageState stat
     private static String createStorageClosedErrorMessage(String storageInfo) {
         return IgniteStringFormatter.format("Storage is already closed: [{}]", storageInfo);
     }
+
+    private static String createStorageInProcessOfCleanupErrorMessage(String storageInfo) {
+        return IgniteStringFormatter.format("Storage in the process of cleanup: [{}]", storageInfo);

Review Comment:
   ```suggestion
           return IgniteStringFormatter.format("Storage is in the process of cleanup: [{}]", storageInfo);
   ```



##########
modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/AbstractMvTableStorageTest.java:
##########
@@ -593,19 +592,15 @@ public void testDestroyTableStorage() throws Exception {
         assertThat(tableStorage.destroy(), willCompleteSuccessfully());
     }
 
-    /**
-     * Checks that if we restart the storages after a crash in the middle of a rebalance, the storages will be empty.
-     */
     @Test
-    public void testRestartStoragesAfterFailDuringRebalance() {
-        assumeFalse(tableStorage.isVolatile());
-
+    public void testRestartStoragesOnMiddleOfRebalance() {

Review Comment:
   ```suggestion
       public void testRestartStoragesInTheMiddleOfRebalance() {
   ```



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/util/StorageUtils.java:
##########
@@ -36,6 +36,49 @@ public static String createMissingMvPartitionErrorMessage(int partitionId) {
         return "Partition ID " + partitionId + " does not exist";
     }
 
+    /**
+     * Throws an exception if the state of the storage is not {@link StorageState#RUNNABLE}.
+     *
+     * @param state Storage state.
+     * @param storageInfoSupplier Storage information supplier, for example in the format "table=user, partitionId=1".
+     * @throws StorageClosedException If the storage is closed.
+     * @throws StorageRebalanceException If storage is in the process of rebalancing.
+     * @throws StorageException For other {@link StorageState}.
+     */
+    public static void throwExceptionIfStorageNotInRunnableState(StorageState state, Supplier<String> storageInfoSupplier) {
+        if (state != StorageState.RUNNABLE) {
+            throwExceptionDependingOnStorageState(state, storageInfoSupplier.get());
+        }
+    }
+
+    /**
+     * Throws an exception if the state of the storage is not {@link StorageState#RUNNABLE} OR {@link StorageState#REBALANCE}.
+     *
+     * @param state Storage state.
+     * @param storageInfoSupplier Storage information supplier, for example in the format "table=user, partitionId=1".
+     * @throws StorageClosedException If the storage is closed.
+     * @throws StorageException For other {@link StorageState}.
+     */
+    public static void throwExceptionIfStorageNotInRunnableOrRebalancedState(StorageState state, Supplier<String> storageInfoSupplier) {

Review Comment:
   ```suggestion
       public static void throwExceptionIfStorageNotInRunnableOrRebalanceState(StorageState state, Supplier<String> storageInfoSupplier) {
   ```



##########
modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/RocksDbMvPartitionStorage.java:
##########
@@ -1543,4 +1550,29 @@ private void saveRaftGroupConfigurationOnRebalance(WriteBatch writeBatch, RaftGr
 
         this.lastGroupConfig = config;
     }
+
+    /**
+     * Prepares the storage for cleanup.
+     *
+     * <p>After cleanup (successful or not), method {@link #finishCleanup()} must be called.
+     */
+    void startCleanup(WriteBatch writeBatch) throws RocksDBException {
+        if (!state.compareAndSet(StorageState.RUNNABLE, StorageState.CLEANUP)) {
+            throwExceptionDependingOnStorageState(state.get(), createStorageInfo());
+        }
+
+        // Changed storage states and expect all storage operations to stop soon.
+        busyLock.block();
+
+        clearStorage(writeBatch, 0, 0);
+    }
+
+    /**
+     * Finishes cleanup up the storage.
+     */
+    void finishCleanup() {
+        if (state.compareAndSet(StorageState.CLEANUP, StorageState.RUNNABLE)) {
+            busyLock.unblock();

Review Comment:
   I wonder why in AbstractPageMemoryMvPartitionStorage` `unblock()` is called in `startCleanup()`, but here it is called in `finishCleanup()`?



##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/storage/state/TxStateStorage.java:
##########
@@ -194,4 +194,21 @@ public interface TxStateStorage extends ManuallyCloseable {
      *      has failed.
      */
     CompletableFuture<Void> finishRebalance(long lastAppliedIndex, long lastAppliedTerm);
+
+    /**
+     * Clears transaction state storage.

Review Comment:
   It would be nice to mention that the storage is fully operational after this finishes.



##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/storage/state/TxStateStorage.java:
##########
@@ -194,4 +194,21 @@ public interface TxStateStorage extends ManuallyCloseable {
      *      has failed.
      */
     CompletableFuture<Void> finishRebalance(long lastAppliedIndex, long lastAppliedTerm);
+
+    /**
+     * Clears transaction state storage.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) with storage and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) with the storage until the cleaning is completed;</li>
+     *     <li>Clear storage;</li>

Review Comment:
   ```suggestion
        *     <li>Clears storage;</li>
   ```



##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/AbstractPageMemoryMvPartitionStorage.java:
##########
@@ -561,7 +572,7 @@ private static byte[] rowBytes(@Nullable TableRow row) {
         assert rowId.partitionId() == partitionId : rowId;
 
         return busy(() -> {
-            throwExceptionIfStorageInProgressOfRebalance(state.get(), this::createStorageInfo);
+            throwExceptionIfStorageNotInRunnableState(state.get(), this::createStorageInfo);

Review Comment:
   addWrite and commitWrite are allowed in `RunnableOrRebalance`, but abortWrite is only allowed in Runnable state. Is this ok?



##########
modules/storage-api/src/testFixtures/java/org/apache/ignite/internal/storage/AbstractMvTableStorageTest.java:
##########
@@ -632,10 +627,76 @@ public void testRestartStoragesAfterFailDuringRebalance() {
         hashIndexStorage = tableStorage.getOrCreateHashIndex(PARTITION_ID, hashIdx.id());
         sortedIndexStorage = tableStorage.getOrCreateSortedIndex(PARTITION_ID, sortedIdx.id());
 
-        // Let's check the repositories: they should be empty.
-        checkForMissingRows(mvPartitionStorage, hashIndexStorage, sortedIndexStorage, rows);
+        if (tableStorage.isVolatile()) {
+            // Let's check the repositories: they should be empty.
+            checkForMissingRows(mvPartitionStorage, hashIndexStorage, sortedIndexStorage, rows);
+
+            checkLastApplied(mvPartitionStorage, 0, 0, 0);
+        } else {
+            checkForPresenceRows(mvPartitionStorage, hashIndexStorage, sortedIndexStorage, rows);
+
+            checkLastApplied(mvPartitionStorage, REBALANCE_IN_PROGRESS, REBALANCE_IN_PROGRESS, REBALANCE_IN_PROGRESS);
+        }
+    }
+
+    @Test
+    void testClear() {
+        assertThrows(IllegalArgumentException.class, () -> tableStorage.clearPartition(getPartitionIdOutOfRange()));
+
+        // Let's check that there will be an error for a non-existent partition.
+        assertThrows(StorageException.class, () -> tableStorage.clearPartition(PARTITION_ID));
+
+        MvPartitionStorage mvPartitionStorage = tableStorage.getOrCreateMvPartition(PARTITION_ID);
+        HashIndexStorage hashIndexStorage = tableStorage.getOrCreateHashIndex(PARTITION_ID, hashIdx.id());
+        SortedIndexStorage sortedIndexStorage = tableStorage.getOrCreateSortedIndex(PARTITION_ID, sortedIdx.id());
+
+        // Let's check the cleanup for an empty partition.
+        assertThat(tableStorage.clearPartition(PARTITION_ID), willCompleteSuccessfully());
+
+        checkLastApplied(mvPartitionStorage, 0, 0, 0);
+        assertNull(mvPartitionStorage.committedGroupConfiguration());
+
+        // Let's fill the storages and clean them.
+        List<IgniteTuple3<RowId, TableRow, HybridTimestamp>> rows = List.of(
+                new IgniteTuple3<>(new RowId(PARTITION_ID), tableRow(new TestKey(0, "0"), new TestValue(0, "0")), clock.now()),
+                new IgniteTuple3<>(new RowId(PARTITION_ID), tableRow(new TestKey(1, "1"), new TestValue(1, "1")), clock.now())
+        );
+
+        RaftGroupConfiguration raftGroupConfig = createRandomRaftGroupConfiguration();
+
+        fillStorages(mvPartitionStorage, hashIndexStorage, sortedIndexStorage, rows);
+
+        mvPartitionStorage.runConsistently(() -> {
+            mvPartitionStorage.lastApplied(100, 500);
+
+            mvPartitionStorage.committedGroupConfiguration(raftGroupConfig);
+
+            return null;
+        });
+
+        // Let's clear the storages and check them out.
+        assertThat(tableStorage.clearPartition(PARTITION_ID), willCompleteSuccessfully());
 
         checkLastApplied(mvPartitionStorage, 0, 0, 0);
+        assertNull(mvPartitionStorage.committedGroupConfiguration());
+
+        checkForMissingRows(mvPartitionStorage, hashIndexStorage, sortedIndexStorage, rows);
+    }
+

Review Comment:
   Do we tests that make sure that:
   
   1. Operations active to the moment we initiate a cleanup still finish successfully
   2. No operations are possible while the cleanup is under way
   3. The storage is fully operable after it has been cleaned up (all operations function correctly)
   
   ?



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/util/StorageState.java:
##########
@@ -28,5 +28,8 @@ public enum StorageState {
     CLOSED,
 
     /** Storage is in the process of rebalancing. */
-    REBALANCE
+    REBALANCE,
+
+    /** Storage in the process of cleanup. */

Review Comment:
   ```suggestion
       /** Storage is in the process of cleanup. */
   ```



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/MvTableStorage.java:
##########
@@ -257,4 +258,27 @@ CompletableFuture<Void> finishRebalancePartition(
             long lastAppliedTerm,
             RaftGroupConfiguration raftGroupConfig
     );
+
+    /**
+     * Clears a partition and all associated indices.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) of a {@link MvPartitionStorage multi-version partition storage} and its
+     *     associated indexes ({@link HashIndexStorage} and {@link SortedIndexStorage}) and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) of a multi-version partition storage and its indexes
+     *     until the cleaning is completed;</li>
+     *     <li>Clear a multi-version partition storage and its indexes;</li>
+     *     <li>Sets {@link MvPartitionStorage#lastAppliedIndex()}, {@link MvPartitionStorage#lastAppliedTerm()},
+     *     {@link MvPartitionStorage#persistedIndex()} to {@code 0} and {@link MvPartitionStorage#committedGroupConfiguration()} to
+     *     {@code null};</li>
+     *     <li>Once cleanup a multi-version partition storage and its indexes is complete (success or error), allows to perform all with a
+     *     multi-version partition storage and its indexes.</li>
+     * </ul>
+     *
+     * @return Future of cleanup a multi-version partition storage and its indexes.
+     * @throws IllegalArgumentException If Partition ID is out of bounds.
+     * @throws StorageClosedException If a multi-version partition storage and its indexes is closed or destroyed.
+     * @throws StorageRebalanceException If a multi-version partition storage and its indexes in process of rebalance.
+     * @throws StorageException If a multi-version partition storage and its indexes in progress of cleanup or if failed.

Review Comment:
   ```suggestion
        * @throws StorageException If a multi-version partition storage and its indexes are in progress of cleanup or failed for another reason.
   ```



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/MvTableStorage.java:
##########
@@ -257,4 +258,27 @@ CompletableFuture<Void> finishRebalancePartition(
             long lastAppliedTerm,
             RaftGroupConfiguration raftGroupConfig
     );
+
+    /**
+     * Clears a partition and all associated indices.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) of a {@link MvPartitionStorage multi-version partition storage} and its
+     *     associated indexes ({@link HashIndexStorage} and {@link SortedIndexStorage}) and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) of a multi-version partition storage and its indexes
+     *     until the cleaning is completed;</li>
+     *     <li>Clear a multi-version partition storage and its indexes;</li>
+     *     <li>Sets {@link MvPartitionStorage#lastAppliedIndex()}, {@link MvPartitionStorage#lastAppliedTerm()},
+     *     {@link MvPartitionStorage#persistedIndex()} to {@code 0} and {@link MvPartitionStorage#committedGroupConfiguration()} to
+     *     {@code null};</li>
+     *     <li>Once cleanup a multi-version partition storage and its indexes is complete (success or error), allows to perform all with a
+     *     multi-version partition storage and its indexes.</li>
+     * </ul>
+     *
+     * @return Future of cleanup a multi-version partition storage and its indexes.
+     * @throws IllegalArgumentException If Partition ID is out of bounds.
+     * @throws StorageClosedException If a multi-version partition storage and its indexes is closed or destroyed.
+     * @throws StorageRebalanceException If a multi-version partition storage and its indexes in process of rebalance.

Review Comment:
   ```suggestion
        * @throws StorageRebalanceException If a multi-version partition storage and its indexes are in process of rebalance.
   ```



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/MvTableStorage.java:
##########
@@ -257,4 +258,27 @@ CompletableFuture<Void> finishRebalancePartition(
             long lastAppliedTerm,
             RaftGroupConfiguration raftGroupConfig
     );
+
+    /**
+     * Clears a partition and all associated indices.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) of a {@link MvPartitionStorage multi-version partition storage} and its
+     *     associated indexes ({@link HashIndexStorage} and {@link SortedIndexStorage}) and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) of a multi-version partition storage and its indexes
+     *     until the cleaning is completed;</li>
+     *     <li>Clear a multi-version partition storage and its indexes;</li>

Review Comment:
   ```suggestion
        *     <li>Clears a multi-version partition storage and its indexes;</li>
   ```



##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/AbstractPageMemoryTableStorage.java:
##########
@@ -412,6 +412,35 @@ public CompletableFuture<Void> finishRebalancePartition(
         });
     }
 
+    @Override
+    public CompletableFuture<Void> clearPartition(int partitionId) {
+        return inBusyLock(busyLock, () -> {
+            AbstractPageMemoryMvPartitionStorage mvPartitionStorage = getMvPartitionBusy(partitionId);
+
+            if (mvPartitionStorage == null) {
+                throw new StorageException(createMissingMvPartitionErrorMessage(partitionId));
+            }
+
+            try {
+                mvPartitionStorage.startCleanup();
+
+                return clearStorageAndUpdateDataStructures(mvPartitionStorage)
+                        .whenComplete((unused, throwable) -> mvPartitionStorage.finishCleanup());
+            } catch (StorageException e) {
+                mvPartitionStorage.finishCleanup();
+
+                throw e;
+            } catch (Exception e) {

Review Comment:
   If an `Error` is thrown, we don't finish the cleanup. Is this intentional?



##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/engine/MvTableStorage.java:
##########
@@ -257,4 +258,27 @@ CompletableFuture<Void> finishRebalancePartition(
             long lastAppliedTerm,
             RaftGroupConfiguration raftGroupConfig
     );
+
+    /**
+     * Clears a partition and all associated indices.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) of a {@link MvPartitionStorage multi-version partition storage} and its
+     *     associated indexes ({@link HashIndexStorage} and {@link SortedIndexStorage}) and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) of a multi-version partition storage and its indexes
+     *     until the cleaning is completed;</li>
+     *     <li>Clear a multi-version partition storage and its indexes;</li>
+     *     <li>Sets {@link MvPartitionStorage#lastAppliedIndex()}, {@link MvPartitionStorage#lastAppliedTerm()},
+     *     {@link MvPartitionStorage#persistedIndex()} to {@code 0} and {@link MvPartitionStorage#committedGroupConfiguration()} to
+     *     {@code null};</li>
+     *     <li>Once cleanup a multi-version partition storage and its indexes is complete (success or error), allows to perform all with a
+     *     multi-version partition storage and its indexes.</li>
+     * </ul>
+     *
+     * @return Future of cleanup a multi-version partition storage and its indexes.
+     * @throws IllegalArgumentException If Partition ID is out of bounds.
+     * @throws StorageClosedException If a multi-version partition storage and its indexes is closed or destroyed.

Review Comment:
   ```suggestion
        * @throws StorageClosedException If a multi-version partition storage and its indexes is already closed or destroyed.
   ```



##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/storage/state/rocksdb/TxStateRocksDbStorage.java:
##########
@@ -644,6 +674,9 @@ private enum StorageState {
         CLOSED,
 
         /** Storage is in the process of being rebalanced. */
-        REBALANCE
+        REBALANCE,
+
+        /** Storage in the process of cleanup. */

Review Comment:
   ```suggestion
           /** Storage is in the process of cleanup. */
   ```



##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/storage/state/rocksdb/TxStateRocksDbStorage.java:
##########
@@ -562,6 +536,57 @@ public CompletableFuture<Void> finishRebalance(long lastAppliedIndex, long lastA
         return completedFuture(null);
     }
 
+    @Override
+    public CompletableFuture<Void> clear() {
+        if (!state.compareAndSet(StorageState.RUNNABLE, StorageState.CLEANUP)) {
+            throwExceptionDependingOnStorageState();
+        }
+
+        // We changed the status and wait for all current operations (together with cursors) with the storage to be completed.
+        busyLock.block();
+
+        try (WriteBatch writeBatch = new WriteBatch()) {
+            clearStorageData(writeBatch);
+
+            updateLastAppliedAndPersistentIndex(writeBatch, 0, 0);
+
+            db.write(writeOptions, writeBatch);
+
+            return completedFuture(null);
+        } catch (RocksDBException e) {
+            throw new IgniteInternalException(
+                    TX_STATE_STORAGE_ERR,
+                    IgniteStringFormatter.format("Failed to cleanup storage: [{}]", createStorageInfo()),
+                    e
+            );
+        } finally {
+            state.set(StorageState.RUNNABLE);
+
+            busyLock.unblock();
+        }
+    }
+
+    private void clearStorageData(WriteBatch writeBatch) throws RocksDBException {
+        writeBatch.deleteRange(partitionStartPrefix(), partitionEndPrefix());
+    }
+
+    private void updateLastApplied(WriteBatch writeBatch, long lastAppliedIndex, long lastAppliedTerm) throws RocksDBException {
+        writeBatch.put(lastAppliedIndexAndTermKey, indexAndTermToBytes(lastAppliedIndex, lastAppliedTerm));
+
+        this.lastAppliedIndex = lastAppliedIndex;
+        this.lastAppliedTerm = lastAppliedTerm;
+    }
+
+    private void updateLastAppliedAndPersistentIndex(

Review Comment:
   ```suggestion
       private void updateLastAppliedAndPersistedIndex(
   ```



##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/storage/state/TxStateStorage.java:
##########
@@ -194,4 +194,21 @@ public interface TxStateStorage extends ManuallyCloseable {
      *      has failed.
      */
     CompletableFuture<Void> finishRebalance(long lastAppliedIndex, long lastAppliedTerm);
+
+    /**
+     * Clears transaction state storage.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) with storage and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) with the storage until the cleaning is completed;</li>
+     *     <li>Clear storage;</li>
+     *     <li>Sets the {@link #lastAppliedIndex()}, {@link #lastAppliedTerm()} and {@link #persistedIndex()} to {@code 0};</li>
+     *     <li>Once the storage cleanup is complete (success or error), allows to perform all storage operations.</li>
+     * </ul>
+     *
+     * @return Future of transaction state storage cleanup.
+     * @throws IgniteInternalException with {@link Transactions#TX_STATE_STORAGE_STOPPED_ERR} if the storage is closed or destroyed.
+     * @throws IgniteInternalException with {@link Transactions#TX_STATE_STORAGE_REBALANCE_ERR} if the storage in process of rebalance.
+     * @throws IgniteInternalException with {@link Transactions#TX_STATE_STORAGE_ERR} if the storage in progress of cleanup or if failed.

Review Comment:
   ```suggestion
        * @throws IgniteInternalException with {@link Transactions#TX_STATE_STORAGE_ERR} if the storage is in progress of cleanup or failed for another reason.
   ```



##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/storage/state/TxStateStorage.java:
##########
@@ -194,4 +194,21 @@ public interface TxStateStorage extends ManuallyCloseable {
      *      has failed.
      */
     CompletableFuture<Void> finishRebalance(long lastAppliedIndex, long lastAppliedTerm);
+
+    /**
+     * Clears transaction state storage.
+     * <ul>
+     *     <li>Cancels all current operations (including cursors) with storage and waits for their completion;</li>
+     *     <li>Does not allow operations to be performed (exceptions will be thrown) with the storage until the cleaning is completed;</li>
+     *     <li>Clear storage;</li>
+     *     <li>Sets the {@link #lastAppliedIndex()}, {@link #lastAppliedTerm()} and {@link #persistedIndex()} to {@code 0};</li>
+     *     <li>Once the storage cleanup is complete (success or error), allows to perform all storage operations.</li>
+     * </ul>
+     *
+     * @return Future of transaction state storage cleanup.
+     * @throws IgniteInternalException with {@link Transactions#TX_STATE_STORAGE_STOPPED_ERR} if the storage is closed or destroyed.
+     * @throws IgniteInternalException with {@link Transactions#TX_STATE_STORAGE_REBALANCE_ERR} if the storage in process of rebalance.

Review Comment:
   ```suggestion
        * @throws IgniteInternalException with {@link Transactions#TX_STATE_STORAGE_REBALANCE_ERR} if the storage is in process of rebalance.
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@ignite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org