Repository navigation
[IT] Wait for all Regions to be Running after a cluster restart - #19114
luoluoyuyu wants to merge 1 commit into
Conversation
Caideyipi
left a comment
There was a problem hiding this comment.
Reviewed the full diff at a97ad9f, the restart callers, and the Region status query path. The new wait skips table-model Regions because it queries only the tree SQL dialect; see the inline comment. No additional tests were run. Completed CI checks are passing, with the DataNode unit-test job still in progress.
| .ignoreExceptions() | ||
| .untilAsserted( | ||
| () -> { | ||
| try (final Connection connection = env.getConnection(); |
There was a problem hiding this comment.
[P2] Include table-model Regions in the readiness check
BaseEnv.getConnection() always opens a tree-dialect connection. In that dialect, TreeConfigTaskVisitor.visitShowRegion() passes isTableModel=false, and PartitionInfo.getRegionInfoList() filters out table-model databases. A table-only cluster therefore produces an empty result here and immediately passes the wait even while its RegionGroups are still Disabled; a mixed cluster only waits for its tree Regions. Existing table-model callers such as IoTDBPipeLifeCycleIT.testLifeCycleWithClusterRestart() consequently retain the restart/write race that this helper is intended to prevent. Please check both tree and table SHOW REGIONS results, or use a query that includes both models, and cover the table-only case.
There was a problem hiding this comment.
Good catch, fixed in ebe7ce9. awaitAllRegionsRunning() now runs the check on both dialects inside the same Awaitility condition: env.getConnection() (tree) and env.getTableConnection() (table), each asserting that every Region it lists is Running. A table-only cluster therefore waits for its table Regions, and a mixed cluster waits for both.
Also added IoTDBRegionReadyAfterRestartTableIT (TableClusterIT): it creates a table-model Database, calls TestUtils.restartCluster(), then asserts that SHOW REGIONS over the table connection lists Running Regions and that the first write after the restart succeeds. With a tree-only readiness check the regionCount > 0 assertion fails on a table-only cluster, so the regression is covered.
jt2594838
left a comment
There was a problem hiding this comment.
Maybe reduce the poll interval to avoid unnecessary wait.
a97ad9f to
ebe7ce9
Compare
|
@jt2594838 thanks, reduced the poll interval from 1 s to 100 ms in ebe7ce9 (same order as the other Awaitility helpers in Both review points are in ebe7ce9:
CI is re-running on the new commit. |
restartCluster() returns as soon as every node reports a non-Unknown status and a JDBC connection succeeds, but ConfigNode keeps the RegionGroups of a Database Disabled until all Regions of the group report Running. Any write issued in that window, including an active LOAD, is rejected with NO_AVAILABLE_REGION_GROUP. IoTDBLoadTsFileActiveScanIT#testIncompletePublicationSurvivesScannerRestartAndPreservesMods restarts the cluster and immediately publishes a canary TsFile into the active LOAD listening directory. The scanner rescans every second, so the canary was picked up during the Disabled window, the LOAD failed permanently (the file was moved to ext/load/failed) and awaitRows timed out after 60 seconds. Wait for all Regions reported by SHOW REGIONS to be Running before restartCluster() returns. SHOW REGIONS reads the same ConfigNode LoadCache status that rejects the write, so the wait covers exactly the condition that fails the LOAD. SHOW REGIONS only lists the Databases of the dialect of the connection, so the tree model and the table model are checked separately, and the 100 ms poll interval keeps the added delay negligible while still converging within a few heartbeats. IoTDBRegionReadyAfterRestartTableIT covers a table-model-only cluster, where a tree-dialect SHOW REGIONS lists no Region at all.
ebe7ce9 to
a2f3a4b
Compare
Description
TestUtils.restartCluster()returned as soon as every node reported a non-Unknownstatus and aJDBC connection succeeded. A running node does not imply a serving Region: right after a restart the
ConfigNode
LoadCachekeeps the RegionGroups of a DatabaseDisableduntil all of their Regionsreport
Running, and any write issued in that window, including an active LOAD, is rejected withNO_AVAILABLE_REGION_GROUP(906).IoTDBLoadTsFileActiveScanIT#testIncompletePublicationSurvivesScannerRestartAndPreservesModsrestarts the cluster and immediately publishes a canary TsFile into the active LOAD listening
directory.
ActiveLoadDirScannerrescans that directory every second, so the canary was picked upinside the window described above, the LOAD failed permanently (the file was moved to
ext/load/failedand the status was rewritten toLOAD_FILE_ERROR) andawaitRowstimed out after60 seconds.
Timeline from a failing CI run:
The window is ~100 ms wide, so the test passes most of the time and fails rarely.
Fix
restartCluster()now also calls the newTestUtils.awaitAllRegionsRunning(env), which waits(bounded by 2 minutes, polled every 100 ms) until every Region listed by
SHOW REGIONSisRunning.SHOW REGIONSreportsLoadManager.getRegionStatus, read from the sameLoadCachethat computesRegionGroupStatus(RegionGroupCache#caculateRegionGroupStatus: a group isRunningonly when allof its Regions are
Running). "All Regions Running" is therefore exactly the condition thatguarantees the next write cannot hit
NO_AVAILABLE_REGION_GROUP— it waits on the same state thatrejects the write, not on an approximation, and it is an observable condition instead of a fixed
sleep. No assertion of the affected tests is changed, and the active LOAD test itself is untouched.
SHOW REGIONSonly lists the Databases that belong to the dialect of the connection(
TreeConfigTaskVisitor.visitShowRegion()passesisTableModel=falseandPartitionInfo#getRegionInfoListfilters the other model out), so the wait checks the tree modeland the table model through separate connections; otherwise a table-only cluster would wait for
nothing and a mixed cluster would only wait for its tree Regions.
Clusters without any RegionGroup
If the cluster has no Database yet,
SHOW REGIONSreturns no row and the wait returns immediately.That is the intended behaviour: there is no RegionGroup that could be
Disabled, and the statementthat creates a Database also creates its RegionGroups in the same plan, which
CreateRegionGroupsProcedureactivates asRunning(env.activateRegionGroupwith aRegionStatus.Runningsample;Unknownonly for a replica whose creation failed). So the state thehelper waits for is the one produced by a restart, where existing RegionGroups fall back to
Unknownuntil their DataNodes report again.Tests
IoTDBLoadTsFileActiveScanIT(existing): the flake this PR fixes; its assertions are unchanged.IoTDBRegionReadyAfterRestartTableIT(new,TableClusterIT): creates a table-model Database,calls
restartCluster(), then asserts that the table connection lists Running Regions and thatthe first write after the restart succeeds. It fails with a tree-only readiness check, where
SHOW REGIONSover the tree connection lists no Region of a table-only cluster.Alternatives considered
INSERTinside the affected test: works, but only covers oneDatabase and has to be repeated in every restart-based IT.
checkClusterStatusWithoutUnknown(): would also cover the initialcluster start, but that helper is used by many tests that do not need the extra wait, so the wait
is scoped to
restartCluster()here.kept out of this PR. A DataNode cannot observe the ConfigNode
LoadCacheview during startup, andblocking active LOAD globally until every Region is ready would stall healthy Databases whenever a
single RegionGroup is unavailable.
This PR has:
for an unfamiliar reader.
Not applicable: documentation, version/license information, concurrency of the changed helper (it
runs in the test JVM only, single-threaded via Awaitility).
Key changed/added classes (or packages if there are too many classes) in this PR
integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java:restartCluster()calls the newawaitAllRegionsRunning(), which checks the tree and the tabledialect.
integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBRegionReadyAfterRestartTableIT.java:new coverage for a table-model-only cluster.