Yukang-Lian opened a new pull request, #69950:
URL: https://github.com/apache/doris/pull/69950

   ### What problem does this PR solve?
   
   Issue Number: None
   
   Related PR: #64574
   
   Problem Summary:
   
   `is_tablet_encrypted()`, which serves `/api/check_tablet_encryption`, holds 
the tablet `_meta_lock` read lock in `traverse_rowsets()` and takes it again 
through `tablet_schema()` in the visitor. Since #64574 `_meta_lock` is the 
writer-preferring `BthreadSharedMutex`, so a writer that arrives between the 
two reads deadlocks with the check:
   
   - The check holds the first read lock and waits for the second, which is 
blocked by the pending writer.
   - The writer waits for the first read lock to be released.
   
   The window is wide because each rowset's files are read from remote storage 
under the lock, and compaction and rowset sync take the write lock often. Once 
this happens the tablet stays stuck until the BE restarts:
   
   - The HTTP request never returns.
   - The compaction keeps renewing its lease but never finishes, so other BEs 
get `JOB_TABLET_BUSY` for this tablet.
   - Every later reader of this tablet's meta blocks behind the pending writer, 
including the periodic tablet sync.
   
   We hit this in a regression test: the compaction stopped right after its 
rowset sync, and the check timed out on all 10 retries over about 2h47m.
   
   This PR reads the schema once before the check and checks a snapshot of the 
rowsets (`get_snapshot_rowset()`) with no lock held, which also stops holding 
the meta lock across remote file reads. It adds a test-only sync point so a 
unit test can observe the lock at that moment.
   
   ### Release note
   
   Fix a deadlock between the tablet encryption check API and tablet meta 
writers such as compaction, which could block a tablet until the BE restarts.
   
   ### Check List (For Author)
   
   - Test <!-- At least one of them must be included. -->
       - [ ] Regression test
       - [x] Unit Test
       - [x] Manual test (add detailed scripts or steps below)
       - [ ] No need to test or manual test. Explain why:
           - [ ] This is a refactor/code format and no logic has been changed.
           - [ ] Previous test can cover this change.
           - [ ] No code files have been changed.
           - [ ] Other reason <!-- Add your reason?  -->
   
       Unit test 
`CheckEncryptionActionTest.RowsetsAreCheckedWithoutHoldingMetaLock` checks that 
`_meta_lock` is free while a rowset is being checked. It fails on the code 
before this PR and passes with it.
   
       Manual test: a temporary unit test (not committed) started a writer from 
inside the rowset check, then waited for the check to return. On the code 
before this PR the check had not returned after 20s. With this PR it returned 
at once.
   
   - Behavior changed:
       - [x] No.
       - [ ] Yes. <!-- Explain the behavior change -->
   
   - Does this need documentation?
       - [x] No.
       - [ ] Yes. <!-- Add document PR link here. eg: 
https://github.com/apache/doris-website/pull/1214 -->
   
   ### Check List (For Reviewer who merge this PR)
   
   - [ ] Confirm the release note
   - [ ] Confirm test cases
   - [ ] Confirm document
   - [ ] Add branch pick label <!-- Add branch pick label that this PR should 
merge into -->
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


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