Commit Graph

268 Commits

Author SHA1 Message Date
Benny Halevy
f207cff73d token_metadata: set_pending_ranges: prep new interval_map out of line
And move-assign to _pending_ranges_interval_map[keyspace_name]
only when done.

This is more effient since there's no need to look up
_pending_ranges_interval_map[keyspace_name] for every insert to the
interval_map.

And it is exception safe in case we run out of memory mid-way.

Refs #7220

Test: unit(dev)
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Message-Id: <20200916115059.788606-1-bhalevy@scylladb.com>
2020-09-16 15:28:42 +03:00
Avi Kivity
64ebb9c052 Merge 'Remove _pending_ranges and _pending_ranges_map in token_metadata' from Asias
"
This PR removes  _pending_ranges and _pending_ranges_map in token_metadata.
This removal of  makes copying of token_metadata faster and reduces the chance to cause reactor stall.

Refs: #7220
"

* asias-token_metadata_replication_config_less_maps:
  token_metadata: Remove _pending_ranges
  token_metadata: Get rid of unused _pending_ranges_map
2020-09-15 17:16:35 +03:00
Benny Halevy
0dc45529c8 abstract_replication_strategy: get_ranges_in_thread: copy _token_metadata if func may yield
Change 94995acedb added yielding to abstract_replication_strategy::do_get_ranges.
And 07e253542d used get_ranges_in_thread in compaction_manager.

However, there is nothing to prevent token_metadata, and in particular its
`_sorted_tokens` from changing while iterating over them in do_get_ranges if the latter yields.

Therefore copy the the replication strategy `_token_metadata` in `get_ranges_in_thread(inet_address ep)`.

If the caller provides `token_metadata` to get_ranges_in_thread, then the caller
must make sure that we can safely yield while accessing token_metadata (like
in `do_rebuild_replace_with_repair`).

Fixes #7044

Test: unit(dev)

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Message-Id: <20200915074555.431088-1-bhalevy@scylladb.com>
2020-09-15 11:33:55 +03:00
Asias He
c38ec98c6e token_metadata: Remove _pending_ranges
- Remove get_pending_ranges and introduce has_pending_ranges, since the
  caller only needs to know if there is a pending range for the keyspace
  and the node.

- Remove print_pending_ranges which is only used in logging. If we
  really want to log the new pending token ranges, we can log when we
  set the new pending token ranges.

This removal of _pending_ranges makes copying of token_metadata faster
and reduces the chance to cause reactor stall.

Refs: #7220
2020-09-15 16:27:50 +08:00
Asias He
d38506fbf0 token_metadata: Get rid of unused _pending_ranges_map
It is not used anymore. The size of _pending_ranges_map is is O(number
of keyspaces). It can be very big when we have lots of keyspaces.

Refs: #7220
2020-09-15 14:47:00 +08:00
Rafael Ávila de Espíndola
d18af34205 everywhere: Use future::get0 when appropriate
This works with current seastar and clears most of the way for
updating to a version that doesn't use std::tuple in futures.

Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
Message-Id: <20200826231947.1145890-1-espindola@scylladb.com>
2020-08-27 15:05:51 +03:00
Avi Kivity
0dcb16c061 Merge "Constify access to token_metadata" from Benny
"
We keep refrences to locator::token_metadata in many places.
Most of them are for read-only access and only a few want
to modify the token_metadata.

Recently, in 94995acedb,
we added yielding loops that access token_metadata in order
to avoid cpu stalls.  To make that possible we need to make
sure they token_metadata object they are traversing won't change
mid-loop.

This series is a first step in ensuring the serialization of
updates to shared token metadata to reading it.

Test: unit(dev)
Dtest: bootstrap_test:TestBootstrap.start_stop_test{,_node}, update_cluster_layout_tests.py -a next-gating(dev)
"

