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

Siyao Meng updated HDDS-16143:
------------------------------
    Attachment: HDDS-16143.001.patch

> SCM leader transfer flush can split a delete transaction apply and persist a 
> summary undercount
> -----------------------------------------------------------------------------------------------
>
>                 Key: HDDS-16143
>                 URL: https://issues.apache.org/jira/browse/HDDS-16143
>             Project: Apache Ozone
>          Issue Type: Bug
>            Reporter: Siyao Meng
>            Priority: Major
>         Attachments: HDDS-16143.001.patch
>
>
> When SCM leadership changes, {{SCMStateMachine.notifyLeaderChanged}} calls 
> {{transactionBuffer.flush()}} unconditionally. If that flush interposes in 
> the middle of a delete-transaction apply, it can persist the transaction rows 
> without the matching summary update, and the subsequent leader-side 
> reconstruction reads the resulting durable summary undercount into the 
> in-memory summary, baking in a permanent undercount that survives restart.
> h3. Steps to reproduce
> # A delete-transaction apply is in progress. 
> {{DeletedBlockLogStateManagerImpl.addTransactionsToDB}} buffers the 
> transaction rows first and then buffers the updated summary as a separate 
> {{addToBuffer}} call.
> # An SCM leader transfer fires and {{SCMStateMachine.notifyLeaderChanged}} 
> calls {{transactionBuffer.flush()}} between the row buffering and the summary 
> buffering.
> # The flush persists the rows with the stale (pre-update) summary, so the 
> durable summary is now lower than the durable row count.
> # {{onBecomeLeader}} then runs {{initDataDistributionData}}, which reloads 
> the in-memory summary from that undercounted durable value rather than 
> recomputing it from the rows.
> The reconstructed in-memory summary is permanently short; the next durable 
> write re-persists the undercount, so it survives further leader transfers and 
> restart.
> h3. Root cause
> {{addTransactionsToDB}} performs the row mutation and the summary mutation as 
> two separate buffer operations, so they are not atomic with respect to a 
> flush. The leader-transfer path uses the unguarded 
> {{transactionBuffer.flush()}} in {{notifyLeaderChanged}} (not the 
> {{flushIfNeeded}} variant that skips when an apply is in progress), so a 
> flush can split an in-progress apply. {{onBecomeLeader}} then reconstructs 
> the in-memory summary from the split durable value via 
> {{initDataDistributionData}}, converting a transient durable inconsistency 
> into a permanent in-memory one.
> h3. Impact
> The deleted-block transaction summary is observability only. It is surfaced 
> by the SCM client protocol {{getDeletedBlockSummary}}, {{ozone admin scm}}, 
> Recon, and JMX metrics, and does not affect deletion correctness. The 
> consequence is a persistent, operator visible summary undercount that 
> survives leader transfer and restart. There is no data loss and no premature 
> deletion.
> h3. Relation to HDDS-14572, HDDS-15065
> HDDS-14572 added the leader-transfer summary reconstruction 
> ({{onBecomeLeader}} to {{initDataDistributionData}}) that this bug relies on 
> to make the undercount permanent. HDDS-15065 added the guarded 
> {{flushIfNeeded}} path (which skips flushing while an apply is in progress) 
> but did not guard the {{flush()}} in {{notifyLeaderChanged}}. Neither reports 
> or fixes this split-then-reconstruct undercount.
> h3. Suggested fix
> Make the row-and-summary durable mutation atomic with respect to flush 
> (buffer both under the same guarded section), or guard the leader-transfer 
> {{flush()}} the same way {{flushIfNeeded}} is guarded so it cannot split an 
> in-progress apply, or have {{initDataDistributionData}} recompute the summary 
> from the durable rows rather than trusting a possibly-split persisted summary 
> value.



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