2012-07-16 20:25:19 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2014-03-09 17:36:01 +00:00
|
|
|
|
#include <DB/Storages/MergeTree/MergeTreeData.h>
|
2014-03-13 12:48:07 +00:00
|
|
|
|
#include "MergeTree/MergeTreeDataSelectExecutor.h"
|
|
|
|
|
#include "MergeTree/MergeTreeDataWriter.h"
|
|
|
|
|
#include "MergeTree/MergeTreeDataMerger.h"
|
2014-03-13 17:44:00 +00:00
|
|
|
|
#include "MergeTree/DiskSpaceMonitor.h"
|
2012-07-16 20:25:19 +00:00
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
2014-03-09 17:36:01 +00:00
|
|
|
|
/** См. описание структуры данных в MergeTreeData.
|
2012-07-16 20:25:19 +00:00
|
|
|
|
*/
|
|
|
|
|
class StorageMergeTree : public IStorage
|
|
|
|
|
{
|
2014-03-13 12:48:07 +00:00
|
|
|
|
friend class MergeTreeBlockOutputStream;
|
|
|
|
|
|
2012-07-16 20:25:19 +00:00
|
|
|
|
public:
|
|
|
|
|
/** Подцепить таблицу с соответствующим именем, по соответствующему пути (с / на конце),
|
|
|
|
|
* (корректность имён и путей не проверяется)
|
|
|
|
|
* состоящую из указанных столбцов.
|
|
|
|
|
*
|
2012-11-30 00:52:45 +00:00
|
|
|
|
* primary_expr_ast - выражение для сортировки;
|
2012-07-16 20:25:19 +00:00
|
|
|
|
* date_column_name - имя столбца с датой;
|
|
|
|
|
* index_granularity - на сколько строчек пишется одно значение индекса.
|
|
|
|
|
*/
|
2013-02-06 11:26:35 +00:00
|
|
|
|
static StoragePtr create(const String & path_, const String & name_, NamesAndTypesListPtr columns_,
|
2013-05-05 18:02:05 +00:00
|
|
|
|
const Context & context_,
|
2012-12-12 14:25:55 +00:00
|
|
|
|
ASTPtr & primary_expr_ast_,
|
|
|
|
|
const String & date_column_name_,
|
2012-12-12 15:45:08 +00:00
|
|
|
|
const ASTPtr & sampling_expression_, /// NULL, если семплирование не поддерживается.
|
2012-07-31 16:37:20 +00:00
|
|
|
|
size_t index_granularity_,
|
2014-03-09 17:36:01 +00:00
|
|
|
|
MergeTreeData::Mode mode_ = MergeTreeData::Ordinary,
|
2012-08-20 05:32:50 +00:00
|
|
|
|
const String & sign_column_ = "",
|
2014-03-09 17:36:01 +00:00
|
|
|
|
const MergeTreeSettings & settings_ = MergeTreeSettings());
|
2012-07-16 20:25:19 +00:00
|
|
|
|
|
2013-09-30 01:29:19 +00:00
|
|
|
|
void shutdown();
|
|
|
|
|
~StorageMergeTree();
|
2012-07-30 20:32:36 +00:00
|
|
|
|
|
2013-09-30 19:54:25 +00:00
|
|
|
|
std::string getName() const
|
|
|
|
|
{
|
2014-03-09 17:36:01 +00:00
|
|
|
|
return data.getModePrefix() + "MergeTree";
|
2013-09-30 19:54:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-13 12:48:07 +00:00
|
|
|
|
std::string getTableName() const { return name; }
|
2014-03-09 17:36:01 +00:00
|
|
|
|
std::string getSignColumnName() const { return data.getSignColumnName(); }
|
|
|
|
|
bool supportsSampling() const { return data.supportsSampling(); }
|
|
|
|
|
bool supportsFinal() const { return data.supportsFinal(); }
|
|
|
|
|
bool supportsPrewhere() const { return data.supportsPrewhere(); }
|
2012-07-16 20:25:19 +00:00
|
|
|
|
|
2014-03-19 10:45:13 +00:00
|
|
|
|
const NamesAndTypesList & getColumnsList() const { return data.getColumnsList(); }
|
2012-07-16 20:25:19 +00:00
|
|
|
|
|
2012-07-21 03:45:48 +00:00
|
|
|
|
BlockInputStreams read(
|
2012-07-16 20:25:19 +00:00
|
|
|
|
const Names & column_names,
|
|
|
|
|
ASTPtr query,
|
2013-02-01 19:02:04 +00:00
|
|
|
|
const Settings & settings,
|
2012-07-16 20:25:19 +00:00
|
|
|
|
QueryProcessingStage::Enum & processed_stage,
|
|
|
|
|
size_t max_block_size = DEFAULT_BLOCK_SIZE,
|
2012-07-21 03:45:48 +00:00
|
|
|
|
unsigned threads = 1);
|
2012-07-16 20:25:19 +00:00
|
|
|
|
|
2014-03-04 11:30:50 +00:00
|
|
|
|
BlockOutputStreamPtr write(ASTPtr query);
|
2012-07-16 20:25:19 +00:00
|
|
|
|
|
|
|
|
|
/** Выполнить очередной шаг объединения кусков.
|
|
|
|
|
*/
|
2012-07-31 16:37:20 +00:00
|
|
|
|
bool optimize()
|
|
|
|
|
{
|
2014-03-13 12:48:07 +00:00
|
|
|
|
merge(1, false, true);
|
|
|
|
|
return true;
|
2012-07-31 16:37:20 +00:00
|
|
|
|
}
|
2012-07-16 20:25:19 +00:00
|
|
|
|
|
2014-03-20 13:28:49 +00:00
|
|
|
|
void drop() override;
|
2014-03-09 17:36:01 +00:00
|
|
|
|
|
2013-01-23 11:16:32 +00:00
|
|
|
|
void rename(const String & new_path_to_db, const String & new_name);
|
2012-07-16 20:25:19 +00:00
|
|
|
|
|
2013-08-09 00:12:59 +00:00
|
|
|
|
void alter(const ASTAlterQuery::Parameters & params);
|
2014-03-20 13:00:42 +00:00
|
|
|
|
void prepareAlterModify(const ASTAlterQuery::Parameters & params);
|
|
|
|
|
void commitAlterModify(const ASTAlterQuery::Parameters & params);
|
2013-08-07 13:07:42 +00:00
|
|
|
|
|
2012-07-16 20:25:19 +00:00
|
|
|
|
private:
|
2014-03-13 12:48:07 +00:00
|
|
|
|
String path;
|
|
|
|
|
String name;
|
|
|
|
|
String full_path;
|
|
|
|
|
Increment increment;
|
|
|
|
|
|
2014-03-09 17:36:01 +00:00
|
|
|
|
MergeTreeData data;
|
2014-03-13 12:48:07 +00:00
|
|
|
|
MergeTreeDataSelectExecutor reader;
|
|
|
|
|
MergeTreeDataWriter writer;
|
|
|
|
|
MergeTreeDataMerger merger;
|
|
|
|
|
|
2014-03-13 17:44:00 +00:00
|
|
|
|
MergeTreeData::DataParts currently_merging;
|
|
|
|
|
Poco::FastMutex currently_merging_mutex;
|
|
|
|
|
|
2014-03-13 12:48:07 +00:00
|
|
|
|
Logger * log;
|
|
|
|
|
|
|
|
|
|
volatile bool shutdown_called;
|
2014-03-04 11:30:50 +00:00
|
|
|
|
|
2014-03-13 17:44:00 +00:00
|
|
|
|
Poco::SharedPtr<boost::threadpool::pool> merge_threads;
|
|
|
|
|
|
|
|
|
|
/// Пока существует, помечает части как currently_merging и держит резерв места.
|
|
|
|
|
/// Вероятно, что части будут помечены заранее.
|
|
|
|
|
struct CurrentlyMergingPartsTagger
|
|
|
|
|
{
|
|
|
|
|
MergeTreeData::DataPartsVector parts;
|
|
|
|
|
DiskSpaceMonitor::ReservationPtr reserved_space;
|
|
|
|
|
StorageMergeTree & storage;
|
|
|
|
|
|
|
|
|
|
CurrentlyMergingPartsTagger(const MergeTreeData::DataPartsVector & parts_, size_t total_size, StorageMergeTree & storage_)
|
|
|
|
|
: parts(parts_), storage(storage_)
|
|
|
|
|
{
|
|
|
|
|
/// Здесь не лочится мьютекс, так как конструктор вызывается внутри mergeThread, где он уже залочен.
|
|
|
|
|
reserved_space = DiskSpaceMonitor::reserve(storage.full_path, total_size); /// Может бросить исключение.
|
2014-03-13 19:07:17 +00:00
|
|
|
|
for (const auto & part : parts)
|
|
|
|
|
{
|
|
|
|
|
if (storage.currently_merging.count(part))
|
|
|
|
|
throw Exception("Tagging alreagy tagged part " + part->name + ". This is a bug.", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
}
|
2014-03-13 17:44:00 +00:00
|
|
|
|
storage.currently_merging.insert(parts.begin(), parts.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~CurrentlyMergingPartsTagger()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Poco::ScopedLock<Poco::FastMutex> lock(storage.currently_merging_mutex);
|
2014-03-13 19:07:17 +00:00
|
|
|
|
for (const auto & part : parts)
|
2014-03-13 17:44:00 +00:00
|
|
|
|
{
|
2014-03-13 19:07:17 +00:00
|
|
|
|
if (!storage.currently_merging.count(part))
|
|
|
|
|
throw Exception("Untagging already untagged part " + part->name + ". This is a bug.", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
storage.currently_merging.erase(part);
|
2014-03-13 17:44:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
tryLogCurrentException("~CurrentlyMergingPartsTagger");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef Poco::SharedPtr<CurrentlyMergingPartsTagger> CurrentlyMergingPartsTaggerPtr;
|
|
|
|
|
|
2013-02-06 11:26:35 +00:00
|
|
|
|
StorageMergeTree(const String & path_, const String & name_, NamesAndTypesListPtr columns_,
|
2013-11-28 13:16:46 +00:00
|
|
|
|
const Context & context_,
|
|
|
|
|
ASTPtr & primary_expr_ast_,
|
|
|
|
|
const String & date_column_name_,
|
|
|
|
|
const ASTPtr & sampling_expression_, /// NULL, если семплирование не поддерживается.
|
|
|
|
|
size_t index_granularity_,
|
2014-03-13 12:48:07 +00:00
|
|
|
|
MergeTreeData::Mode mode_,
|
|
|
|
|
const String & sign_column_,
|
|
|
|
|
const MergeTreeSettings & settings_);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Определяет, какие куски нужно объединять, и запускает их слияние в отдельном потоке. Если iterations = 0, объединяет, пока это возможно.
|
|
|
|
|
* Если aggressive - выбрать куски не обращая внимание на соотношение размеров и их новизну (для запроса OPTIMIZE).
|
|
|
|
|
*/
|
|
|
|
|
void merge(size_t iterations = 1, bool async = true, bool aggressive = false);
|
|
|
|
|
|
|
|
|
|
/// Если while_can, объединяет в цикле, пока можно; иначе выбирает и объединяет только одну пару кусков.
|
|
|
|
|
void mergeThread(bool while_can, bool aggressive);
|
|
|
|
|
|
|
|
|
|
/// Дождаться, пока фоновые потоки закончат слияния.
|
|
|
|
|
void joinMergeThreads();
|
|
|
|
|
|
2014-03-13 17:44:00 +00:00
|
|
|
|
/// Вызывается во время выбора кусков для слияния.
|
|
|
|
|
bool canMergeParts(const MergeTreeData::DataPartPtr & left, const MergeTreeData::DataPartPtr & right);
|
2012-07-16 20:25:19 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|