Siyao Meng created HDDS-16144:
---------------------------------

             Summary: SCM may purge a delete transaction before a newly copied 
replica has acknowledged it
                 Key: HDDS-16144
                 URL: https://issues.apache.org/jira/browse/HDDS-16144
             Project: Apache Ozone
          Issue Type: Bug
            Reporter: Siyao Meng


{{SCMDeletedBlockTransactionStatusManager.commitTransactions}} decides whether 
a delete transaction can be purged from the deleted-block log using a replica 
set snapshot taken earlier in the same call, and then removes the transaction 
from the durable log without re-checking membership. A replica that is copied 
to a new datanode after the snapshot but before the purge, and that never 
received or acknowledged the deletion, can therefore keep the blocks forever: 
SCM has already purged the transaction and never re-issues it.

h3. Steps to reproduce

# A delete transaction for a container is outstanding and has been sent to the 
current replicas.
# {{commitTransactions}} captures the replica set via 
{{containerManager.getContainerReplicas(containerId)}} and evaluates 
{{canPurge}} from that snapshot (all snapshot replicas have committed).
# Around the same time, replication manager copies the container to a new 
datanode. The copy carries the container RocksDB, so the new replica inherits 
whatever delete state the source had; if the source had not yet physically 
deleted the blocks, the new replica holds them with no pending SCM delete 
transaction.
# {{commitTransactions}} proceeds to purge: 
{{transactionToDNsCommitMap.remove(txID)}} and 
{{removeTransactions(txIDsToBeDeleted)}} delete the row from the durable 
deleted-block log. There is no re-validation of the current replica set at 
removal time.

The transaction is gone from the SCM log and is never recreated. SCM does not 
reconcile a replica reported {{deleteTransactionId}} against the container and 
does not re-issue delete transactions from it (the field is effectively unused 
in server-scm), so the lagging replica is never told to delete.

h3. Root cause

The purge decision and the durable removal are not guarded by a consistent, 
current replica set. {{commitTransactions}} evaluates {{canPurge}} against a 
replica snapshot and then {{removeTransactions}} removes the row with no 
membership re-check. SCM has no catch-up mechanism that compares a replica's 
{{deleteTransactionId}} to the container's and re-issues missed deletions; once 
the transaction is purged it is never re-delivered.

h3. Impact

A container replica that becomes current in the snapshot-to-purge window 
without having applied the deletion permanently retains the deleted blocks, an 
undeleted-block space leak on that datanode with no automatic recovery at the 
SCM level. The leak is confined to datanode capacity; there is no client 
visible data corruption. The SCM-level premature purge reproduces 
deterministically; demonstrating the physical on-disk leak requires a 
mini-cluster with adversarial copy-versus-delete timing, so this is filed as an 
environment-limited (not fully cluster-reproduced) finding.

h3. Relation to HDDS-11498

HDDS-11498 improved deletion efficiency and the "send to all replicas or not at 
all" handling in {{commitTransactions}}, but does not address a replica that 
becomes current after the ACK-set snapshot is taken and before the durable 
removal. No filed issue reports this stale-snapshot premature purge.

h3. Suggested fix

Re-validate the current replica set immediately before removing a transaction 
from the durable log (recompute {{canPurge}} against a fresh 
{{getContainerReplicas}} under the same critical section), or reconcile a newly 
added replica's {{deleteTransactionId}} against the container and re-issue any 
missed delete transactions before allowing the purge, so a replica that has not 
acknowledged the deletion cannot be orphaned.



--
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