Skip to content

Commit 7f34d05

Browse files
committed
replicaset: check URI match when rebind connection
Reconfiguration in router and storage always creates new replica objects, and outdates old objects. Since most of the time reconfiguration does not change cluster topology and URIs, old connections are relocated to the new replicaset objects so as not to reconnect on each router.cfg() and storage.cfg(). Connections were moved from old objects to new ones by UUID match not taking into account possible URI change. If URI was changed, the new replica object took the old connection with old URI, and kept trying to connect to the old address. The patch makes connection relocation work only if old and new URI match. Closes #245
1 parent 0cd777f commit 7f34d05

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

test/router/reconnect_to_master.result

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,61 @@ is_disconnected()
169169
---
170170
- false
171171
...
172+
--
173+
-- gh-245: dynamic uri reconfiguration didn't work - even if URI was changed in
174+
-- the config for any instance, it used old connection, because reconfiguration
175+
-- compared connections by UUID instead of URI.
176+
--
177+
util = require('util')
178+
---
179+
...
180+
-- Firstly, clean router from storage_1_a connection.
181+
rs1_uuid = util.replicasets[1]
182+
---
183+
...
184+
rs1_cfg = cfg.sharding[rs1_uuid]
185+
---
186+
...
187+
cfg.sharding[rs1_uuid] = nil
188+
---
189+
...
190+
vshard.router.cfg(cfg)
191+
---
192+
...
193+
-- Now break the URI in the config.
194+
old_uri = rs1_cfg.replicas[util.name_to_uuid.storage_1_a].uri
195+
---
196+
...
197+
rs1_cfg.replicas[util.name_to_uuid.storage_1_a].uri = 'https://bad_uri.com:123'
198+
---
199+
...
200+
-- Apply the bad config.
201+
cfg.sharding[rs1_uuid] = rs1_cfg
202+
---
203+
...
204+
vshard.router.cfg(cfg)
205+
---
206+
...
207+
-- Should fail - master is not available because of the bad URI.
208+
res, err = vshard.router.callrw(1, 'echo', {1})
209+
---
210+
...
211+
res == nil and err ~= nil
212+
---
213+
- true
214+
...
215+
-- Repair the config.
216+
rs1_cfg.replicas[util.name_to_uuid.storage_1_a].uri = old_uri
217+
---
218+
...
219+
vshard.router.cfg(cfg)
220+
---
221+
...
222+
-- Should drop the old connection object and connect fine.
223+
vshard.router.callrw(1, 'echo', {1})
224+
---
225+
- 1
226+
...
172227
_ = test_run:switch("default")
173228
---
174229
...

test/router/reconnect_to_master.test.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,32 @@ while is_disconnected() and i < max_iters do i = i + 1 fiber.sleep(0.1) end
7070
-- Master connection is active again.
7171
is_disconnected()
7272

73+
--
74+
-- gh-245: dynamic uri reconfiguration didn't work - even if URI was changed in
75+
-- the config for any instance, it used old connection, because reconfiguration
76+
-- compared connections by UUID instead of URI.
77+
--
78+
util = require('util')
79+
-- Firstly, clean router from storage_1_a connection.
80+
rs1_uuid = util.replicasets[1]
81+
rs1_cfg = cfg.sharding[rs1_uuid]
82+
cfg.sharding[rs1_uuid] = nil
83+
vshard.router.cfg(cfg)
84+
-- Now break the URI in the config.
85+
old_uri = rs1_cfg.replicas[util.name_to_uuid.storage_1_a].uri
86+
rs1_cfg.replicas[util.name_to_uuid.storage_1_a].uri = 'https://bad_uri.com:123'
87+
-- Apply the bad config.
88+
cfg.sharding[rs1_uuid] = rs1_cfg
89+
vshard.router.cfg(cfg)
90+
-- Should fail - master is not available because of the bad URI.
91+
res, err = vshard.router.callrw(1, 'echo', {1})
92+
res == nil and err ~= nil
93+
-- Repair the config.
94+
rs1_cfg.replicas[util.name_to_uuid.storage_1_a].uri = old_uri
95+
vshard.router.cfg(cfg)
96+
-- Should drop the old connection object and connect fine.
97+
vshard.router.callrw(1, 'echo', {1})
98+
7399
_ = test_run:switch("default")
74100
_ = test_run:cmd('stop server router_1')
75101
_ = test_run:cmd('cleanup server router_1')

vshard/replicaset.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ local function rebind_replicasets(replicasets, old_replicasets)
456456
for replica_uuid, replica in pairs(replicaset.replicas) do
457457
local old_replica = old_replicaset and
458458
old_replicaset.replicas[replica_uuid]
459-
if old_replica then
459+
if old_replica and old_replica.uri == replica.uri then
460460
local conn = old_replica.conn
461461
replica.conn = conn
462462
replica.down_ts = old_replica.down_ts

0 commit comments

Comments
 (0)