[Bug] createPartition / replacePartition on a non-master FE return no status, so auto-partition loads filter the rows instead of failing

Aperta Adatta ai principianti
#70,258 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
82/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
cpp, java

Direzione di ricerca

Leggi fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java in corrispondenza di createPartition e replacePartition, quindi esamina i tipi di risultato per confermare come viene restituito lo stato. Imposta lo stato di errore in entrambi i rami in cui il nodo non è master e aggiungi o aggiorna test mirati per queste risposte. Il lavoro è completato quando entrambi i risultati RPC riportano NOT_MASTER se la chiamata viene effettuata su un follower.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Search before asking
  • I had searched in the issues 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:

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?
  • Yes I am willing to submit a PR!
Code of Conduct
Lingua principale
Java
Stelle
16.2k
Fork
4k
Merge medio
1g 17h
PR unite (30g)
660

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di apache/doris

Tutte le issue di apache/doris

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.