You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by "lizhimins (via GitHub)" <gi...@apache.org> on 2026/10/15 12:10:02 UTC
[PR] fix(instance): tolerate H2's unsnapshotted index metadata during concurrent startup [rocketmq-dashboard]
lizhimins opened a new pull request, #6736:
URL: https://github.com/apache/rocketmq-dashboard/pull/6736
## Why
`ResourceOwnershipGuardTest.migrationConcurrentStartupIsIdempotentTest` fails roughly **one run in
three** on `rocketmq-studio`:
```
JdbcSQLNonTransientException: General error: "java.util.ConcurrentModificationException"
at org.h2.jdbc.meta.DatabaseMetaLocal.getIndexInfo(DatabaseMetaLocal.java:1229)
at org.h2.jdbc.JdbcDatabaseMetaData.getIndexInfo(JdbcDatabaseMetaData.java:261)
at ...instance.ResourceOwnershipSchemaMigration.indexes(ResourceOwnershipSchemaMigration.java:140)
at ...instance.ResourceOwnershipSchemaMigration.ensureIndex(...:132)
at ...instance.ResourceOwnershipSchemaMigration.afterPropertiesSet(...:99)
```
The file is untouched by recent merges (blob-identical to `8bbe7947a`), so this is a long-standing
flake rather than a regression — but it makes `mvn test` unreliable as a merge gate.
## Root cause
H2 answers `getIndexInfo` from a mutable metadata cache without taking a snapshot. When a second
node starts concurrently and commits a `CREATE INDEX`, the `ArrayList` being iterated by the first
node's metadata read is structurally modified, and H2 wraps the resulting
`ConcurrentModificationException` in a `SQLException`.
## What this does
Retries the metadata read a bounded number of times (`INDEX_METADATA_ATTEMPTS = 5`) **only** when the
cause chain carries a `ConcurrentModificationException`; every other `SQLException` is rethrown
unchanged, so a real failure — including the duplicate-data case `ensureIndex` deliberately
distinguishes — still surfaces.
**Deliberately not a lock.** Serializing the migration inside one JVM (the approach in the open
#6175) would make this test assert nothing: it starts migrations concurrently precisely to prove
idempotency under a race. The production database is MySQL, whose metadata reads are taken from
committed state and never hit this path.
## Verification
- `ResourceOwnershipGuardTest` run **eight times consecutively: 8 green / 0 red** (one in three
failed before this change)
- Full `mvn -B -ntp test` on the server module: recorded in a follow-up comment
- The retry is keyed on the exception cause, not on a broad `SQLException` catch, so the
"failures caused by duplicate data must not be swallowed" contract in `ensureIndex` is unchanged
--
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: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] fix(instance): tolerate H2's unsnapshotted index metadata during concurrent startup [rocketmq-dashboard]
Posted by "lizhimins (via GitHub)" <gi...@apache.org>.
lizhimins merged PR #6736:
URL: https://github.com/apache/rocketmq-dashboard/pull/6736
--
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: commits-unsubscribe@rocketmq.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org