Repository navigation
GH-5435 Tenant databases with one name on one host are told apart by port - #5436
Merged
Merged
Conversation
…port
A relational store's agent Uri is wolverinedb://{engine}/{host}/{database}/{schema}, without the port.
Two tenant databases with the same name on the same host but different ports shared one Uri, so only
the first got a durability agent. The second database's scheduled messages were never released, and
its dead nodes' work was never recovered. Found by the durability chaos rig, leg 8 (#5414).
When MessageStoreCollection finds two such databases, each one that is not the main store switches
to a Uri that carries its port. A Uri that collided once is remembered, so a database discovered
later is qualified too, whatever order the nodes discover them in. Configurations without the
collision keep the Uris they have.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nKJrqsJw3j23Xd46q37ob
This was referenced Nov 7, 2026
Merged
This was referenced Nov 9, 2026
This was referenced Nov 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #5435
What was wrong
A relational message store's agent
Uriiswolverinedb://{engine}/{host}/{database}/{schema}. It leaves out the port: PostgreSQL and MySQL keep the port apart from the host, and SQL Server'shost,portis split at the comma. Two tenant databases with the same name on the same host but different ports (two clusters or two containers on one box) therefore shared oneUri.MessageStoreCollectionkeys stores byUri, so only the first database got a durability agent. The second database's scheduled messages were never released, and its dead nodes' work was never recovered.Found by the durability chaos rig, leg 8 (#5414). In a 20 second run with one pause fault, all 820 of the second tenant's delayed messages stayed
Scheduledwith owner 0.The fix
IPortQualifiedAgentUri, implemented byMessageDatabase<T>. It exposes the port and can switch theUritowolverinedb://{engine}/{host}:{port}/{database}/{schema}. The qualifiedUriis built only when it is asked for.MessageStoreCollection.categorizeStorechecks for the collision. If a non-main store'sUriis already taken by another database on a different port, each of the two that is not the main store is qualified. The collidingUriis remembered, so a database discovered later with thatUriis qualified too. Nodes that discover tenant databases in different orders therefore end up with the same Uris.Uri.MySqlMessageStore.Describe()now setsPort.No
Urichanges for any configuration that works today. Qualification only happens for the collision, so agent assignments,node_assignmentsrows and CritterWatch'sDatabaseUristay as they are for everyone else.DurabilityProjectionAffinityalready normalizes ports away, so projection affinity is unaffected.Tests
CoreTests.Persistence.tenant_databases_told_apart_by_port_5435: collision, a later colliding database, collision with the main store, same database twice, and no collision. Without the fix, 3 of 5 fail.PostgresqlTests.agent_uri_carries_the_port_when_asked_5435andSqlServerTests.agent_uri_carries_the_port_when_asked_5435run offline against the real stores.Persistence+Runtime.Agents(760), PostgresqlTestsMultiTenancy(29), MartenTestsMultiTenancy(79), PersistenceTestsModularMonoliths(28).🤖 Generated with Claude Code
https://claude.ai/code/session_013nKJrqsJw3j23Xd46q37ob