Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move parts between storage volumes according to configured TTL expressions #7420

Merged
merged 50 commits into from
Dec 11, 2019
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
c85479c
Parser for extended TTL expressions.
excitoon Oct 9, 2019
747cf27
Fixed ClickHouse after changing syntax.
excitoon Oct 16, 2019
bf59c6e
Updated ttl test according to new TTL syntax.
excitoon Oct 16, 2019
85d1201
First attempt to store min/max for move ttl expressions.
excitoon Oct 17, 2019
71eb0c3
Minor fix.
excitoon Oct 17, 2019
32d628e
Attempt to add background moves by TTL expressions.
excitoon Oct 22, 2019
ad49ec4
Fixed 00933 ttl tests.
excitoon Oct 28, 2019
dd50605
Fixed ttl move logic in background move task and added ttl enforcemen…
excitoon Oct 28, 2019
b83e0bb
Style fix.
excitoon Oct 28, 2019
33fcba5
Refactored, added move enforcement on merges, fixed a bug with wrong …
excitoon Oct 31, 2019
dd60c5b
Removed 'DELETE' keyword from default TTL syntax description.
excitoon Oct 31, 2019
4246e10
Removed TODO comments.
excitoon Nov 11, 2019
f610df1
Minor fix of JSON handling in `MergeTreeDataPartTTLInfo`.
excitoon Nov 11, 2019
a65a48e
Moved settings for `BackgroundProcessingPool` to configuration.
excitoon Nov 11, 2019
39841f7
Correct merge of background move pool.
excitoon Nov 30, 2019
2162b4e
Fixed Clang build.
excitoon Nov 11, 2019
c1399ec
Style fixes.
excitoon Nov 11, 2019
fd68281
Fixed Clang build one more time.
excitoon Nov 12, 2019
403a9ba
Renamed TTLDestinationType to PartDestinationType.
excitoon Nov 20, 2019
000db76
Removed redundant template from `updateTTL()` method.
excitoon Nov 20, 2019
b0e08dd
Added first version of tests for extended TTL expressions (still need…
excitoon Nov 25, 2019
64ea4d9
Fixed typos in `test_ttl_move` test.
excitoon Nov 26, 2019
f2f15c7
Fixed more typos in `test_ttl_move` test.
excitoon Nov 26, 2019
953134a
Fixed `MergeTreeData::hasTableTTL()` method according to extended TTLs.
excitoon Nov 26, 2019
e79bd30
Fixes of tests for extended TTL syntax.
excitoon Nov 26, 2019
b0a7039
Added few FIXMEs to not forget.
excitoon Nov 26, 2019
31b5ff5
Fixed a bug with erasing columns with same name.
excitoon Nov 27, 2019
518f41d
Fixed typos in a test.
excitoon Nov 27, 2019
72e5a70
Refactored tests a little bit.
excitoon Nov 28, 2019
d25ee92
Fixed some typos in `test_ttl_move` test.
excitoon Nov 28, 2019
0565edf
Placed move TTL rules to a vector.
excitoon Nov 28, 2019
33c1b5d
Added move TTL rules to metadata of `ReplicatedMergeTree`.
excitoon Nov 28, 2019
813a180
Fixed move TTL metadata.
excitoon Nov 28, 2019
f9ea4cf
Fixed more typos in `test_ttl_move`.
excitoon Nov 28, 2019
9a58474
Fixed `test_ttl_move` again.
excitoon Nov 28, 2019
71fd1af
Fixed move TTL expiration logic.
excitoon Nov 28, 2019
d9b01ba
Finally fixed selection of destination of move TTL.
excitoon Nov 29, 2019
b6cf4f0
Removing expired rows shall not be triggered on move TTL expiration.
excitoon Nov 29, 2019
b1a1a9a
Don't move anything if part already belongs their destination.
excitoon Nov 29, 2019
d9d4714
Fixed a typo in `MergeTreeData::selectMoveDestination()`.
excitoon Nov 29, 2019
83d0b76
Finally fixed tests and logic for extended TTL syntax.
excitoon Nov 30, 2019
9ca9abb
Fixed Clang build.
excitoon Dec 1, 2019
fb8137b
Boosted `test_ttl_move::test_moves_to_volume_work` a little.
excitoon Dec 1, 2019
8bd6dae
Review fixes.
excitoon Dec 5, 2019
25e7d1b
Added comment to `MergeTreePartsMover::selectPartsForMove()`.
excitoon Dec 5, 2019
c294d4a
Minor style fix.
excitoon Dec 5, 2019
0d5c724
Missed review fixes.
excitoon Dec 5, 2019
f594d19
Just trigger CI
alesapin Dec 6, 2019
edb5c77
Fix style
alesapin Dec 6, 2019
65194d6
Empty commit to re-run checks.
excitoon Dec 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions dbms/src/Common/quoteString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ String quoteString(const StringRef & x)
}


String doubleQuoteString(const StringRef & x)
{
String res(x.size, '\0');
WriteBufferFromString wb(res);
writeDoubleQuotedString(x, wb);
return res;
}


String backQuote(const StringRef & x)
{
String res(x.size, '\0');
Expand Down
3 changes: 3 additions & 0 deletions dbms/src/Common/quoteString.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ namespace DB
/// Quote the string.
String quoteString(const StringRef & x);

/// Double quote the string.
String doubleQuoteString(const StringRef & x);

/// Quote the identifier with backquotes.
String backQuote(const StringRef & x);

Expand Down
39 changes: 35 additions & 4 deletions dbms/src/DataStreams/TTLBlockInputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ Block TTLBlockInputStream::readImpl()

removeValuesWithExpiredColumnTTL(block);

updateMovesTTL(block);

return block;
}

Expand Down Expand Up @@ -145,7 +147,8 @@ void TTLBlockInputStream::removeValuesWithExpiredColumnTTL(Block & block)
defaults_expression->execute(block_with_defaults);
}

for (const auto & [name, ttl_entry] : storage.ttl_entries_by_name)
std::vector<String> columns_to_remove;
for (const auto & [name, ttl_entry] : storage.column_ttl_entries_by_name)
{
const auto & old_ttl_info = old_ttl_infos.columns_ttl[name];
auto & new_ttl_info = new_ttl_infos.columns_ttl[name];
Expand All @@ -159,7 +162,10 @@ void TTLBlockInputStream::removeValuesWithExpiredColumnTTL(Block & block)
continue;

if (!block.has(ttl_entry.result_column))
{
columns_to_remove.push_back(ttl_entry.result_column);
ttl_entry.expression->execute(block);
}

ColumnPtr default_column = nullptr;
if (block_with_defaults.has(name))
Expand Down Expand Up @@ -192,9 +198,34 @@ void TTLBlockInputStream::removeValuesWithExpiredColumnTTL(Block & block)
column_with_type.column = std::move(result_column);
}

for (const auto & elem : storage.ttl_entries_by_name)
if (block.has(elem.second.result_column))
block.erase(elem.second.result_column);
for (const String & column : columns_to_remove)
block.erase(column);
}

void TTLBlockInputStream::updateMovesTTL(Block & block)
{
std::vector<String> columns_to_remove;
for (const auto & ttl_entry : storage.move_ttl_entries)
{
auto & new_ttl_info = new_ttl_infos.moves_ttl[ttl_entry.result_column];

if (!block.has(ttl_entry.result_column))
{
columns_to_remove.push_back(ttl_entry.result_column);
ttl_entry.expression->execute(block);
}

const IColumn * ttl_column = block.getByName(ttl_entry.result_column).column.get();

for (size_t i = 0; i < block.rows(); ++i)
{
UInt32 cur_ttl = getTimestampByIndex(ttl_column, i);
new_ttl_info.update(cur_ttl);
}
}

for (const String & column : columns_to_remove)
block.erase(column);
}

UInt32 TTLBlockInputStream::getTimestampByIndex(const IColumn * column, size_t ind)
Expand Down
3 changes: 3 additions & 0 deletions dbms/src/DataStreams/TTLBlockInputStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class TTLBlockInputStream : public IBlockInputStream
/// Removes rows with expired table ttl and computes new ttl_infos for part
void removeRowsWithExpiredTableTTL(Block & block);

/// Updates TTL for moves
void updateMovesTTL(Block & block);

UInt32 getTimestampByIndex(const IColumn * column, size_t ind);
bool isTTLExpired(time_t ttl);
};
Expand Down
4 changes: 2 additions & 2 deletions dbms/src/Interpreters/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1487,15 +1487,15 @@ BackgroundProcessingPool & Context::getBackgroundPool()
{
auto lock = getLock();
if (!shared->background_pool)
shared->background_pool.emplace(settings.background_pool_size);
shared->background_pool.emplace(settings.background_pool_size, getConfigRef());
return *shared->background_pool;
}

