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