diff --git a/changelogs/unreleased/gh-10013-wal-queue-max-size.md b/changelogs/unreleased/gh-10013-wal-queue-max-size.md new file mode 100644 index 0000000000000000000000000000000000000000..5a76a6dee739aa67f80d639084f41374265fe4f9 --- /dev/null +++ b/changelogs/unreleased/gh-10013-wal-queue-max-size.md @@ -0,0 +1,4 @@ +## bugfix/box + +* Fixed the `wal_queue_max_size` configuration option not being applied during + the initial configuration (gh-10013). diff --git a/src/box/box.cc b/src/box/box.cc index e2724ba45d24677c9e128586a0b251b6130c5647..fbe5114ce5dfbdf91cb30b735e1c846319374f7d 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -4962,6 +4962,8 @@ box_cfg_xc(void) box_set_replication_sync_timeout(); box_set_replication_skip_conflict(); box_set_replication_anon(); + if (box_set_wal_queue_max_size() != 0) + diag_raise(); /* * Must be set before opening the server port, because it may be * requested by a client before the configuration is completed. diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua index c7cc53101807044a800ab0d79fac3c6ea4bf22e0..4465065c71083a7269bdbda818666004ab49a5a5 100644 --- a/src/box/lua/load_cfg.lua +++ b/src/box/lua/load_cfg.lua @@ -651,6 +651,7 @@ local dynamic_cfg_skip_at_load = { replication_anon = true, bootstrap_strategy = true, wal_dir_rescan_delay = true, + wal_queue_max_size = true, custom_proc_title = true, force_recovery = true, instance_uuid = true, diff --git a/test/replication-luatest/gh_10013_wal_queue_max_size_test.lua b/test/replication-luatest/gh_10013_wal_queue_max_size_test.lua new file mode 100644 index 0000000000000000000000000000000000000000..0efa8bec245ff094b75bef1225838e18728e2334 --- /dev/null +++ b/test/replication-luatest/gh_10013_wal_queue_max_size_test.lua @@ -0,0 +1,75 @@ +local t = require('luatest') +local server = require('luatest.server') +local replica_set = require('luatest.replica_set') + +local g = t.group() + +g.before_each(function(cg) + t.tarantool.skip_if_not_debug() + cg.replica_set = replica_set:new{} + cg.master = cg.replica_set:build_and_add_server{ + alias = 'master', + box_cfg = { + replication_timeout = 0.1, + }, + } + cg.replica = cg.replica_set:build_and_add_server{ + alias = 'replica', + box_cfg = { + replication = { + server.build_listen_uri('master', cg.replica_set.id), + }, + replication_timeout = 0.1, + wal_queue_max_size = 1, + -- We want to check that correct wal_queue_max_size is in effect + -- during sync, so set huge sync timeout to make sure sync doesn't + -- end too fast and an old code path (setting size after sync) isn't + -- tested. + replication_sync_timeout = 300, + }, + } + cg.replica_set:start() + cg.master:exec(function() + box.schema.space.create('test') + box.space.test:create_index('pk') + end) + cg.replica:wait_for_vclock_of(cg.master) +end) + +g.after_each(function(cg) + cg.replica_set:drop() +end) + +local run_before_cfg = [[ + rawset(_G, 'wal_write_count', 0) + box.error.injection.set('ERRINJ_WAL_DELAY' , true) + wal_write_count = box.error.injection.get('ERRINJ_WAL_WRITE_COUNT') +]] + +-- gh-10013: wal_queue_max_size wasn't respected during initial box.cfg() call, +-- and the replica used the default value (16 Mb) during sync. Test that this is +-- fixed: introduce a WAL delay before initial box.cfg() on replica, write some +-- data on master to be synced with, make sure replica respects queue max size. +g.test_wal_queue_max_size_apply_on_initial_sync = function(cg) + cg.replica:stop() + cg.master:exec(function() + for i = 1,10 do + box.space.test:insert{i} + end + end) + cg.replica.env['TARANTOOL_RUN_BEFORE_BOX_CFG'] = run_before_cfg + cg.replica:start({wait_until_ready=false}) + t.helpers.retrying({}, cg.replica.connect_net_box, cg.replica) + cg.replica:exec(function() + t.helpers.retrying({}, function() + t.assert_equals(box.error.injection.get('ERRINJ_WAL_WRITE_COUNT'), + _G.wal_write_count + 1) + end) + box.error.injection.set('ERRINJ_WAL_DELAY', false) + t.helpers.retrying({}, function() + t.assert_equals(box.error.injection.get('ERRINJ_WAL_WRITE_COUNT'), + _G.wal_write_count + 10) + end) + end) + cg.replica:wait_for_vclock_of(cg.master) +end