Commit Graph

26204 Commits

Author SHA1 Message Date
Botond Dénes
d246e2df0a reader_concurrency_semaphore: add dump_diagnostics()
Allow semaphore related tests to include a diagnostics printout in error
messages to help determine why the test failed.
2021-04-26 15:56:56 +03:00
Botond Dénes
caaa8ef59a reader_permit: always forward resources
This commit conceptually reverts 4c8ab10. Said commit was meant to
prevent the scenario where memory-only permits -- those that don't pass
admission but still consume memory -- completely prevent the admission
of reads, possibly even causing a deadlock because a permit might even
blocks its own admission. The protection introduced by said commit
however proved to be very problematic. It made the status of resources
on the permit very hard to reason about and created loopholes via which
permits could accumulate without tracking or they could even leak
resources. Instead of continuing to patch this broken system, this
commit does away with this "protection" based on the observation that
deadlocks are now prevented anyway by the admission criteria introduced
by 0fe75571d9, which admits a read anyway when all the initial count
resources are available (meaning no admitted reader is alive),
regardless of availability of memory.
The benefits of this revert is that the semaphore now knows about all
the resources and is able to do its job better as it is not "lied to"
about resource by the permits. Furthermore the status of a permit's
resources is much simpler to reason about, there are no more loopholes
in unexpected state transitions to swallow/leak resources.
To prove that this revert is indeed safe, in the next commit we add
robust tests that stress test admission on a highly contested semaphore.
This patch also does away with the registered/admitted differentiation
of permits, as this doesn't make much sense anymore, instead these two
are unified into a single "active" state. One can always tell whether a
permit was admitted or not from whether it owns count resources anyway.
2021-04-26 15:56:56 +03:00
Botond Dénes
2b66f7222e reader_concurrency_semaphore: inactive_read_handle: abandon(): close reader
fa43d7680 recently introduced mandatory closing of readers before they
are destroyed. One reader destroy path that was left not closing the
reader before destruction is `inactive_reader_handle::abandon()`. This
path is executed when the handle is destroyed while still referring to a
non-evicted inactive read. This patch fixes it up to close the reader
and adds a small unit test which checks that this happens.
2021-04-26 15:56:54 +03:00
Avi Kivity
5801c93715 utils: rjson: convert enable_if to concept
Simpler and easier to understand. Vague comment about enable_if
removed.

Closes #8405
2021-04-25 21:53:46 +03:00
Botond Dénes
f7f5fca5a8 Add very basic coverage report generation support
This patch introduces the most basic bare infrastructure to generate
coverage report as well as a guide on how to manually generate them.
Although this barely qualifies as "support", it already allows one to
generate a coverage report with the help of this guide.

One immediate limitation of this patch is that it only supports clang,
which is not a terrible problem, given that its our main compiler
currently.

Future patches will build on this to incrementally improve and
automate this:
* Provide script to automatically merge profraw files and generate html
  report from it.
* Integrate into test.py, adding a flag which causes it to generate
  a coverage report after a run.
* Support GCC too, but at least auto-detect whether clang is used or
  not.

Signed-off-by: Botond Dénes <bdenes@scylladb.com>
Message-Id: <20210423140100.659452-1-bdenes@scylladb.com>
2021-04-25 15:59:20 +03:00
Avi Kivity
fa43d7680c Merge "Close flat mutation readers" from Benny
"
This patchset adds future-returning close methods to all
flat_mutation_reader-s and makes sure that all readers
are explicitly closed and waited for.

The main motivation for doing so is for providing a path
for cancelling outstanding i/o requests via a the input_stream
close (See https://github.com/scylladb/seastar/issues/859)
and wait until they complete.

Also, this series also introduces a stop
method to reader_concurrency_semaphore to be used when
shutting down the database, instead of calling
clear_inactive_readers in the database destructor.

The series does not change microbenchmarks performance in a significant way.
It looks like the results are within the tests' jitter.

- perf_simple_query: (in transactions per second, more is better)
before: median 184701.83 tps (90 allocs/op, 20 tasks/op)
after:  median 188970.69 tps (90 allocs/op, 20 tasks/op) (+2.3%)

- perf_mutation_readers: (in time per iteration, less is better)
combined.one_row                               65.042ns  -> 57.961ns  (-10.9%)
combined.single_active                         46.634us  -> 46.216us  ( -0.9%)
combined.many_overlapping                      364.752us -> 371.507us ( +1.9%)
combined.disjoint_interleaved                  43.634us  -> 43.448us  ( -0.4%)
combined.disjoint_ranges                       43.011us  -> 42.991us  ( -0.0%)
combined.overlapping_partitions_disjoint_rows  57.609us  -> 58.820us  ( +2.1%)
clustering_combined.ranges_generic             93.464ns  -> 96.236ns  ( +3.0%)
clustering_combined.ranges_specialized         86.537ns  -> 87.645ns  ( +1.3%)
memtable.one_partition_one_row                 903.546ns -> 957.639ns ( +6.0%)
memtable.one_partition_many_rows               6.474us   -> 6.444us   ( -0.5%)
memtable.one_large_partition                   905.593us -> 878.271us ( -3.0%)
memtable.many_partitions_one_row               13.815us  -> 14.718us  ( +6.5%)
memtable.many_partitions_many_rows             161.250us -> 158.590us ( -1.6%)
memtable.many_large_partitions                 24.237ms  -> 23.348ms  ( -3.7%)
average                                        -0.02%

Fixes #1076
Refs #2927

Test: unit(release, debug)
Perf: perf_mutation_readers, perf_simple_query (release)
Dtest: next-gating(release),
       materialized_views_test:TestMaterializedViews.interrupt_build_process_and_resharding_max_to_half_test repair_additional_test:RepairAdditionalTest.repair_disjoint_row_3nodes_diff_shard_count_test(debug)
"

* tag 'flat_mutation_reader-close-v7' of github.com:bhalevy/scylla: (94 commits)
  mutation_reader: shard_reader: get rid of stop
  mutation_reader: multishard_combining_reader: get rid of destructor
  flat_mutation_reader: abort if not closed before destroyed
  flat_mutation_reader: require close
  repair: row_level_repair: run: close repair_meta when done
  repair: repair_reader: close underlying reader on_end_of_stream
  perf: everywhere: close flat_mutation_reader when done
  test: everywhere: close flat_mutation_reader when done
  mutation_partition: counter_write_query: close reader when done
  index: built_indexes_reader: implement close
  mutation_writer: multishard_writer: close readers when done
  mutation_writer: feed_writer: close reader when done
  table: for_all_partitions_slow: close iteration_step reader when done
  view_builder: stop: close all build_step readers
  stream_transfer_task: execute: close send_info reader when done
  view_update_generator: start: close staging_sstable_reader when done
  view: build_progress_virtual_reader: implement close method
  view: generate_view_updates: close builder readers when done
  view_builder: initialize_reader_at_current_token: close reader before reassigning it
  view_builder: do_build_step: close build_step reader when done
  ...
2021-04-25 13:53:11 +03:00
Avi Kivity
54b76e82bc Merge "Make migration manager main-local" from Pavel
"
There are few places left that call for migration manager
by global reference. This set patches all those places
and makes the migration manager a service that locally
lives in main(). Surprisingly, the largest changes are to
get rid of global migration manager calls from ... the
migration manager itself.

Two tricks here. First, repair code gets its private global
migration manager pointer. That's not nice, but it aligned
with current repair design -- all its references are now
"global". Some day they all will be moved into sharded
repair service, for now these globals just describe the real
dependencies of the repair code.

Second is storage proxy that needs to call migration manager
to get schema. Proper layering makes migration manager sit
on top of storage proxy, so the direct back-reference is
not nice. To overcome this the proxy gets migration manager's
shared_from_this() pointer and drops all of them on stop.
This makes sure that by the time migration manager stops
no references from proxy exist.

tests: unit(dev), start-stop, start-drain-stop
"

* 'br-turn-migration-manager-local' of https://github.com/xemul/scylla: (21 commits)
  migration_manager: Make it main-local
  tests: Have own migration manager instances
  tests: Use migration_manager from cql_test_env
  migration_manager: Call maybe_sync from this
  migration_manager: Make get_schema_for_... methods
  migration_manager: Hide get_schema_definition
  streaming: Keep migration_manager ptr in rpc lambdas
  storage_proxy: Keep migration_manager ptr in rpc lambdas
  streaming: Get migration_manager shared_ptr in messaging
  storage_proxy: Get migration_manager shared_ptr in messaging
  migration_manager: Make maybe_sync a method
  migration_manager: Open-code merge lambda
  migration_manager: Turn do_announce_new_type non-static
  migration_manager: Make announce() non-static method
  storage_servive: Use local migration manager
  storage_service: Keep migration manager on board
  migration_manager: Use 'this' where appropriate
  repair: Use private migration manager pointer
  repair: Keep private sharded migration manager pointer
  redis: Carry sharded migration manager over init
  ...
2021-04-25 13:29:16 +03:00
Nadav Har'El
de938eba8c Reduce dependency on header utils/rjson.hh
If utils/rjson.hh is modified, 300 (!) source files get recompiled.
This is frustrating for anyone working on this header file (like me).
Moreover - utils/rjson.hh includes the large rapidjson header
files (rapidjson is a header-only library!), slowing the compilation
all these 300 files.

It turns out most includers utils/rjson.hh get it because
column_computation.hh includes it. But the fact that column
computations are serialized as JSON are an internal implementation
detail that the users of this header don't need to know - and they
care even less that this JSON implementation uses utils/rjson.hh.

So in this patch column_computation.hh no longer includes rjson.hh,
and no longer exposes a method taking a rjson::value that was never
used outside the implementation.

After this patch, touching utils/rjson.hh only recompiles 21 files.

Refs #1

Signed-off-by: Nadav Har'El <nyh@scylladb.com>
Message-Id: <20210422183526.114366-1-nyh@scylladb.com>
2021-04-25 13:20:51 +03:00
Benny Halevy
5ca8f28297 storage_service: load_new_sstables: log success message as info, not warning
Success is important, but nothing to be warned about.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Message-Id: <20210425070909.476226-1-bhalevy@scylladb.com>
2021-04-25 12:39:47 +03:00
Benny Halevy
6e62ec8c24 mutation_reader: shard_reader: get rid of stop
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
fc5e4688db mutation_reader: multishard_combining_reader: get rid of destructor
Now that the multishard_combining_reader is guaranteed to be called
there is no longer need for stopping the shard readers
in the destructor.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
b134640829 flat_mutation_reader: abort if not closed before destroyed
The motivation to abort if the reader is not closed before its destroyed
is mainly driven by:
1. Aborting will force us find and fix missing closes.
Otherwise, log warnings can easily be lost in the noise.
(ERRORs however are caught by dtests but won't be necessarily
caught in SCT / production environments)

2. Following patches remove existing cleanup code
in destructors that is not needed once close() is mandated.
If we don't abort on missing close we'll have to keep maintaining
both cleanup paths forever.

3. Not enforcing close exposes us to leaks and potential
use-after-free from background tasks that are left behind.
We want to stop guranteeing the safety of the background tasks
post close().

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
5b22731f9a flat_mutation_reader: require close
Make flat_mutation_reader::impl::close pure virtual
so that all implementations are required to implemnt it.

With that, provide a trivial implementation to
all implementations that currently use the default,
trivial close implementation.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
77cc694a08 repair: row_level_repair: run: close repair_meta when done
Always close repair_meta (that closes its reader).

Proper closing is done via the repair_meta::stop path.

Ignore any errors when auto-closing in a deferred action
since there is nothing else we can do at this point.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
0c19f788e5 repair: repair_reader: close underlying reader on_end_of_stream
Need to close the reader before reassigning it with
an empty f_m_r.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
391f942b2a perf: everywhere: close flat_mutation_reader when done
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
aa5289f255 test: everywhere: close flat_mutation_reader when done
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
7427b60caf mutation_partition: counter_write_query: close reader when done
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
2fa8b3b84e index: built_indexes_reader: implement close
Close underlying reader.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
e453f890f2 mutation_writer: multishard_writer: close readers when done
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
64c5b7fda6 mutation_writer: feed_writer: close reader when done
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
825acd4031 table: for_all_partitions_slow: close iteration_step reader when done
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
dad6c94476 view_builder: stop: close all build_step readers
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
6082d854f9 stream_transfer_task: execute: close send_info reader when done
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
02d74e1530 view_update_generator: start: close staging_sstable_reader when done
The staging_sstable_reader has to be closed before it's destroyed.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
1e1c8ea824 view: build_progress_virtual_reader: implement close method
Close underlying reader.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
2d8b00f2d8 view: generate_view_updates: close builder readers when done
Make sure to close the builder's _updates and optional _existings
readers before they are destroyed.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
652ba714fe view_builder: initialize_reader_at_current_token: close reader before reassigning it
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
7093610931 view_builder: do_build_step: close build_step reader when done
Make sure to close the build_step reader before destroying it.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
51c96d405d mutation_reader: evictable_reader: fill_buffer: make sure to close the reader
If reader.fill_buffer() fails, we will not call `maybe_pause` and the
reader will be destroyed, so make sure to close it.

Otherwise, the reader is std:move'ed to `maybe_pause` that either
paused using register_inactive_read or further std::move'ed to _reader,
in both cases it doesn't need to be closed.  `with_closeable`
can safely try to close the moved-from reader and do nothing in this
case, as the f_m_r::impl was already moved away.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
7c7569f0ad querier_cache: implement stop
Close the _closing_gate to wait on background
close of dropped queries, and close all remaining queriers.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
87c62b5f59 test: querier_cache_test: close looked up querier
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
3e7075a739 compaction: setup: fixup indentation
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
90a7a8ff0e compaction: close reader when done consuming
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
07f34b4a32 querier_cache: lookup_querier: close the querier before dropping it
Make sure to close the dropped querier before it's destroyed.
The operation is moved to the background so not to penelize
the common path.

A following patch will add a querier_cache::close() method
that will close _closing_gate to wait on the querier close
(among other things it needs to wait on :)).

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
4a0abc7b9c querier_cache: lookup_querier: define as a private method
In preparation to closing the querier in the background
before dropping it.

