matanper opened a new issue, #70258:
URL: https://github.com/apache/doris/issues/70258

   ### Search before asking
   
   - [x] I had searched in the 
[issues](https://github.com/apache/doris/issues?q=is%3Aissue) and found no 
similar issues.
   
   ### Version
   
   4.1.4. master is the same: `FrontendServiceImpl.createPartition` 
(`fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java:4732-4737`)
 and `FrontendServiceImpl.replacePartition` (`:5056-5061`). Both have done this 
since the `isMaster()` check was added in #24412.
   
   ### What's Wrong?
   
   When `createPartition` or `replacePartition` is called on an FE that is not 
the master, the handler builds a `NOT_MASTER` status but returns the result 
without setting it:
   
   ```java
   TStatus errorStatus = new TStatus(TStatusCode.RUNTIME_ERROR);
   if (!Env.getCurrentEnv().isMaster()) {
       errorStatus.setStatusCode(TStatusCode.NOT_MASTER);
       errorStatus.addToErrorMsgs(NOT_MASTER_ERR_MSG);
       LOG.warn("failed to createPartition: {}", NOT_MASTER_ERR_MSG);
       return result;   // result.status is never set
   }
   ```
   
   `status` is optional in `TCreatePartitionResult` / 
`TReplacePartitionResult`, so the BE receives the default `TStatus`, whose 
`status_code` is `0` (`OK`). In `VRowDistribution::automatic_create_partition` 
(`be/src/exec/sink/vrow_distribution.cpp:148-159`) the BE then takes the 
success path with an empty partition list. When the batched rows are replayed 
(`VTabletWriter::_send_new_partition_batch`, with `_deal_batched = true`), 
`OlapTabletFinder::find_tablets` is called without a missing-rows list. Rows 
that still have no partition are therefore counted as filtered ("no partition 
for this tuple").
   
   The result depends on the load's filter tolerance:
   - With `max_filter_ratio` > 0 (or `strict_mode` off for INSERT), the load 
can succeed while silently dropping every row that needed a new partition.
   - With no tolerance, it fails with a filtered-rows error that hides the real 
cause, `NOT_MASTER`.
   
   The BE sends these RPCs to the master address it learned from heartbeats. So 
this happens when that address is briefly stale, for example during an FE 
master switch, or when the old master restarts as a follower. 
`replacePartition` (INSERT OVERWRITE with auto-detect partitions) has the same 
missing `setStatus`; we have not traced what that path then does with the rows.
   
   ### What You Expected?
   
   A non-master FE should return the `NOT_MASTER` status, so the BE fails the 
request (or retries against the new master) instead of treating it as a 
successful call that created nothing.
   
   ### How to Reproduce?
   
   We found this while reading the code and have not reproduced it by forcing a 
failover. Two ways to see it:
   
   1. Call `FrontendService.createPartition` over thrift on a follower FE. The 
returned `TCreatePartitionResult` has no `status` field set.
   2. On an auto-partition table, run a Stream Load with `max_filter_ratio=1` 
whose rows need a new partition, and switch the FE master while the load runs 
(stop the master FE so a follower takes over before the BEs' next heartbeat). 
The load can finish with those rows counted as filtered.
   
   ### Anything Else?
   
   The fix is one line in each handler: `result.setStatus(errorStatus);` before 
`return result;` in the `!isMaster()` branch. Separately, the BE could treat a 
result with no `status` set as an error rather than reading the default `OK`, 
which would cover any other handler with the same mistake.
   
   ### Are you willing to submit PR?
   
   - [x] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [x] I agree to follow this project's [Code of 
Conduct](https://www.apache.org/foundation/policies/conduct)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to