Commit Graph

303 Commits

Author SHA1 Message Date
Calle Wilund
b3c35f9ec0 commitlog: coroutinize commitlog::create_commitlog 2021-07-19 08:27:30 +00:00
Calle Wilund
ef471d0a93 commitlog: coroutinize commitlog::add_entries 2021-07-19 08:27:30 +00:00
Calle Wilund
96434b1b12 commitlog: coroutinize commitlog::add_entry 2021-07-19 08:27:30 +00:00
Calle Wilund
e16cff6952 commitlog: coroutinize commitlog::add 2021-07-19 08:27:30 +00:00
Calle Wilund
da360fb841 commitlog: change entry_writer usage to reference
Calling frames keeps object alive in all paths. Use references in
allocate()/allocate_when_possible()
2021-07-19 08:27:30 +00:00
Calle Wilund
42bfae513a commitlog: coroutinize segment_manager::clear 2021-07-19 08:27:30 +00:00
Calle Wilund
554a09baab commitlog: coroutinize segment_manager::do_pending_deletes 2021-07-19 08:27:30 +00:00
Calle Wilund
9e18cf3f5f commitlog: coroutinize segment_manager::delete_file 2021-07-19 08:27:30 +00:00
Calle Wilund
ca65387c53 commitlog: coroutinize segment_manager::shutdown 2021-07-19 08:27:30 +00:00
Calle Wilund
4678d1fbec commitlog: coroutinize segment_manager::shutdown_all_segments 2021-07-19 08:27:30 +00:00
Calle Wilund
2f048e658b commitlog: coroutinize segment_manager::sync_all_segments 2021-07-19 08:27:30 +00:00
Calle Wilund
ad4e4e9ee4 commitlog: coroutinize segment_manager::clear_reserve_segments 2021-07-19 08:27:30 +00:00
Calle Wilund
ec430807fc commitlog: coroutinize segment_manager::active_segment 2021-07-19 08:27:30 +00:00
Calle Wilund
13bba1ef39 commitlog: coroutinize segment_manager::new_segment 2021-07-19 08:27:30 +00:00
Calle Wilund
ccd34203dc commitlog: coroutinize segment_manager::allocate_segment 2021-07-19 08:27:30 +00:00
Calle Wilund
f5de830f0c commitlog: coroutinize segment_manager::rename_file 2021-07-19 08:27:30 +00:00
Calle Wilund
011bc68209 commitlog: coroutinize segment_manager::init 2021-07-19 08:27:30 +00:00
Calle Wilund
04c725b29c commitlog: coroutinize segment_manager::list_descriptors 2021-07-19 08:27:30 +00:00
Calle Wilund
d514fc5822 commitlog: coroutinize segment_manager::replenish_reserve 2021-07-19 08:27:30 +00:00
Calle Wilund
d4bd17d577 commitlog: coroutinize segment::shutdown 2021-07-19 08:17:33 +00:00
Calle Wilund
e9820827e3 commitlog: coroutinize segment::close 2021-07-19 08:17:33 +00:00
Calle Wilund
999701a8ee commitlog: coroutinize segment::batch_cycle 2021-07-19 08:17:33 +00:00
Calle Wilund
cef7ee2014 commitlog: coroutinize segment::do_flush 2021-07-19 08:17:33 +00:00
Calle Wilund
1a76d735f2 commitlog: coroutinize segment::flush 2021-07-19 08:17:33 +00:00
Calle Wilund
0b1e2084ce commitlog: coroutinize segment::cycle 2021-07-19 08:17:33 +00:00
Calle Wilund
79b9cb1e5c commitlog: coroutinize allocate_when_possible 2021-07-19 08:17:33 +00:00
Calle Wilund
e545b382bd commitlog: coroutinize segment::allocate 2021-07-19 08:17:33 +00:00
Calle Wilund
ce45ffdffb commitlog: Use defensive copies of segment list in iterations
Fixes #8952

In 5ebf5835b0 we added a segment
prune after flushing, to deal with deadlocks in shutdown.
This means that calls that issue sync/flush-like ops "for-all",
need to operate on a defensive copy of the list.

Closes #8980
2021-07-07 13:30:37 +02:00
Calle Wilund
a40b6a2f54 commitlog: Use disk file alignment info (with lower value if possible)
Previously, the disk block alignment of segments was hardcoded (due to
really old code). Now we use the value as declared in the actual file
opened. If we are using a previously written file (i.e. o_dsync), we
can even use the sometimes smaller "read" alignment.

