Skip to content

HDDS-15135. Import container to another volume if already exists in selected one#10161

Open
devmadhuu wants to merge 3 commits intoapache:masterfrom
devmadhuu:HDDS-15135
Open

HDDS-15135. Import container to another volume if already exists in selected one#10161
devmadhuu wants to merge 3 commits intoapache:masterfrom
devmadhuu:HDDS-15135

Conversation

@devmadhuu
Copy link
Copy Markdown
Contributor

This change prevents DN replication/import from failing the whole target DN when the volume selected by the volume choosing policy already contains a stale container directory.

Key changes:

  • Retry container creation on another candidate volume when KeyValueContainer#create hits an existing container directory on the selected volume.
  • Add retry-aware import path in ContainerImporter for pull and push replication.
  • Keep retry scoped to CONTAINER_ALREADY_EXISTS; other import failures still fail normally.
  • Handling committed space reservation accounting for both initial and retry-selected volumes.
  • Add unit coverage for stale selected-volume container dirs in create/import paths.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-15135

How was this patch tested?

This patch was tested using some new unit tests and some existing ones:

Tests:

  • Added unit coverage for retrying another candidate volume when the selected volume already has the target container directory.
  • Added unit coverage for retry-aware container import when the initially selected volume has a stale container directory.

… when selected target volume already has same container directory.
@devmadhuu devmadhuu changed the title HDDS-15135. DN replication/reconstruction should retry another volume… HDDS-15135. DN replication/reconstruction should retry another volume when selected target volume already has same container directory. Apr 30, 2026
@adoroszlai adoroszlai changed the title HDDS-15135. DN replication/reconstruction should retry another volume when selected target volume already has same container directory. HDDS-15135. Import container to another volume if already exists in selected one Apr 30, 2026
@devmadhuu devmadhuu marked this pull request as ready for review April 30, 2026 09:14
Copy link
Copy Markdown
Contributor

@ArafatKhan2198 ArafatKhan2198 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving a few comments @devmadhuu please take a look.

}
}

public void importContainerWithVolumeRetry(long containerID, Path tarFilePath,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add JavaDoc to clarify committed-space ownership.

/**
 * Imports a container and retries on alternate volumes only when the selected
 * volume already has the container directory.
 *
 * The caller is responsible for releasing committed bytes on
 * initialTargetVolume. This method releases committed bytes only for
 * retry-selected volumes.
 */

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

doImportContainer(containerID, tarFilePath, targetVolume, compression);
} finally {
importContainerProgress.remove(containerID);
deleteFileQuietely(tarFilePath);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have a utility method for it - FileUtils.deleteQuietly
could we use it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

}

@Test
public void testImportWithVolumeRetrySkipsSelectedVolumeWithContainerDir()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new tests cover the successful retry case, which is good. But I would also add a negative test where every candidate volume already has the stale container directory.

Expected behavior:

Import/create tries all candidate volumes.
It fails with CONTAINER_ALREADY_EXISTS.
Committed bytes are restored on all attempted volumes.
The tarball is deleted.
No container is added to containerSet.

This is important because the PR changes the final error message to “already exists on all candidate volumes”, but currently the main added tests mostly verify the happy retry path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@@ -260,6 +262,43 @@ protected void createContainerMetaData(File containerMetaDataPath,
assertEquals(2, callCount.get());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion - DO you think the test coverage should verify non-retriable failures are not retried

The PR explicitly says retry is scoped only to CONTAINER_ALREADY_EXISTS. That behavior should have a test.

For example, mock controller.importContainer(...) to throw a normal IOException or a StorageContainerException with a different result code. Then verify only the initially selected volume was attempted.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ArafatKhan2198 this comment doesn't hold right in this test class. We do mock controller.importContainer in ContainerImporter#importContainerWithVolumeRetry which belongs to TestContainerImporter class.

@ChenSammi
Copy link
Copy Markdown
Contributor

ChenSammi commented May 6, 2026

Hi @devmadhuu , do we see container replication eventually failed in real case due to this?
I'm not sure if we need this as it will create more same container replicas on single datanode cases, and is current duplicate replica deletion logic ready to handle this? If we are sure the existing container directory is stale, can we just delete it and continue the import?

@devmadhuu
Copy link
Copy Markdown
Contributor Author

Hi @devmadhuu , do we see container replication eventually failed in real case due to this? I'm not sure if we need this as it will create more same container replicas on single datanode cases, and is current duplicate replica deletion logic ready to handle this? If we are sure the existing container directory is stale, can we just delete it and continue the import?

@ChenSammi thanks for your review. This was identified as part of some use case discussed. We don't have good conflict resolution for Ratis or EC when a DN ends up with multiple copies, but we can end up in this situation due to volume failures as well. We need to prioritize moving to a safer state, which means allowing replication to pass. We do not want to end up in a situation where containers are perpetually under-replicated because no target nodes are valid.

Since replication failure is not the only way DNs can end up with duplicate replicas, we should allow replication and just pick a different volume. Better duplicate replica handling on startup may require internal reconciliation within the DN but that can be done later.

cc: @errose28

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants