From 9421cfded4f36f5726da83aa60aedabb34edf818 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 15 Sep 2020 16:44:01 +0300 Subject: [PATCH] reconcilable_result_builder: don't aggrevate out-of-memory condition during recovery Consider an unpaged query that consumes all of available memory, despite fea5067dfa339ddf36d86704a8bdbb671efb27cf which limits them (perhaps the user raised the limit, or this is a system query). Eventually we will see a bad_alloc which will abort the query and destroy this reconcilable_result_builder. During destruction, we first destroy _memory_accounter, and then _result. Destroying _memory_accounter resumes some continuations which can then allocate memory synchronously when increasing the task queue to accomodate them. We will then crash. Had we not crashed, we would immediately afterwards release _result, freeing all the memory that we would ever need. Fix by making _result the last member, so it is freed first. Fixes #7240. --- mutation_query.hh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mutation_query.hh b/mutation_query.hh index 32581a54c4..934101c7fe 100644 --- a/mutation_query.hh +++ b/mutation_query.hh @@ -140,15 +140,16 @@ class reconcilable_result_builder { const schema& _schema; const query::partition_slice& _slice; - utils::chunked_vector _result; - uint64_t _live_rows{}; - bool _return_static_content_on_partition_with_no_rows{}; bool _static_row_is_alive{}; uint64_t _total_live_rows = 0; query::result_memory_accounter _memory_accounter; stop_iteration _stop; std::optional _mutation_consumer; + + uint64_t _live_rows{}; + // make this the last member so it is destroyed first. #7240 + utils::chunked_vector _result; public: reconcilable_result_builder(const schema& s, const query::partition_slice& slice, query::result_memory_accounter&& accounter)