FreeOnePlus opened a new pull request, #68429:
URL: https://github.com/apache/doris/pull/68429

   # [fix](storage) Preserve pending publish retries for unfinished MoW writes
   
   ### What problem does this PR solve?
   
   Related issue: #62057. This PR does **not** claim to reproduce or close that 
issue's specific empty-success case.
   
   **Draft / validation status:** source changes and tests are implemented, but 
a full BE build and runtime validation have **not** completed. Do not merge or 
deploy based on the auxiliary workflow's green status: it records the build 
attempt and publishes the branch even when the attempt cannot complete.
   
   #### Problem Summary
   
   In the non-cloud MoW write path, a replica can receive `PUBLISH_VERSION` 
while its local transaction is still PREPARED and its rowset has not been 
committed. The existing null-rowset path reports the tablet as failed, but does 
not retain this request for local asynchronous recovery.
   
   Separately, `_process_async_publish()` removes an entry and its durable 
pending marker immediately after submitting work to the tablet publish pool. 
Submission may fail, and the worker may return without publishing because local 
transaction state is unavailable, migration locking fails, or publishing fails. 
In these cases this local recovery path has already discarded its retry intent; 
other reporting, re-publishing or repair mechanisms may still recover the 
replica.
   
   This change preserves a bounded local retry opportunity. It is a recovery 
fix, not a claim that Delete Bitmap computation is faster, that a 3.x-to-4.x 
regression has been proven, or that all query slowdowns are resolved.
   
   #### Changes
   
   - Retain the requested version when normal publish encounters a PREPARED MoW 
tablet with a null local rowset. Continue reporting the original tablet 
failure; do not fabricate success or change FE quorum handling.
   - Keep pending requests and their existing durable markers while an attempt 
is queued or running. Remove the marker and then the in-memory request only 
after the target version is confirmed present. Preserve the existing 
bounded-backlog pruning policy, including a warning for pruned entries.
   - Track one asynchronous attempt per tablet at a time. Record 
submission/execution results using release/acquire completion publication and 
retry completed failures with a one-second monotonic backoff instead of 
re-submitting every producer tick.
   - Add an asynchronous-path readiness getter requiring a committed, non-null 
rowset and, for MoW, installed Delete Bitmap context. This avoids using the 
interval between `commit_txn()` and `set_txn_related_delete_bitmap()` as 
publish readiness. It does not refactor normal commit into a new atomic 
protocol.
   - Preserve binlog-first migration/rowset-update lock order; recheck the 
target version and its immediate predecessor before asynchronous publish, and 
reject shutdown tablets.
   - Propagate pending-marker persistence and pool-submission errors instead of 
silently discarding them.
   - Keep failed requests retryable **without indefinitely fencing Clone**: 
`get_pending_publish_min_version()` excludes completed failed attempts from 
Clone's repair ceiling. Queued/running attempts remain fenced. No FE repair 
scheduler policy is changed.
   
   #### Tests added (not yet executed)
   
   Eleven `AsyncPublishRecoveryTest` cases cover:
   
   1. Missing transaction retention.
   2. Prepared-to-committed retry.
   3. Incomplete MoW context.
   4. Duplicate queued registration.
   5. Pool rejection.
   6. Predecessor ordering.
   7. Durable-marker replay after a failed attempt.
   8. Already-published idempotency.
   9. Publish-before-local-commit registration.
   10. Aborted transaction rejection.
   11. Failed-attempt/Clone-ceiling coexistence.
   
   One additional `TxnManagerTest` covers committed rowset/MoW readiness and 
Tablet UID mismatch. The existing async-publish storage-engine unit test is 
adapted to retained-intent semantics.
   
   A three-replica Docker fault-injection regression delays one replica's local 
commit, injects asynchronous failures, and then checks that it catches up 
without an additional write or replica cloning. It uses no production data.
   
   The marker-replay unit case exercises the recovery interface; it is **not** 
a real process-restart test. Full restart, Clone concurrency, row-binlog and 
non-empty update workloads remain validation requirements.
   
   #### Validation performed
   
   Passed on the isolated fork workflow:
   
   - Repository `build-support/clang-format.sh`, clang-format **16.0.6**, and 
