Siyao Meng created HDDS-17009:
---------------------------------

             Summary: Container create retried on another volume after an 
IOException leaves the full container size reserved on the abandoned volume
                 Key: HDDS-17009
                 URL: https://issues.apache.org/jira/browse/HDDS-17009
             Project: Apache Ozone
          Issue Type: Bug
            Reporter: Siyao Meng
         Attachments: MC-5-release-reservation-on-create-retry.patch, 
TestBugMC5CreateRetryReservationLeak.java

h3. Mechanism
{{VolumeChoosingPolicy.chooseVolume}} reserves the container size on the volume 
it returns ({{RoundRobinVolumeChoosingPolicy}}, 
{{CapacityVolumeChoosingPolicy}}, since HDDS-12810). When 
{{KeyValueContainer.create}} then gets an {{IOException}} from 
{{createContainerMetaData}} on that volume, it deletes the container directory, 
removes the volume from the candidate list and tries the next volume, without 
releasing the reservation. The next attempt overwrites 
{{containerData.volume}}, so the release in 
{{KeyValueHandler.handleCreateContainer}} (only on failure, through 
{{releaseCommitSpace}}) can only reach the last volume tried. Nothing 
recomputes {{HddsVolume.committedBytes}} while the datanode runs.

h3. Trigger
A datanode with two or more volumes. A CreateContainer whose first chosen 
volume fails to create the container directories or DB with an {{IOException}} 
(EIO, ENOSPC, EACCES), and the retry on another volume succeeds. If every 
volume fails in the directory or DB creation, all but the last one leak.

h3. Impact
Each failed attempt keeps the full container size (5 GB by default) committed 
on a volume that holds no such container, until the datanode restarts. After 
the fault clears, the volume keeps refusing new containers and imports it has 
room for ({{AvailableSpaceFilter}} subtracts the committed bytes), and the 
inflated committed value is reported in the storage report. No data is lost.

h3. Reproduction
[^TestBugMC5CreateRetryReservationLeak.java] 
({{hadoop-hdds/container-service}}) uses two real volumes with a fixed 1000 MB 
capacity, 600 MB containers, the real {{RoundRobinVolumeChoosingPolicy}} and 
{{KeyValueHandler}}. The fault is a real filesystem error: the first volume's 
cluster directory is read only. Container 1 ends on the second volume and the 
first keeps {{committed=629145600}}. After the fault is cleared and container 1 
is closed, two creates that fit one per volume give {{SUCCESS}} and 
{{DISK_OUT_OF_SPACE}}, with the first volume empty. A passing test means the 
defect is present. Not exercised: a real EIO or ENOSPC, and the SCM side.

h3. Patch
[^MC-5-release-reservation-on-create-retry.patch], against 
cce1ca28944886218132f01c0e271c1fd0700078. It also applies to master at 
2536fe9cbc3. Released 2.1.0 and later have the same code.

The retry branch calls {{containerData.releaseCommitSpace()}} before it moves 
to the next volume. At that point the container data still points at the failed 
volume and nothing is written, so exactly the reserved size is released; the 
flag it clears makes the handler's later release a no op, so nothing is 
released twice. Covered by the existing 
{{TestKeyValueContainer.testNextVolumeTriedOnWriteFailure}}, whose mocked 
policy now reserves like the real ones and which now checks the committed bytes 
of both volumes, and by the new 
{{testReservationReleasedWhenCreateFailsOnAllVolumes}}. Both fail without the 
change (5368709120 committed on a failed volume). With it the container and 
handler suites pass (485 tests) and checkstyle is clean.

Found by TLA+ model checking and code review of the datanode volume and 
per-disk RocksDB lifecycle paths under HDDS-15926, on commit 
cce1ca28944886218132f01c0e271c1fd0700078. Checked against HDDS issues and 
apache/ozone pull requests for duplicates before filing. The attached patch is 
a proposal for review. Generated with Specula (Claude Opus 5.5).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to