You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hbase.apache.org by "mazhengxuan (Jira)" <ji...@apache.org> on 2026/08/17 18:11:00 UTC

[jira] [Commented] (HBASE-30332) ProtobufUtil.toResult() silently discards QueryMetrics for empty (row-not-found) results

    [ https://issues.apache.org/jira/browse/HBASE-30332?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18105331#comment-18105331 ] 

mazhengxuan commented on HBASE-30332:
-------------------------------------

I investigated this issue and would like to work on it.

The server already computes and attaches QueryMetrics to the Result in RSRpcServices#get, including when the requested row does not exist. The metrics are lost later because both ProtobufUtil.toResult(Result, boolean) and
ProtobufUtil.toResultNoData(Result) return cached empty protobuf instances before copying Result#getMetrics.

My proposed fix is to:

1. Keep using the cached empty protobuf instances for empty results without metrics, but build an empty protobuf carrying QueryMetrics when metrics are present. This will cover both the inline-cell and cell-block response paths.

2. Update the corresponding protobuf-to-Result conversion paths to create a per-response empty Result when metrics are present. Reusing the shared EMPTY_RESULT and then calling setMetrics on it could otherwise leak metrics into subsequent metrics-disabled empty results.

3. Add focused regression tests covering both serialization paths and both deserialization paths. The tests will verify that blockBytesScanned survives an empty-result round trip and that a subsequent empty result without metrics still has getMetrics() == null.

No protobuf schema change should be necessary because the Result message already contains the optional metrics field.

> ProtobufUtil.toResult() silently discards QueryMetrics for empty (row-not-found) results
> ----------------------------------------------------------------------------------------
>
>                 Key: HBASE-30332
>                 URL: https://issues.apache.org/jira/browse/HBASE-30332
>             Project: HBase
>          Issue Type: Bug
>          Components: Client, IPC/RPC
>            Reporter: Abinayaa Tharmmarajhan
>            Priority: Minor
>
> When a {{Get}} is issued with {{setQueryMetricsEnabled(true)}} and the requested row does not exist, the {{{}QueryMetrics{}}}(specifically {{{}blockBytesScanned{}}}) are silently dropped during protobuf serialization. The client always receives {{result.getMetrics() == null}} for missing rows, even though the server did read blocks (bloom filters, index blocks) to determine the row is absent and correctly computed the byte count.
>  
> *Steps to Reproduce*
>  # Issue a {{Get}} against a row that does not exist, with {{get.setQueryMetricsEnabled(true)}}
>  # Check {{result.getMetrics()}} on the returned {{Result}}
>  # Observe {{null}} despite blocks having been read server-side
>  
> *Expected Behavior*
> {{result.getMetrics().getBlockBytesScanned()}} returns the number of bytes read to determine the row is absent — the same as it would for a row that exists.
>  
> *Root cause*
> Based on some analysis, in {{ProtobufUtil.toResult(Result result, boolean encodeTags)}} and {{{}ProtobufUtil.toResultNoData(Result result){}}}, when a result has no cells, the code takes an early-return path that returns one of six pre-built static proto constants. This could be causing the QueryMetrics to be dropped for such cases. 



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