BackgroundProcessingPool & Context::getBackgroundMovePool()
{
auto lock = getLock();
if (!shared->background_move_pool)
shared->background_move_pool.emplace(settings.background_move_pool_size, "BackgroundMovePool", "BgMoveProcPool");
shared->background_move_pool.emplace(settings.background_move_pool_size, getConfigRef(), "BackgroundMovePool", "BgMoveProcPool");
return *shared->background_move_pool;
}

Expand Down
6 changes: 4 additions & 2 deletions dbms/src/Parsers/ASTAlterQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,14 @@ void ASTAlterCommand::formatImpl(
settings.ostr << " TO ";
switch (move_destination_type)
{
case MoveDestinationType::DISK:
case PartDestinationType::DISK:
settings.ostr << "DISK ";
break;
case MoveDestinationType::VOLUME:
case PartDestinationType::VOLUME:
settings.ostr << "VOLUME ";
break;
default:
break;
}
settings.ostr << quoteString(move_destination_name);
}
Expand Down
11 changes: 3 additions & 8 deletions dbms/src/Parsers/ASTAlterQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <Parsers/IAST.h>
#include <Parsers/ASTQueryWithTableAndOutput.h>
#include <Parsers/ASTQueryWithOnCluster.h>
#include <Parsers/ASTTTLElement.h>


namespace DB
Expand Down Expand Up @@ -128,15 +129,9 @@ class ASTAlterCommand : public IAST

bool if_exists = false; /// option for DROP_COLUMN, MODIFY_COLUMN, COMMENT_COLUMN

enum MoveDestinationType
{
DISK,
VOLUME,
};

MoveDestinationType move_destination_type;
PartDestinationType move_destination_type; /// option for MOVE PART/PARTITION

String move_destination_name;
String move_destination_name; /// option for MOVE PART/PARTITION

/** For FETCH PARTITION - the path in ZK to the shard, from which to download the partition.
*/
Expand Down
27 changes: 27 additions & 0 deletions dbms/src/Parsers/ASTTTLElement.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

#include <Columns/Collator.h>
#include <Common/quoteString.h>
#include <Parsers/ASTTTLElement.h>


namespace DB
{

void ASTTTLElement::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{
children.front()->formatImpl(settings, state, frame);
if (destination_type == PartDestinationType::DISK)
{
settings.ostr << " TO DISK " << quoteString(destination_name);
}
else if (destination_type == PartDestinationType::VOLUME)
{
settings.ostr << " TO VOLUME " << quoteString(destination_name);
}
else if (destination_type == PartDestinationType::DELETE)
{
/// It would be better to output "DELETE" here but that will break compatibility with earlier versions.
}
}

}
36 changes: 36 additions & 0 deletions dbms/src/Parsers/ASTTTLElement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include <Parsers/IAST.h>
#include <Storages/MergeTree/PartDestinationType.h>


namespace DB
{
/** Element of TTL expression.
*/
class ASTTTLElement : public IAST
{
public:
PartDestinationType destination_type;
String destination_name;

ASTTTLElement(PartDestinationType destination_type_, const String & destination_name_)
: destination_type(destination_type_)
, destination_name(destination_name_)
{
}

String getID(char) const override { return "TTLElement"; }

ASTPtr clone() const override
{
auto clone = std::make_shared<ASTTTLElement>(*this);
clone->cloneChildren();
return clone;
}

protected:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
};

}
37 changes: 37 additions & 0 deletions dbms/src/Parsers/ExpressionElementParsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <Parsers/ASTAsterisk.h>
#include <Parsers/ASTQualifiedAsterisk.h>
#include <Parsers/ASTQueryParameter.h>
#include <Parsers/ASTTTLElement.h>
#include <Parsers/ASTOrderByElement.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTFunctionWithKeyValueArguments.h>
Expand Down Expand Up @@ -1477,6 +1478,42 @@ bool ParserFunctionWithKeyValueArguments::parseImpl(Pos & pos, ASTPtr & node, Ex
return true;
}

bool ParserTTLElement::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserKeyword s_to_disk("TO DISK");
ParserKeyword s_to_volume("TO VOLUME");
ParserKeyword s_delete("DELETE");
ParserStringLiteral parser_string_literal;
ParserExpression parser_exp;

ASTPtr expr_elem;
if (!parser_exp.parse(pos, expr_elem, expected))
return false;

PartDestinationType destination_type = PartDestinationType::DELETE;
String destination_name;
if (s_to_disk.ignore(pos))
destination_type = PartDestinationType::DISK;
else if (s_to_volume.ignore(pos))
destination_type = PartDestinationType::VOLUME;
else
s_delete.ignore(pos);
excitoon marked this conversation as resolved.
Show resolved Hide resolved

