Jose Luis López created HBASE-30468:
---------------------------------------

             Summary: TestProcDispatcher.testRetryLimitOnConnClosedErrors still 
flaky: finished SCPs are evicted before the test checks for them
                 Key: HBASE-30468
                 URL: https://issues.apache.org/jira/browse/HBASE-30468
             Project: HBase
          Issue Type: Bug
          Components: test
    Affects Versions: 4.0.0-alpha-1
            Reporter: Jose Luis López


h3. Symptom
After HBASE-30265, {{TestProcDispatcher.testRetryLimitOnConnClosedErrors}} 
still fails intermittently and
passes on the surefire rerun:
{noformat}
org.opentest4j.AssertionFailedError: Waiting timed out after [60,000] msec
        at 
org.apache.hadoop.hbase.util.TestProcDispatcher.testRetryLimitOnConnClosedErrors(TestProcDispatcher.java:141)
{noformat}
Every poll of the first {{waitFor}} logs {{Num of SCPs: 0}}.

h3. Occurrences
HBase Nightly master (all failed once, then passed on rerun):
* [#1501|https://ci-hbase.apache.org/job/HBase%20Nightly/job/master/1501/] 
jdk17-hadoop3 (2026-09-16)
* [#1506|https://ci-hbase.apache.org/job/HBase%20Nightly/job/master/1506/] 
jdk17-hadoop3 (2026-09-25)
* [#1508|https://ci-hbase.apache.org/job/HBase%20Nightly/job/master/1508/] 
jdk17-hadoop3 (2026-10-01)
* [#1509|https://ci-hbase.apache.org/job/HBase%20Nightly/job/master/1509/] 
jdk21-hadoop3 (2026-10-03)
* [#1510|https://ci-hbase.apache.org/job/HBase%20Nightly/job/master/1510/] 
jdk21-hadoop3 (2026-10-07)

PR precommit (Yetus JDK17 Hadoop3 Unit Check on GitHub Actions), on PRs 
unrelated to this test:
3 flaky out of 20 runs that still have artifacts (~15%); 0 of 12 on the 
JDK11/JDK8 branch-2.x checks.
* [run 37446446948|https://github.com/apache/hbase/actions/runs/37446446948] 
(PR #8584, HBASE-30335)
* [run 37489643917|https://github.com/apache/hbase/actions/runs/37489643917] 
(PR #8744, HBASE-30461)
* [run 37475000411|https://github.com/apache/hbase/actions/runs/37475000411] 
(PR #8742, HBASE-30463; branch on an older master, so the line is 143)

h3. Root cause
Error injection works. In every failed attempt the logs show two "Scheduling 
server crash" events and
both ServerCrashProcedures (SCPs) finishing with SUCCESS. What fails is how the 
test detects them.

The test checks {{getMasterProcedureExecutor().getProcedures()}} for a 
{{ServerCrashProcedure}}. That
list holds running procedures plus *retained* completed ones. 
{{ServerCrashProcedure#shouldWaitClientAck}}
returns false, so {{ProcedureExecutor#rootProcedureFinished}} sets its 
client-ack time to 0 and the
next {{CompletedProcedureCleaner}} run (every 30s, 
{{hbase.procedure.cleaner.interval}}) evicts it.
A finished SCP therefore stays visible for only 0-30s, depending on the 
cleaner's phase.

If a cleaner tick falls between the SCPs finishing and the test's next look at 
the procedure list,
the SCPs are gone and the condition can never become true. Two windows were 
observed:
# *Before the first poll.* The test's synchronous {{Admin#move}} calls keep 
retrying with client backoff
("region is currently in transition") while the SCPs run, so the first poll 
comes 0.5-10s after
the SCPs finish. Timelines (last SCP finished -> cleaner tick -> first poll):
#* nightly #1501: 17:03:51.889 -> 17:03:51.892 -> 17:03:52.471
#* nightly #1506: 13:29:00.8 -> 13:29:07.2 -> 13:29:10.98
#* nightly #1508: 17:07:49.6 -> 17:07:50.3 -> 17:07:50.365
#* nightly #1509: 16:01:35.8 -> 16:01:42.0 -> 16:01:46.0 (the rerun polled at 
16:03:13.8, before the 16:03:18 tick, and passed)
#* nightly #1510: 16:44:39.4 -> 16:44:40.3 -> 16:44:41.7
# *Between two polls.* In run 37475000411 the test was already polling and had 
seen {{Num of SCPs: 2}}.
Both SCPs finished at 17:04:30.511/30.541, the cleaner ticked at 17:04:31.040, 
and the next poll
(17:04:31.095) saw 0 SCPs, with the procedure list down from 32 to 5 entries.

h3. Reproduction
* Deterministic: set {{hbase.procedure.cleaner.interval=1000}} in 
{{setUpBeforeClass}}; the test fails
every time with the same signature.
* Statistical, default config, local JDK 17, original and fixed test alternated 
in fresh JVMs:
the original failed 6/39 (15.4%, 95% CI 7.2-29.7%); the fixed version failed 
0/39 (Fisher p ~ 0.025).
In every run, whether a cleaner tick fell between the last SCP finishing and 
the first poll
predicted the original's outcome exactly: 6/6 such runs failed, 0/33 others 
failed. The fixed
version passed all 6 runs where that happened.

h3. Proposed fix (test only)
Detect that an SCP was submitted with the master's monotonic SCP counter 
instead of scanning
{{getProcedures()}}: sample 
{{master.getMasterMetrics().getServerCrashProcMetrics().getSubmittedCounter()}}
before injecting errors, and wait until it has increased. The counter is not 
affected by procedure
eviction, so it covers both windows above. The other {{waitFor}} conditions 
(region count unchanged,
all listed procedures SUCCESS) and the hbck check are unchanged.

There is no product bug: evicting finished SCPs quickly is intended, since 
nothing waits on their
result. Note that anything outside the master that uses the procedure list to 
confirm a server
crash was handled (scripts, dashboards, the Procedures UI) has the same blind 
spot; the
{{serverCrash}} master metrics or the master log are the reliable sources.



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

Reply via email to