With that, stats need not be passed as a parameter,
but rather the _stats member can be used directly.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
fa6d6c17f2 mutation_partition: mark query_result_builder constructor noexcept
It is trivially so.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
320cb67b08 table: query, mutation_query: close querier when done
Make sure to close the querier and subsequently its reader before
destroying it (unless it was moved).

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
8b8c721431 querier: add close method
Depening on the variant _reader contents, either close
the reader or unregister the inactive reader and close it.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
3f00c21481 querier_cache: evict: close evicted reader
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
0d8d56c36f querier: coroutinize evict methods
Instead of calling a lambda function for each index
simply iterate over all indices and use co_await / co_return
in the inner loop.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
2f9cf01aa7 querier_cache: futurize evict api
Prepare for futurizing the lower-level inactive reads api.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
57f921de4f database: streaming_reader_lifecycle_policy: destroy_reader: close inactive reader
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
29b2b1f8dd reader_lifecycle_policy: close inactive_read
Make sure to close the unregistered inactive_read
before it's destroyed, if the unregistered reader_opt
is engaged.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
a144819683 reader_concurrency_semaphore: unregister_inactive_read: close reader also on internal error
"forward" the unregister to the other semaphore
in case on_internal_error throws rather than aborting.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
c8e30db5db reader_concurrency_semaphore: close evicted reader
Close readers in the background:
- evicted based on ttl, or
- those that weren't admitted by register_inactive_read
- those that are destoryed in clear_inactive_reads.