Also allow config to completely override this with a disk alignment
config option (not exposed to global config yet, but can be).

v2:
* Use overwrite alignment if doing only overwrite
* Ensure to adjust actual alignment if/when doing file wrapping

v3:
* Kill alignment config param. Useless and unsafe.

Closes #8935
2021-06-29 16:00:49 +03:00
Calle Wilund
d6113912cd commitlog: Add waitable future for background sync/flush
Commitlog timer issues un-waited syncs on all segments. If such
a sync takes too long we can end up keeping a segment alive across
a shutdown, causing the file to be left on disk, even if actually
clean.

This adds a future in segment_manager that is "chained" with all
active syncs (hopefully just one), and ensures we wait for this
to complete in shutdown, before pruning and deleting segments
2021-06-21 06:01:19 +00:00
Calle Wilund
14559b5a86 commitlog: abort queues on shutdown
In case we only have a single segment active when shutting down,
the replenisher can be blocked even though we manually flush-deleted.

Add a signal type and abort queues using this to wake up waiter and
force them to check shutdown status.
2021-06-16 15:35:56 +00:00
Calle Wilund
227b573cdf commitlog: break out "abort" calls into member functions 2021-06-16 15:35:56 +00:00
Calle Wilund
5cd9691f00 commitlog: Do explicit discard+delete in shutdown
When we are shutting down, before trying to close the gate,
we should issue a discard to ensure waking up the replenish task
2021-06-16 15:35:56 +00:00
Calle Wilund
03b8baaa8d commitlog: Recycle or not should not depend on shutdown state
If we are using recycling, we should always use recycle in
delete_segments, otherwise we can cause deadlock with replenish
task, since it will be waiting for segment, then shutdown is set,
and we are called, and can't fulfil the alloc -> deadlock
2021-06-16 15:35:56 +00:00
Calle Wilund
5ebf5835b0 commitlog: Issue discard_unused_segments on segment::flush end IFF deletable
If a segments, when finishing a flush call, is deletable, we should issue
a manual call to discard function (which moves deleteable segments off
segment list) asap, since we otherwise are dependent on more calls
from flush handlers (memtable flush). And since we could have blocked
segment allocation, this can cause deadlocks, at least in tests.
2021-06-16 15:35:56 +00:00
Calle Wilund
cbddcf46aa commitlog: Flush all segments if we only have one.
Handle test cases with borked config so we don't deadlock
in cases where we only have one segment in a commitlog
2021-06-16 15:35:56 +00:00
Calle Wilund
a0f559a44c commitlog: Always force flush if segment allocation is waiting
Refs #8270

If segement allocation is blocked, we should bypass all thresholds
and issue a flush of as much as possible.
2021-06-16 15:35:56 +00:00
Calle Wilund
bcf4d07f0b commitlog: Include segment wasted (slack) size in footprint check
Refs #8270

Since segment allocation looks at actual disk footprint, not active,
the threshold check in timer task should include slack space so we
don't mistake sparse usage for space left.
2021-06-16 15:35:56 +00:00
Calle Wilund
1187f5c181 commitlog: Adjust (lower) usage threshold
Refs #8270

Try to ensure we issue a flush as soon as we are allocating in the
last allowable segment, instead of "half through". This will make
flushing a little more eager, but should reduce latencies created
by waiting for segment delete/recycle on heavy usage.
2021-06-16 15:35:56 +00:00
Avi Kivity
a55b434a2b treewide: extent copyright statements to present day 2021-06-06 19:18:49 +03:00
Benny Halevy
946f9d9c83 commitlog: segment_manager::shutdown: abort on errors
Currently, if sync_all_segments fails during shutdown,
_shutdown is never set, causing replenish_reserve
to hang, as possibly seen in #8577.

It is better if scylla aborts on critical errors
during shutdown rather than just hang.

Refs #8577

Test: unit(dev)
DTest: commitlog_test.py
Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-05-04 10:00:03 +03:00
Benny Halevy
f01307d816 commitlog: allocate_segment_ex: make_checked_file
To make sure no errors writing to commitlog are tolerated.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
2021-05-04 09:00:58 +03:00
Benny Halevy
705f9c4f79 commitlog: segment_manager: max_size must be aligned
This was triggered by the test_total_space_limit_of_commitlog dtest.
When it passes a very large commitlog_segment_size_in_mb (1/6th of the
free memory size, in mb), segment_manager constructor limits max_size
to std::numeric_limits<position_type>::max() which is 0xffffffff.

