2014-03-13 12:48:07 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <DB/Storages/MergeTree/MergeTreeData.h>
|
2014-08-04 11:41:59 +00:00
|
|
|
|
#include <DB/Storages/MergeTree/DiskSpaceMonitor.h>
|
2014-12-17 11:50:24 +00:00
|
|
|
|
#include <atomic>
|
2014-03-13 12:48:07 +00:00
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
2015-04-16 06:12:35 +00:00
|
|
|
|
class MergeListEntry;
|
2016-01-28 01:00:27 +00:00
|
|
|
|
class ReshardingJob;
|
2015-04-16 06:12:35 +00:00
|
|
|
|
|
|
|
|
|
|
2014-03-13 12:48:07 +00:00
|
|
|
|
/** Умеет выбирать куски для слияния и сливать их.
|
|
|
|
|
*/
|
|
|
|
|
class MergeTreeDataMerger
|
|
|
|
|
{
|
|
|
|
|
public:
|
2014-05-14 17:51:37 +00:00
|
|
|
|
static const size_t NO_LIMIT = std::numeric_limits<size_t>::max();
|
|
|
|
|
|
2014-12-17 11:50:24 +00:00
|
|
|
|
MergeTreeDataMerger(MergeTreeData & data_) : data(data_), log(&Logger::get(data.getLogName() + " (Merger)")) {}
|
2014-03-13 12:48:07 +00:00
|
|
|
|
|
2014-04-04 10:37:33 +00:00
|
|
|
|
typedef std::function<bool (const MergeTreeData::DataPartPtr &, const MergeTreeData::DataPartPtr &)> AllowedMergingPredicate;
|
2014-03-13 17:44:00 +00:00
|
|
|
|
|
|
|
|
|
/** Выбирает, какие куски слить. Использует кучу эвристик.
|
|
|
|
|
* Если merge_anything_for_old_months, для кусков за прошедшие месяцы снимается ограничение на соотношение размеров.
|
2014-05-14 17:51:37 +00:00
|
|
|
|
* Выбирает куски так, чтобы available_disk_space, скорее всего, хватило с запасом для их слияния.
|
2014-03-13 17:44:00 +00:00
|
|
|
|
*
|
|
|
|
|
* can_merge - функция, определяющая, можно ли объединить пару соседних кусков.
|
|
|
|
|
* Эта функция должна координировать слияния со вставками и другими слияниями, обеспечивая, что:
|
|
|
|
|
* - Куски, между которыми еще может появиться новый кусок, нельзя сливать. См. METR-7001.
|
|
|
|
|
* - Кусок, который уже сливается с кем-то в одном месте, нельзя начать сливать в кем-то другим в другом месте.
|
|
|
|
|
*/
|
2014-03-13 12:48:07 +00:00
|
|
|
|
bool selectPartsToMerge(
|
|
|
|
|
MergeTreeData::DataPartsVector & what,
|
2014-04-04 10:37:33 +00:00
|
|
|
|
String & merged_name,
|
2014-03-13 12:48:07 +00:00
|
|
|
|
size_t available_disk_space,
|
|
|
|
|
bool merge_anything_for_old_months,
|
2014-03-13 17:44:00 +00:00
|
|
|
|
bool aggressive,
|
|
|
|
|
bool only_small,
|
|
|
|
|
const AllowedMergingPredicate & can_merge);
|
2014-03-13 12:48:07 +00:00
|
|
|
|
|
2014-08-04 11:41:59 +00:00
|
|
|
|
/** Сливает куски.
|
|
|
|
|
* Если reservation != nullptr, то и дело уменьшает размер зарезервированного места
|
|
|
|
|
* приблизительно пропорционально количеству уже выписанных данных.
|
|
|
|
|
*/
|
2016-01-28 16:06:57 +00:00
|
|
|
|
MergeTreeData::DataPartPtr mergeParts(
|
2015-04-16 06:12:35 +00:00
|
|
|
|
const MergeTreeData::DataPartsVector & parts, const String & merged_name, MergeListEntry & merge_entry,
|
2015-04-10 15:31:51 +00:00
|
|
|
|
size_t aio_threshold, MergeTreeData::Transaction * out_transaction = nullptr,
|
|
|
|
|
DiskSpaceMonitor::Reservation * disk_reservation = nullptr);
|
2014-03-13 12:48:07 +00:00
|
|
|
|
|
2016-01-28 16:06:57 +00:00
|
|
|
|
/** Перешардирует заданную партицию.
|
|
|
|
|
*/
|
|
|
|
|
MergeTreeData::PerShardDataParts reshardPartition(
|
|
|
|
|
const ReshardingJob & job,
|
|
|
|
|
size_t aio_threshold,
|
|
|
|
|
DiskSpaceMonitor::Reservation * disk_reservation = nullptr);
|
|
|
|
|
|
2014-03-13 12:48:07 +00:00
|
|
|
|
/// Примерное количество места на диске, нужное для мерджа. С запасом.
|
2015-06-11 00:35:36 +00:00
|
|
|
|
static size_t estimateDiskSpaceForMerge(const MergeTreeData::DataPartsVector & parts);
|
2014-03-13 12:48:07 +00:00
|
|
|
|
|
2014-05-13 10:10:26 +00:00
|
|
|
|
/** Отменяет все мерджи. Все выполняющиеся сейчас вызовы mergeParts скоро бросят исключение.
|
2015-11-06 17:34:48 +00:00
|
|
|
|
* Все новые вызовы будут бросать исключения, пока не будет вызван uncancel().
|
2014-03-13 12:48:07 +00:00
|
|
|
|
*/
|
2015-12-09 04:06:44 +00:00
|
|
|
|
void cancel() { cancelled = true; }
|
|
|
|
|
void uncancel() { cancelled = false; }
|
|
|
|
|
bool isCancelled() const { return cancelled; }
|
2014-05-13 10:10:26 +00:00
|
|
|
|
|
2016-01-28 16:06:57 +00:00
|
|
|
|
void abortIfRequested() const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
/** Выбрать все куски принадлежащие одной партиции.
|
|
|
|
|
*/
|
|
|
|
|
MergeTreeData::DataPartsVector selectAllPartsFromPartition(DayNum_t partition);
|
|
|
|
|
|
2014-03-13 12:48:07 +00:00
|
|
|
|
private:
|
|
|
|
|
MergeTreeData & data;
|
|
|
|
|
|
|
|
|
|
Logger * log;
|
|
|
|
|
|
2014-05-21 10:20:41 +00:00
|
|
|
|
/// Когда в последний раз писали в лог, что место на диске кончилось (чтобы не писать об этом слишком часто).
|
|
|
|
|
time_t disk_space_warning_time = 0;
|
|
|
|
|
|
2015-12-09 04:06:44 +00:00
|
|
|
|
std::atomic<bool> cancelled {false};
|
2014-12-17 11:50:24 +00:00
|
|
|
|
};
|
|
|
|
|
|
2015-11-06 17:34:48 +00:00
|
|
|
|
|
|
|
|
|
/** Временно приостанавливает мерджи.
|
|
|
|
|
*/
|
2014-12-17 11:50:24 +00:00
|
|
|
|
class MergeTreeMergeBlocker
|
|
|
|
|
{
|
|
|
|
|
public:
|
2015-12-03 05:18:22 +00:00
|
|
|
|
MergeTreeMergeBlocker(MergeTreeDataMerger & merger_)
|
|
|
|
|
: merger(merger_)
|
2015-11-06 17:34:48 +00:00
|
|
|
|
{
|
|
|
|
|
merger.cancel();
|
|
|
|
|
}
|
2014-12-17 11:50:24 +00:00
|
|
|
|
|
|
|
|
|
~MergeTreeMergeBlocker()
|
|
|
|
|
{
|
2015-11-06 17:34:48 +00:00
|
|
|
|
merger.uncancel();
|
2014-12-17 11:50:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
MergeTreeDataMerger & merger;
|
2014-03-13 12:48:07 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|