changed-file dry-run checks.
   - `git diff --check`.
   - `build-support/check-build-hygiene.sh`: header layering/reach, 
extern-template pairing, unity-skip coverage.
   
   Attempted with JDK 17:
   
   ```bash
   bash run-be-ut.sh --run \
     
--filter='AsyncPublishRecoveryTest.*:StorageEngineTest.TestAsyncPublish:TxnManagerTest.PublishableInfo*'
 -j 2
   ```
   
   The hosted-runner attempt was bounded to 150 seconds and exited **124 while 
initializing third-party submodules**, before tests executed. This is not 
evidence of a source compilation failure or of a successful build. Full BE 
compilation, ASAN/TSAN, clang-tidy, Docker regression and comparative 
performance replay are unverified.
   
   Auxiliary logs/artifacts:
   https://github.com/FreeOnePlus/doris/actions/runs/35825091270
   
   The auxiliary workflow and encoded patches are on a separate diagnostics 
branch and are **not included** in this PR.
   
   #### Source-review checkpoints and remaining gates
   
   | Checkpoint | Current conclusion |
   |---|---|
   | Scope | Local non-cloud async-publish recovery only; no performance 
improvement numbers claimed. |
   | Concurrency | Producer owns request/attempt transitions under 
`_async_publish_lock`; worker result uses release/acquire completion. Stress 
testing remains pending. |
   | Lock order | Existing binlog-first migration and rowset-update ordering 
preserved. Pending-marker I/O is serialized under the async lock; contention 
must be measured. |
   | Lifecycle | Requests retain an attempt until completion; the worker owns a 
separate shared pointer. Shutdown, replacement and real-restart integration 
tests remain pending. |
   | Correctness | Existing publish helper/quorum/version checks retained, with 
readiness and predecessor guards. Full runtime correctness remains unverified. |
   | Errors | Pool submission and marker persistence failures are retained or 
propagated. True failure is not reported as publish success. |
   | Recovery/Clone | Completed failed attempts do not cap Clone's repair 
range; a dedicated unit test is added, while live Clone concurrency still needs 
testing. |
   | Compatibility | No new wire/storage format or public configuration. This 
is based on master; a 4.0.8 backport has not been produced. |
   | Parallel paths | Normal publish receives a narrow prepared-rowset handoff; 
its commit registration protocol is not otherwise refactored. Cloud behavior is 
out of scope. |
   | Observability | Retry and bounded-pruning logs identify tablet/version; 
additional operational metrics may be desirable after runtime review. |
   | Tests/results | Twelve new BE unit cases and one Docker regression added; 
no fabricated `.out` or passing-runtime claim. |
   
   Before marking ready for review, validate repeated requests, normal-vs-async 
publish races, cancellation, restart, Clone/replacement, attached row-binlog 
failures, and non-empty MoW updates. Measure replica catch-up time, actual 
Clone bytes, pending backlog, write throughput and uncached query latency under 
comparable load.
   
   This PR does not optimize Delete Bitmap algorithms, change the all-writers 
Close barrier, disable repair, or change Compaction scheduling.
   
   ### Release note
   
   Retain pending local publish requests across unfinished MoW writes and 
transient asynchronous failures so eligible replicas can retry publishing local 
rowsets without losing the retry intent. Failed local attempts do not 
indefinitely prevent necessary replica repair.
   
   ### Check List (For Author)
   
   - Test
       - [ ] Regression test — added; execution pending
       - [ ] Unit Test — added; full build and execution pending
       - [x] Manual test — formatting, diff and build-hygiene checks only, 
documented above
       - [ ] No need to test or manual test
   - Behavior changed:
       - [ ] No.
       - [x] Yes. Pending requests survive queued/running and failed attempts; 
completed failures are retried with backoff and excluded from Clone's 
pending-version ceiling.
   - Does this need documentation?
       - [x] No. No new public configuration or wire/storage format.
       - [ ] Yes.
   
   ### Check List (For Reviewer who merge this PR)
   
   - [ ] Confirm the release note
   - [ ] Confirm test cases and actual test results
   - [ ] Confirm document
   - [ ] Add branch pick label only after backport validation
   


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