From 54162a026fb2b1718a467a43172fc32989de00fc Mon Sep 17 00:00:00 2001 From: Asias He Date: Thu, 11 Sep 2025 15:29:44 +0800 Subject: [PATCH] scylla-nodetool: Add --incremental-mode option to cluster repair The `--incremental-mode` option specifies the incremental repair mode. Can be 'disabled', 'regular', or 'full'. 'regular': The incremental repair logic is enabled. Unrepaired sstables will be included for repair. Repaired sstables will be skipped. The incremental repair states will be updated after repair. 'full': The incremental repair logic is enabled. Both repaired and unrepaired sstables will be included for repair. The incremental repair states will be updated after repair. 'disabled': The incremental repair logic is disabled completely. The incremental repair states, e.g., repaired_at in sstables and sstables_repaired_at in the system.tablets table, will not be updated after repair. When the option is not provided, it defaults to regular. Fixes #25931 Closes scylladb/scylladb#25969 --- .../nodetool-commands/cluster/repair.rst | 8 ++++++ test/nodetool/test_cluster_repair.py | 26 +++++++++++++++++++ tools/scylla-nodetool.cc | 10 +++++++ 3 files changed, 44 insertions(+) diff --git a/docs/operating-scylla/nodetool-commands/cluster/repair.rst b/docs/operating-scylla/nodetool-commands/cluster/repair.rst index 4e01969424..bb590d8dd2 100644 --- a/docs/operating-scylla/nodetool-commands/cluster/repair.rst +++ b/docs/operating-scylla/nodetool-commands/cluster/repair.rst @@ -53,6 +53,14 @@ ScyllaDB nodetool cluster repair command supports the following options: nodetool cluster repair --tablet-tokens 1,10474535988 +- ``--incremental-mode`` specifies the incremental repair mode. Can be 'disabled', 'regular', or 'full'. 'regular': The incremental repair logic is enabled. Unrepaired sstables will be included for repair. Repaired sstables will be skipped. The incremental repair states will be updated after repair. 'full': The incremental repair logic is enabled. Both repaired and unrepaired sstables will be included for repair. The incremental repair states will be updated after repair. 'disabled': The incremental repair logic is disabled completely. The incremental repair states, e.g., repaired_at in sstables and sstables_repaired_at in the system.tablets table, will not be updated after repair. When the option is not provided, it defaults to regular. + + For example: + + :: + + nodetool cluster repair --incremental-mode regular + - ``keyspace`` executes a repair on a specific keyspace. The default is all keyspaces. For example: diff --git a/test/nodetool/test_cluster_repair.py b/test/nodetool/test_cluster_repair.py index cba7a02576..bc5745c6e3 100644 --- a/test/nodetool/test_cluster_repair.py +++ b/test/nodetool/test_cluster_repair.py @@ -368,3 +368,29 @@ def test_repair_keyspace(nodetool): expected_request("GET", "/storage_service/keyspaces", params={"replication": "tablets"}, response=[]), ]}, ["error processing arguments: nodetool cluster repair repairs only tablet keyspaces. To repair vnode keyspaces use nodetool repair."]) + +@pytest.mark.parametrize("mode", ["disabled", "regular", "full"]) +def test_repair_incremenatal_repair(nodetool, mode): + id1 = "ef1b7a61-66c8-494c-bb03-6f65724e6eee" + res = nodetool("cluster", "repair", "--incremental-mode", mode, "ks", "table1", expected_requests=[ + expected_request("GET", "/storage_service/keyspaces", response=["ks"]), + expected_request("GET", "/storage_service/keyspaces", params={"replication": "tablets"}, response=["ks"]), + expected_request( + "POST", + "/storage_service/tablets/repair", + params={ + "ks": "ks", + "table": "table1", + "incremental_mode": mode, + "tokens": "all"}, + response={"tablet_task_id": id1}), + expected_request( + "GET", + f"/task_manager/wait_task/{id1}", + response={"state": "done"}), + ]) + + assert _remove_log_timestamp(res.stdout) == f"""\ +Starting repair with task_id={id1} keyspace=ks table=table1 +Repair with task_id={id1} finished +""" diff --git a/tools/scylla-nodetool.cc b/tools/scylla-nodetool.cc index e49c11e29e..b5f7b1c0fd 100644 --- a/tools/scylla-nodetool.cc +++ b/tools/scylla-nodetool.cc @@ -557,6 +557,15 @@ void cluster_repair_operation(scylla_rest_client& client, const bpo::variables_m repair_params["dcs_filter"] = std::move(dcs.value()); } + if (vm.contains("incremental-mode")) { + auto mode = vm["incremental-mode"].as(); + const std::unordered_set supported_mode{"disabled", "regular", "full"}; + if (!supported_mode.contains(mode)) { + throw std::invalid_argument("nodetool cluster repair --incremental-mode only supports: disabled, regular, full"); + } + repair_params["incremental_mode"] = mode; + } + auto log = [&] (fmt::format_string fmt, Args&&... param) { const auto msg = fmt::format(fmt, param...); using clock = std::chrono::system_clock; @@ -3709,6 +3718,7 @@ For more information, see: {}" typed_option>("in-dc", "Constrain repair to specific datacenter(s)"), typed_option>("in-hosts", "Constrain repair to the specific host(s)"), typed_option>("tablet-tokens", "Tokens owned by the tablets to repair."), + typed_option("incremental-mode", "Specify the incremental repair mode: disabled, regular, full"), }, { typed_option("keyspace", "The keyspace to repair, if missing all keyspaces are repaired", 1),