[ 
https://issues.apache.org/jira/browse/HDDS-16175?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Chi-Hsuan Huang updated HDDS-16175:
-----------------------------------
    Affects Version/s: 2.1.0
                       2.1.1
                       2.2.0

> usedNamespace is charged on every hsync re-commit of the same key
> -----------------------------------------------------------------
>
>                 Key: HDDS-16175
>                 URL: https://issues.apache.org/jira/browse/HDDS-16175
>             Project: Apache Ozone
>          Issue Type: Bug
>          Components: OM
>    Affects Versions: 2.1.0, 2.2.0, 2.1.1
>            Reporter: Chi-Hsuan Huang
>            Priority: Major
>
> ### Problem
> A bucket's {{usedNamespace}} is charged once per key commit but refunded only 
> once per key.
> Every hsync re-commit of the same key by the same client charges the counter 
> again without
> ever adding a key, so a file that is hsync'd N times consumes N+1 namespace 
> units while
> holding one name. Deleting the key refunds 1. The residue is permanent: after 
> every key in
> the bucket has been deleted, {{usedNamespace}} stays at a non-zero value and 
> never returns
> to 0. It permanently consumes the bucket's namespace quota, so
> {{OMKeyRequest.checkBucketQuotaInNamespace}} eventually rejects writes on a 
> bucket that
> holds fewer keys than its quota allows. {{ozone sh bucket info}} and the 
> Recon quota bar
> read the same persisted counter.
> This affects any hsync workload, HBase WALs in particular, on both OBS and 
> FSO buckets.
> ### Root cause
> {{c351de9914}} (HDDS-13756, "Introduce Bucket Snapshot Used Bytes and 
> SnapshotUsedNamespace
> in BucketInfo") hoisted {{incrUsedNamespace(1L)}} out of the {{else}} branch 
> and placed it
> after the whole if/else chain:
>     } else {
>       checkBucketQuotaInNamespace(omBucketInfo, 1L);
>       checkBucketQuotaInBytes(omMetadataManager, omBucketInfo, 
> correctedSpace);
> -     omBucketInfo.incrUsedNamespace(1L);
>     }
> -
> +   omBucketInfo.incrUsedNamespace(1L);
> Every commit now increments the counter, including the {{isSameHsyncKey}} 
> branch at
> {{OMKeyCommitRequest.java:324}}, which handles a re-commit of a key the same 
> client already
> hsync'd. That branch previously did not touch namespace, and that was 
> deliberate:
> {{df4df20371}} (HDDS-7965, "Quota needs to be updated correctly for Hsync") 
> introduced it
> precisely to settle only the byte delta for an hsync re-commit:
>     -      if (keyToDelete != null && !omBucketInfo.getIsVersionEnabled()) {
>     +      if (keyToDelete != null && isHSync) {
>     +        correctedSpace -= keyToDelete.getReplicatedSize();
>     +        checkBucketQuotaInBytes(omMetadataManager, omBucketInfo, 
> correctedSpace);
>     +      } else if (keyToDelete != null && 
> !omBucketInfo.getIsVersionEnabled()) {
> ({{d7e5b3a3fd}}, HDDS-10770, later narrowed the condition from {{isHSync}} to
> {{isSameHsyncKey}}; the intent was unchanged.) HDDS-13756 therefore reverts 
> HDDS-7965 for
> the namespace counter while leaving its byte handling in place.
> The refund side is unchanged: {{OMKeyDeleteRequest.java:169}} refunds a flat
> {{decrUsedNamespace(1L, ...)}} per key, and the neighbouring line 168 
> releases bytes via
> {{sumBlockLengths}}. Bytes are therefore symmetric while namespace is not.
> Both commit paths carry the hoisted increment:
> * {{OMKeyCommitRequest.java:375}}
> * {{OMKeyCommitRequestWithFSO.java:307}}
> ### Expected semantics
> Every other surface treats {{usedNamespace}} as a count of keys:
> * {{a58d3f5a00}} (HDDS-4277) introduced the counter with the commit body "add
>   namespaceQuotaUsage and update it when create and delete key in a bucket".
> * {{hadoop-hdds/docs/content/feature/Quota.md:57}}: "When bucket namespace 
> quota is enabled,
>   the total number of keys under the bucket, cannot exceed the bucket 
> namespace quota", and
>   "Namespace quota is a number that represents how many unique names can be 
> used".
> * All six refund sites ({{OMKeyDeleteRequest}}, {{OMKeyDeleteRequestWithFSO}},
>   {{OMKeysDeleteRequest}}, {{OMDirectoriesPurgeRequestWithFSO}}, 
> {{OMKeyPurgeRequest}}, and
>   the overwrite branch of {{OMKeyCommitRequest}}) refund one unit per key.
> * {{OzoneRpcClientTests.java:1921}}: "Test create a file twice will not 
> increase
>   usedNamespace twice".
> No commit message, javadoc, document or test in the repository states that 
> re-committing a
> key should consume an additional namespace unit.
> ### Fix
> Charge {{incrUsedNamespace(1L)}} only on the paths that actually add a key, 
> i.e. move it
> back inside the branches rather than after the chain, in both 
> {{OMKeyCommitRequest}} and
> {{OMKeyCommitRequestWithFSO}}.
> The regression shipped unnoticed because no test asserts {{usedNamespace}} 
> across repeated
> hsync commits; the quota tests around this code assert {{getUsedBytes()}} 
> only. A fix should
> add an assertion that hsync'ing a key N times leaves {{usedNamespace}} at 1, 
> and that the
> counter returns to 0 after the key is deleted.
> ### Note on bucket versioning
> The same hoisted increment also charges once per version on a 
> versioning-enabled bucket,
> because {{ff351025bc}} (HDDS-6709) routed versioned overwrites into the 
> {{else}} branch that
> carries the increment. That half is out of scope here: per the discussion on 
> HDDS-16127,
> there is no code path that exercises bucket versioning today, and HDDS-15728 
> object
> versioning stores each version as a separate {{OmKeyInfo}}. This issue is 
> limited to the
> hsync path, which is exercised by ordinary non-versioned buckets.
> The stale comment at {{OMKeyCommitRequest.java:322-323}}, "if keyToDelete 
> isn't null,
> usedNamespace needn't check and increase" (introduced by {{9055a11216}}, 
> HDDS-6556), still
> contradicts the code and can be corrected alongside the fix.
> ### Notes
> Found while scoping HDDS-16127. Pinned source commit 4766aa8609. Analysis 
> assisted by AI
> tooling (Claude Code, Opus 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