* tag 'constify-token-metadata-access-v2' of github.com:bhalevy/scylla:
  api/http_context: keep a const sharded<locator::token_metadata>&
  gossiper: keep a const token_metadata&
  storage_service: separate get_mutable_token_metadata
  range_streamer: keep a const token_metadata&
  storage_proxy: delete unused get_restricted_ranges declaration
  storage_proxy: keep a const token_metadata&
  storage_proxy: get rid of mutable get_token_metadata getter
  database: keep const token_metadata&
  database: keyspace_metadata: pass const locator::token_metadata& around
  everywhere_replication_strategy: move methods out of line
  replication_strategy: keep a const token_metadata&
  abstract_replication_strategy: get_ranges: accept const token_metadata&
  token_metadata: rename calculate_pending_ranges to update_pending_ranges
  token_metadata: mark const methods
  token_ranges: pending_endpoints_for: return empty vector if keyspace not found
  token_ranges: get_pending_ranges: return empty vector if keyspace not found
  token_ranges: get rid of unused get_pending_ranges variant
  replication_strategy: calculate_natural_endpoints: make token_metadata& param const
  token_metadata: add get_datacenter_racks() const variant
2020-08-22 20:47:45 +03:00
Benny Halevy
2f7c529c1c storage_service: separate get_mutable_token_metadata
Use a different getter for a token_metadata& that
may be changed so we can better synchronize readers
and writers of token_metadata and eventually allow
them to yield in asynchronous loops.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 16:20:34 +03:00
Benny Halevy
e4e4b269c7 everywhere_replication_strategy: move methods out of line
Move methods depending on token_metadata to source file
so we can avoid including token_metadata.hh in header files
where spossible.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 16:20:34 +03:00
Benny Halevy
4dba81cb92 replication_strategy: keep a const token_metadata&
replication strategies don't need to change token_metadata.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 16:20:34 +03:00
Benny Halevy
2fd59e8bba abstract_replication_strategy: get_ranges: accept const token_metadata&
Now that calculate_natural_endpoints can be passed a const token_metadata&

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 16:20:34 +03:00
Benny Halevy
8b63523fb7 token_metadata: rename calculate_pending_ranges to update_pending_ranges
Since it sets the token_metadata_impl's pending ranges.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 16:20:34 +03:00
Benny Halevy
22275e579e token_metadata: mark const methods
Many token_metadata methods do not modify the object
and can be marked as const.

The motivation is to better control who may modify
token_metadata.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 16:20:21 +03:00
Benny Halevy
65d89512d0 token_ranges: pending_endpoints_for: return empty vector if keyspace not found
Rather than creating a bogus empty entry.

With that, it can be marked as const.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 16:16:14 +03:00
Benny Halevy
ca61c2797a token_ranges: get_pending_ranges: return empty vector if keyspace not found
Rather than creating a bogus empty entry.

With that, it can be marked as const.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 16:14:44 +03:00
Benny Halevy
23a0625998 token_ranges: get rid of unused get_pending_ranges variant
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 14:46:53 +03:00
Benny Halevy
b4f76cbb8a replication_strategy: calculate_natural_endpoints: make token_metadata& param const
No replication strategy needs to change token_metadata
when calculating natural endpoints.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 14:38:45 +03:00
Benny Halevy
78f40cac8d token_metadata: add get_datacenter_racks() const variant
Needed for passing a const token_metadata& to
calculate_natural_endpoints methods.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2020-08-20 14:38:45 +03:00
Pavel Emelyanov
4ea63b2211 gossiper: Share the messaging service with snitch
And make snitch use gossiper's messaging, not global

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
2020-08-19 20:50:52 +03:00
Piotr Jastrzebski
c001374636 codebase wide: replace count with contains
C++20 introduced `contains` member functions for maps and sets for
checking whether an element is present in the collection. Previously
`count` function was often used in various ways.

`contains` does not only express the intend of the code better but also
does it in more unified way.

This commit replaces all the occurences of the `count` with the
`contains`.

Tests: unit(dev)

Signed-off-by: Piotr Jastrzebski <piotr@scylladb.com>
Message-Id: <b4ef3b4bc24f49abe04a2aba0ddd946009c9fcb2.1597314640.git.piotr@scylladb.com>
2020-08-15 20:26:02 +03:00
Piotr Jastrzebski
80e3923b3c codebase wide: replace find(...) != end() with contains
C++20 introduced `contains` member functions for maps and sets for
checking whether an element is present in the collection. Previously
the code pattern looked like:

<collection>.find(<element>) != <collection>.end()

In C++20 the same can be expressed with:

<collection>.contains(<element>)

This is not only more concise but also expresses the intend of the code
more clearly.

This commit replaces all the occurences of the old pattern with the new
approach.

Tests: unit(dev)

Signed-off-by: Piotr Jastrzebski <piotr@scylladb.com>
Message-Id: <f001bbc356224f0c38f06ee2a90fb60a6e8e1980.1597132302.git.piotr@scylladb.com>
2020-08-11 13:28:50 +03:00
Asias He
bdaf904864 storage_service: Improve log on removing pending replacing node
The log "removing pending replacing node" is printed whenever a node
jumps to normal status including a normal restart. For example, on
node1, we saw the following when node2 restarts.

[shard 0] storage_service - Node 127.0.0.2 state jump to normal
[shard 0] storage_service - Remove node 127.0.0.2 from pending replacing endpoint

This is confusing since no node is really being replaced.

To fix, log only if a node is really removed from the pending replacing
nodes.

In addition, since do_remove_node will call del_replacing_endpoint,
there is no need to call del_replacing_endpoint again in
storage_service::handle_state_normal after do_remove_node.

Fixes #6936
2020-07-28 11:51:22 +03:00
Tomasz Grabiec
f20c77d0f8 Merge "Make handle_state_left more robust when tokens are empty" from Asias
1. storage_service: Make handle_state_left more robust when tokens are empty

In case the tokens for the node to be removed from the cluster are
empty, log the application_state of the leaving node to help understand
why the tokens are empty and try to get the tokens from token_metadata.

2. token_metadata: Do not throw if empty tokens are passed to remove_bootstrap_tokens

Gossip on_change callback calls storage_service::excise which calls
remove_bootstrap_tokens to remove the tokens of the leaving node from
bootstrap tokens. If empty tokens, e.g., due to gossip propagation issue
as we saw in #6468, are passed
to remove_bootstrap_tokens, it will throw. Since the on_change callback
is marked as noexcept, such throw will cause the node to terminate which
is an overkill.

To avoid such error causing the whole cluster to down in worse cases,
just log the tokens are empty passed to remove_bootstrap_tokens.

Refs #6468
2020-07-14 13:19:45 +02:00
Asias He
116f6141d5 token_metadata: Fix incorrect log in update_normal_tokens
Currently, when update_normal_tokens is called, a warning logged.

   Token X changing ownership from A to B

It is not correct to log so because we can call update_normal_tokens
against a temporary token_metadata object during topology calculation.

Refs: #6437
2020-07-14 14:13:37 +03:00
Asias He
027fa022e2 token_metadata: Do not throw if empty tokens are passed to remove_bootstrap_tokens
Gossip on_change callback calls storage_service::excise which calls
remove_bootstrap_tokens to remove the tokens of the leaving node from
bootstrap tokens. If empty tokens, e.g., due to gossip propagation issue
as we saw in https://github.com/scylladb/scylla/issues/6468, are passed
to remove_bootstrap_tokens, it will throw. Since the on_change callback
is marked as noexcept, such throw will cause the node to terminate which
is an overkill.

To avoid such error causing the whole cluster to down in worse cases,
just log the tokens are empty passed to remove_bootstrap_tokens.

Refs #6468
2020-07-06 14:28:23 +08:00
Asias He
94995acedb abstract_replication_strategy: Add get_ranges_in_thread
Add a version that runs inside a seastar thread. The benefit is that
get_ranges can yield to avoid stalls.

Refs #6662
2020-07-01 15:00:01 +08:00
Calle Wilund
7ce4a8b458 token_metadata: Prune empty racks on endpoint change
Fixes #6459

When moving or removing endpoints, we should ensure
that the set of available racks reflect the nodes
known, i.e. match what would be the result of a
reboot + create sets initially.
Message-Id: <20200519153300.15391-1-calle@scylladb.com>
2020-05-20 13:35:08 +02:00
Asias He
b640614aa6 abstract_replication_strategy: Add get_ranges which takes token_metadata
It is useful when the caller wants to calculate ranges using a
custom token_metadata.

It will be used soon in do_rebuild_replace_with_repair for replace
operation.

Refs: #5482
2020-04-30 10:22:30 +08:00
Asias He
37d3d3e051 abstract_replication_strategy: Add get_natural_endpoints_without_node_being_replaced
Similar to natural_endpoints but with the node being replaced filtered out.

Refs: #5482
2020-04-30 10:22:30 +08:00
Asias He
1a75a60cfc abstract_replication_strategy: Add allow_remove_node_being_replaced_from_natural_endpoints
Decide if the replication strategy allow removing the node being replaced from
the natural endpoints when a node is being replaced in the cluster.
LocalStrategy is the not allowed to do so because it always returns the node
itself as the natural_endpoints and the node will not appear in the
pending_endpoints.

It is needed by the "Make replacing node take writes" work.

Refs: #5482
2020-04-30 10:22:30 +08:00
Asias He
bd6691301e token_metadata: Calculate pending ranges for replacing node
It will be needed soon for making replace node take writes.

Refs: #5482
2020-04-29 16:02:10 +08:00
Kamil Braun
1f7290a0ff versioned_value: remove versioned_value::factory class
If there was a Most Useless Abstraction award, this would be a good
candidate.
2020-04-20 12:57:16 +02:00
Avi Kivity
88ade3110f treewide: replace calls to engine().some_api() with some_api()
This removes the need to include reactor.hh, a source of compile
time bloat.

In some places, the call is qualified with seastar:: in order
to resolve ambiguities with a local name.

Includes are adjusted to make everything compile. We end up
having 14 translation units including reactor.hh, primarily for
deprecated things like reactor::at_exit().

Ref #1
2020-04-05 12:46:04 +03:00
Avi Kivity
1799cfa88a logalloc: use namespace-scope seastar::idle_cpu_handler and related rather than reactor scope
This allows us to drop a #include <reactor.hh>, reducing compile time.

Several translation units that lost access to required declarations
are updated with the required includes (this can be an include of
reactor.hh itself, in case the translation unit that lost it got it
indirectly via logalloc.hh)

Ref #1.
2020-04-05 12:45:08 +03:00
Rafael Ávila de Espíndola
c5795e8199 everywhere: Replace engine().cpu_id() with this_shard_id()
This is a bit simpler and might allow removing a few includes of
reactor.hh.

Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
Message-Id: <20200326194656.74041-1-espindola@scylladb.com>
2020-03-27 11:40:03 +03:00
Rafael Ávila de Espíndola
c0072eab30 everywhere: Be more explicit that we don't want std::make_shared
If sstring is made an alias to std::string ADL causes std::make_shared
to be found. Explicitly ask for ::make_shared.

Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
2020-03-10 13:13:48 -07:00
Konstantin Osipov
ac6f64a885 locator: correctly select endpoints if RF=0
SimpleStrategy creates a list of endpoints by iterating over the set of
all configured endpoints for the given token, until we reach keyspace
replication factor.
There is a trivial coding bug when we first add at least one endpoint
to the list, and then compare list size and replication factor.
If RF=0 this never yields true.
Fix by moving the RF check before at least one endpoint is added to the
list.
Cassandra never had this bug since it uses a less fancy while()
loop.

Fixes #5962
Message-Id: <20200306193729.130266-1-kostja@scylladb.com>
2020-03-08 16:53:01 +02:00
Piotr Sarna
22798f7b7b locator: fix validating replication factor
In order to properly validate not only network topology strategy,
but also other strategies, the checks are moved straight to
validate_replication_factor().
Also, the test case is extended with a too long integer
and a check for SimpleStrategy replication factor.

Fixes #3801
Tests: unit(dev)