if (destination_type == PartDestinationType::DISK || destination_type == PartDestinationType::VOLUME)
{
ASTPtr ast_space_name;
if (!parser_string_literal.parse(pos, ast_space_name, expected))
return false;

destination_name = ast_space_name->as<ASTLiteral &>().value.get<const String &>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the bad cast of there will be a number. Better tryGet and apparent exception in case of error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I can not get the idea, it looks like we do not do that in way more other places.

}

node = std::make_shared<ASTTTLElement>(destination_type, destination_name);
node->children.push_back(expr_elem);

return true;
}

bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ParserIdentifier non_parametric;
Expand Down
10 changes: 10 additions & 0 deletions dbms/src/Parsers/ExpressionElementParsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,4 +320,14 @@ class ParserIdentifierWithOptionalParameters : public IParserBase
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
};

/** Element of TTL expression - same as expression element, but in addition,
* TO DISK 'xxx' | TO VOLUME 'xxx' | DELETE could be specified
*/
class ParserTTLElement : public IParserBase
{
protected:
const char * getName() const { return "element of TTL expression"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
};

}
7 changes: 7 additions & 0 deletions dbms/src/Parsers/ExpressionListParsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,13 @@ bool ParserOrderByExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected &
}


bool ParserTTLExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
return ParserList(std::make_unique<ParserTTLElement>(), std::make_unique<ParserToken>(TokenType::Comma), false)
.parse(pos, node, expected);
}


bool ParserNullityChecking::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr node_comp;
Expand Down
9 changes: 9 additions & 0 deletions dbms/src/Parsers/ExpressionListParsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ class ParserKeyValuePair : public IParserBase
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};


/// Parser for list of key-value pairs.
class ParserKeyValuePairsList : public IParserBase
{
Expand All @@ -394,4 +395,12 @@ class ParserKeyValuePairsList : public IParserBase
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
};


class ParserTTLExpressionList : public IParserBase
{
protected:
const char * getName() const { return "ttl expression"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected);
};

}
11 changes: 6 additions & 5 deletions dbms/src/Parsers/ParserAlterQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
/* allow_empty = */ false);
ParserSetQuery parser_settings(true);
ParserNameList values_p;
ParserTTLExpressionList parser_ttl_list;

if (is_live_view)
{
Expand Down Expand Up @@ -236,9 +237,9 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
command->part = true;

if (s_to_disk.ignore(pos))
command->move_destination_type = ASTAlterCommand::MoveDestinationType::DISK;
command->move_destination_type = PartDestinationType::DISK;
else if (s_to_volume.ignore(pos))
command->move_destination_type = ASTAlterCommand::MoveDestinationType::VOLUME;
command->move_destination_type = PartDestinationType::VOLUME;
else
return false;

Expand All @@ -256,9 +257,9 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
command->type = ASTAlterCommand::MOVE_PARTITION;

if (s_to_disk.ignore(pos))
command->move_destination_type = ASTAlterCommand::MoveDestinationType::DISK;
command->move_destination_type = PartDestinationType::DISK;
else if (s_to_volume.ignore(pos))
command->move_destination_type = ASTAlterCommand::MoveDestinationType::VOLUME;
command->move_destination_type = PartDestinationType::VOLUME;
else
return false;

Expand Down Expand Up @@ -431,7 +432,7 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
}
else if (s_modify_ttl.ignore(pos, expected))
{
if (!parser_exp_elem.parse(pos, command->ttl, expected))
if (!parser_ttl_list.parse(pos, command->ttl, expected))
return false;
command->type = ASTAlterCommand::MODIFY_TTL;
}
Expand Down
3 changes: 2 additions & 1 deletion dbms/src/Parsers/ParserCreateQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ bool ParserStorage::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
ParserIdentifierWithOptionalParameters ident_with_optional_params_p;
ParserExpression expression_p;
ParserSetQuery settings_p(/* parse_only_internals_ = */ true);
ParserTTLExpressionList parser_ttl_list;

ASTPtr engine;
ASTPtr partition_by;
Expand Down Expand Up @@ -303,7 +304,7 @@ bool ParserStorage::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)

if (!ttl_table && s_ttl.ignore(pos, expected))
{
if (expression_p.parse(pos, ttl_table, expected))
if (parser_ttl_list.parse(pos, ttl_table, expected))
continue;
else
return false;
Expand Down
Loading