Use a gate for waiting on these background closes in stop().

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
be1cafc1a5 reader_concurrency_semaphore: do_wait_admission: close evicted readers
enqueue_waiter before evicting readers and start a loop in the
background to dequeue and close inactive_readers until
either the _wait_list is empty or there are no more inactive_readers
to evict.

We admit the read synchronously only if the wait_list is empty
and the semaphore has_available_units to statisfy admission.

We need to enqueue the reader before starting to evict readers
to make sure any evicted resources are assigned to the
waiter at the head of the queue and not "stolen"
in case we yield and some other caller grabs them.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
43bf0f9356 reader_concurrency_semaphore: add stop method
In addition to clear_inactive_reads, that's currently called when
the database object is destroyed, introduce a stop() method that will:
1. wait on all background closes of inactive_reads.
2. close all present inactive_reads and waits on their close.
3. signal waiters on the wait_list via broken() with a proper
   exception indicating that the semaphore was closed.

In addition, assert in the semaphore's destructor
that it has no remaining inactive reads.

Stop must be called from whoever owns the r_c_s.
Mainly, from database::stop.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
2f4134e1cc reader_concurrency_semaphore: broken: make broken_semaphore the default exception
Rather than explcitily generating it by all callers
and then not using the argument at all.

Prepare for providing a different exception_ptr
from a stop() path to be introduced in the next patch.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00
Benny Halevy
cd0991f28d multishard_mutation_query: read_context::stop: properly close unregistered inactive_reads
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-04-25 11:35:07 +03:00