diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d2c5fa074..e1c6cb12b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,6 +24,8 @@ Added - Filter param to Lua API ``get_servers`` to filter instances. +- new issue about vshard storages marked as ``ALL_RW``. + ------------------------------------------------------------------------------- [2.8.4] - 2023-10-31 ------------------------------------------------------------------------------- diff --git a/cartridge/issues.lua b/cartridge/issues.lua index c7821ef16..05bce2b62 100644 --- a/cartridge/issues.lua +++ b/cartridge/issues.lua @@ -45,6 +45,12 @@ -- * warning: "Advertise URI (...) differs from clusterwide config (...)"; -- * warning: "Configuring roles is stuck on ... and hangs for ... so far"; -- +-- Vshard: +-- +-- * various vshard alerts (see vshard docs for details); +-- * warning: "Group "..." wasn't bootstrapped: ..."; +-- * warning: Vshard storages in replicaset %s marked as "all writable". +-- -- Alien members: -- -- * warning: "Instance ... with alien uuid is in the membership" - diff --git a/cartridge/roles/vshard-storage.lua b/cartridge/roles/vshard-storage.lua index 3d759450b..432a98feb 100644 --- a/cartridge/roles/vshard-storage.lua +++ b/cartridge/roles/vshard-storage.lua @@ -20,10 +20,12 @@ hotreload.whitelist_globals({ vars:new('vshard_cfg') vars:new('instance_uuid') vars:new('replicaset_uuid') +vars:new('issues', {}) local _G_vshard_backup -local function apply_config(conf, _) +local function apply_config(conf, opts) checks('table', {is_master = 'boolean'}) + vars.issues = {} local my_replicaset = conf.topology.replicasets[vars.replicaset_uuid] local group_name = my_replicaset.vshard_group or 'default' @@ -34,6 +36,15 @@ local function apply_config(conf, _) vshard_cfg.listen = box.cfg.listen vshard_cfg.replication = box.cfg.replication + if my_replicaset.all_rw and opts.is_master then + table.insert(vars.issues, { + level = 'warning', + topic = 'vshard', + message = ([[Vshard storages in replicaset %s marked as "all writable". ]] .. + [[This might not work as expected.]]):format(vars.replicaset_uuid), + }) + end + if utils.deepcmp(vshard_cfg, vars.vshard_cfg) then -- No reconfiguration required, skip it return @@ -101,4 +112,5 @@ return { on_apply_config = on_apply_config, init = init, stop = stop, + get_issues = function() return vars.issues end, } diff --git a/rst/cartridge_admin.rst b/rst/cartridge_admin.rst index f7f0934e5..783b2a5f6 100644 --- a/rst/cartridge_admin.rst +++ b/rst/cartridge_admin.rst @@ -1379,6 +1379,14 @@ Cartridge displays cluster and instances issues in WebUI: |nbsp| +* Vshard: + + * various vshard alerts (see vshard docs for details); + + * **warning**: warning: "Group "..." wasn't bootstrapped: ..."; + + * **warning**: Vshard storages in replicaset %s marked as "all writable". + * Alien members: * **warning**: "Instance ... with alien uuid is in the membership" -- @@ -1390,10 +1398,21 @@ Cartridge displays cluster and instances issues in WebUI: |nbsp| +* Expelled instances: + + * **warning**: "Replicaset ... has expelled instance ... in box.space._cluster" - + when instance was expelled from replicaset, but still remains in box.space._cluster; + * Deprecated space format: * **warning**: "Instance ... has spaces with deprecated format: space1, ..." +* Raft issues: + + * **warning**: "Raft leader idle is 10.000 on ... . + Is raft leader alive and connection is healthy?" + + * Custom issues (defined by user): * Custom roles can announce more issues with their own level, topic diff --git a/test/integration/api_edit_test.lua b/test/integration/api_edit_test.lua index 150a71a22..fe902fe03 100644 --- a/test/integration/api_edit_test.lua +++ b/test/integration/api_edit_test.lua @@ -313,4 +313,11 @@ end function g.test_all_rw_true() test_all_rw(true) + helpers.retrying({}, function() + t.assert_equals( + helpers.list_cluster_issues(g.cluster.main_server)[1].message, + ('Vshard storages in replicaset %s '):format(helpers.uuid('b')).. + 'marked as "all writable". This might not work as expected.' + ) + end) end diff --git a/test/integration/api_query_test.lua b/test/integration/api_query_test.lua index 65f4904de..5e1b52a29 100644 --- a/test/integration/api_query_test.lua +++ b/test/integration/api_query_test.lua @@ -27,7 +27,6 @@ g.before_all(function() }, { uuid = helpers.uuid('b'), roles = {'vshard-storage'}, - all_rw = true, servers = { { alias = 'storage', @@ -479,7 +478,7 @@ function g.test_replicasets() master = {uuid = helpers.uuid('b', 'b', 1)}, active_master = {uuid = helpers.uuid('b', 'b', 1)}, weight = 1, - all_rw = true, + all_rw = false, servers = { {uri = 'localhost:13302', priority = 1}, {uri = 'localhost:13304', priority = 2}, diff --git a/webui/cypress/integration/bootstrap.spec.js b/webui/cypress/integration/bootstrap.spec.js index e370c7c21..ef1df53aa 100644 --- a/webui/cypress/integration/bootstrap.spec.js +++ b/webui/cypress/integration/bootstrap.spec.js @@ -186,9 +186,6 @@ describe('Replicaset configuration & Bootstrap Vshard', () => { cy.get('form input[value="vshard-router"]').check({ force: true }).should('be.checked'); cy.get('form input[value="vshard-storage"]').should('not.be.checked'); - cy.get('form input[name="all_rw"]').check({ force: true }); - cy.get('form input[name="all_rw"]').should('be.checked'); - cy.get('.meta-test__EditReplicasetSaveBtn').click(); cy.get('#root').contains('test-router'); @@ -243,12 +240,9 @@ describe('Replicaset configuration & Bootstrap Vshard', () => { cy.get('form input[value="vshard-router"]').should('not.be.checked'); cy.get('form input[value="vshard-storage"]').should('be.checked'); - cy.get('form input[name="all_rw"]').check({ force: true }).should('be.checked'); - cy.get('.meta-test__CreateReplicaSetBtn').click(); cy.get('#root').contains('test-storage'); - cy.get('.meta-test__ReplicasetList_allRw_enabled').should('have.length', 2); // Check health state cy.get('section').eq(0).contains('Total unconfigured instances1'); @@ -283,7 +277,6 @@ describe('Replicaset configuration & Bootstrap Vshard', () => { cy.get('.meta-test__EditReplicasetSaveBtn').should('be.enabled'); cy.get('form input[name="alias"]').type('{selectall}edited-storage').should('have.value', 'edited-storage'); - cy.get('form input[name="all_rw"]').uncheck({ force: true }).should('not.be.checked'); cy.get('form input[value="myrole"]').uncheck({ force: true }).should('not.be.checked'); cy.get('form input[value="myrole-dependency"]').should('be.enabled').should('not.be.checked');