Message-Id: <e0c3c3c36c589e1d440c9708a6dce820c111b8da.1583483602.git.sarna@scylladb.com>
2020-03-06 10:39:34 +02:00
Piotr Sarna
5b7a35e02b network_topology_strategy: validate integers
In order to prevent users from creating a network topology
strategy instance with invalid inputs, it's not enough to use
std::stol() on the input: a string "3abc" still returns the number '3',
but will later confuse cqlsh and other drivers, when they ask for
topology strategy details.
The error message is now more human readable, since for incorrect
numeric inputs it used to return a rather cryptic message:
    ServerError: stol()
This commit fixes the issue and comes with a simple test.

Fixes #3801
Tests: unit(dev)
Message-Id: <7aaae83d003738f047d28727430ca0a5cec6b9c6.1583478000.git.sarna@scylladb.com>
2020-03-06 09:50:33 +02:00
Avi Kivity
91c4409376 locator: token_metadata: remove unused include "query-request.hh"
sstable_datafile_test.cc lost access to interval_map (via
position_in_partition.hh), so it now includes that directly.
2020-02-14 20:46:25 +02:00
Avi Kivity
bee1cc42fe locator: token_metadata: move implementation classes to .cc
With pimplification complete, move the implementation classes to .cc and
remove boost/icl includes.
2020-02-14 20:34:44 +02:00
Avi Kivity
ef41b45142 locator: token_metadata: pimplify tokens_iterator
Because tokens_iterator refers to token_metadata_impl, the latter cannot
be moved out-of-line. So this patch pimplifies tokens_iterator as well.
2020-02-14 20:29:14 +02:00
Avi Kivity
9425e9c13d locator: token_metadata: make token_metadata_impl::tokens_iterator a non-nested class
In order to pimplify token_metadata_impl::tokens_iterator, we must make it
a non-nested class, since eventually token_metadata_impl will be an incomplete
class for users and nested classes cannot be forward declared. So this patch
makes it a non-nested class. Two inline functions that referred to it were
moved out of class scope so they can see the definition.

No functional changes.
2020-02-14 20:29:13 +02:00
Avi Kivity
6d53f240d1 locator: token_metadata: pimplify
token_metadata is a heavyweight class, with heavyweight include
dependencies (icl, which has tens of thousands of lines in headers),
heavyweight methods, but it rarely used. So it is a classic candidate
for pimmplication.

This patch splits off the implementation into token_metadata_impl
and leaves token_metadata as a forwarding class. Actual movement
of the code is left to a later patch to ease review.

Notes:
 - some constructors were made public due to limitations of std::make_unique
 - a few token_metadata methods pass *this along to external functions, so we
   now pass the holder object as "unpimplified_this" to support this.
2020-02-14 20:29:12 +02:00
Avi Kivity
90a3670952 locator: token_metadata: use non-deduced return type for ring_range()
Deduced return types are user hostile as the user has to look at the
implementation in order to understand what the return type is.
2020-02-14 15:44:46 +02:00
Kamil Braun
1a56310687 locator: remove get_shard_count and get_ignore_msb_bits from snitch
Snitch forms a class hierarchy which get_shard_count and
get_ignore_msb_bits ignore (their returned values only depend on the
gossiper's state).

Besides, these functions just don't belong there.
Snitch has nothing to do with shard_count or ignore_msb_bits.
2020-01-30 11:10:08 +01:00
Kamil Braun
96e5d6c924 token_metadata: add count_normal_token_owners method 2020-01-30 11:10:08 +01:00
Rafael Ávila de Espíndola
845116dfaf gossiper: Store subscribers in an atomic_vector
The new guarantees are a bit better IMHO:

Once a subscriber is removed, it is never notified. This was not true
in the old code since it would iterate over a copy that would still
have that subscriber.

Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
2020-01-22 08:16:03 -08:00
Rafael Ávila de Espíndola
085544f054 locator: Return future from i_endpoint_snitch::reload_gossiper_state
This just reduces the noise of a followup patch.

Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
2020-01-22 08:16:03 -08:00
Pavel Emelyanov
6e06c88b4c token_metadata: Remove unused helper
There are two _identical_ methods in token_metadata class:
get_all_endpoints_count() and number_of_endpoints().
The former one is used (called) the latter one is not used, so
let's remove it.

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
2019-12-23 14:22:43 +02:00