This causes allocate_segment_ex to loop forever when writing the segment
file since `dma_write` returns 0 when the count is unaligned (seen 4095).

The fix here is to select a sligtly small maxsize that is aligned
down to a multiple of 1MB.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Message-Id: <20210407121059.277912-1-bhalevy@scylladb.com>
2021-04-11 13:17:50 +03:00
Calle Wilund
d734f85280 commitlog: Add signalling to recycle queue iff we fail to recycle
Fixes #8376

If a recycle should fail, we will sort of handle it by deleting
the segment, so no leaks. But if we have waiter(s) on the recycle
queue, we could end up deadlocked/starved because nothing is
incoming there.

This adds an abort of the queue iff we failed and no objects are
available. This will wake up any waiter, and he should retry,
and hopefully at least be able to create a new segment.
We then reset the queue to a new one. So we can go on.

v2:
* Forgot to reset queue
v3:
* Nicer exception handling in allocate_segment_ex
2021-04-06 16:38:14 +00:00
Calle Wilund
15dd76f0c2 commitlog: Fix race and edge condition in delete_segments
Fixes #8363

Delete segements has two issues when running with size-limited
commit log and strict adherence to said limit.

1.) It uses parallel processing, with deferral. This means that
    the disk usage variables it looks at might not be fully valid
    - i.e. we might have already issued a file delete that will
    reduce disk footprint such that a segment could instead be
    recycled, but since vars are (and should) only updated
    _post_ delete, we don't know.
2.) It does not take into account edge conditions, when we only
    delete a single segment, and this segment is the border segment
    - i.e. the one pushing us over the limit, yet allocation is
    desperately waiting for recycling. In this case we should
    allow it to live on, and assume that next delete will reduce
    footprint. Note: to ensure exact size limit, make sure
    total size is a multiple of segment size.

Fixed by
a.) Doing delete serialized. It is not like being parallel here will
    win us speed awards. And now we can know exact footprint, and
    how many segments we have left to delete
b.) Check if we are a block across the footprint boundry, and people
    might be waiting for a segment. If so, don't delete segment, but
    recycle.

As a follow-up, we should probably instead adjust the commitlog size
limit (per shard) to be a multiple of segment sizes, but there is
risks in that too.
2021-04-06 16:38:14 +00:00
Calle Wilund
d9a9897892 commitlog: coroutinize delete_segments
Because we like cow routines.
2021-04-06 16:38:14 +00:00
Calle Wilund
813694b617 commitlog_test: Add test for deadlock in recycle waiter
Not a very good test, mind you. Nothing to verify, just see if
the test times out. But try to make it at least complete for
failure report.
2021-04-06 16:38:14 +00:00
Calle Wilund
c0666ea89b commitlog: Fix inner loop condition in allocation pre-fill
Fixes #8369

This was originally found (and fixed) by @gleb-cloudius, but the patch set with
the fix was reverted at some point, and the fix went away. Now the error remains
even in new, nice coroutine code.

We check the wrong var in the inner loop of the pre-fill path of
allocate_segment_ex, often causing us to generate giant writev:s of more or less
the whole file.  Not intended.

Closes #8370
2021-03-30 12:14:55 +02:00
Pavel Emelyanov
37bec6fb76 commitlog: Open files with append_is_unlikely
This open option tells seastar that the file in question
will be truncated to the needed size right at once and all
the subsequent writes will happen within this size. This
hint turns off append optimization in seastar that's not
that cheap and helps so save few cpu cycles.

The option was introduced in seastar by 8bec57bc.

tests: unit(dev), dtest(commitlog:
                        test_batch_commitlog,
                        test_periodic_commitlog,
                        test_commitlog_replay_on_startup)

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
Message-Id: <20210323115409.31215-1-xemul@scylladb.com>
2021-03-24 13:05:33 +02:00
Calle Wilund
48ca01c3ab commitlog: Make pre-allocation drop O_DSYNC while pre-filling
Refs #7794

Iff we need to pre-fill segment file ni O_DSYNC mode, we should
drop this for the pre-fill, to avoid issuing flushes until the file
is filled. Done by temporarily closing, re-opening in "normal" mode,
filling, then re-opening.

v2:
* More comment
v3:
* Add missing flush
v4:
* comment
v5:
* Split coroutine and fix into separate patches
2021-03-15 09:35:45 +00:00