Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
49439aa2
C
ClickHouse
项目概览
2dot5
/
ClickHouse
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ClickHouse
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
49439aa2
编写于
4月 19, 2018
作者:
A
Alexey Zatelepin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
write mutations to ZK [#CLICKHOUSE-3747]
上级
4ca3bf65
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
248 addition
and
5 deletion
+248
-5
dbms/src/Common/ErrorCodes.cpp
dbms/src/Common/ErrorCodes.cpp
+1
-0
dbms/src/Storages/MergeTree/ReplicatedMergeTreeMutationEntry.cpp
...c/Storages/MergeTree/ReplicatedMergeTreeMutationEntry.cpp
+68
-0
dbms/src/Storages/MergeTree/ReplicatedMergeTreeMutationEntry.h
...src/Storages/MergeTree/ReplicatedMergeTreeMutationEntry.h
+32
-0
dbms/src/Storages/MutationCommands.cpp
dbms/src/Storages/MutationCommands.cpp
+82
-0
dbms/src/Storages/MutationCommands.h
dbms/src/Storages/MutationCommands.h
+7
-0
dbms/src/Storages/StorageReplicatedMergeTree.cpp
dbms/src/Storages/StorageReplicatedMergeTree.cpp
+56
-5
dbms/src/Storages/StorageReplicatedMergeTree.h
dbms/src/Storages/StorageReplicatedMergeTree.h
+2
-0
未找到文件。
dbms/src/Common/ErrorCodes.cpp
浏览文件 @
49439aa2
...
...
@@ -372,6 +372,7 @@ namespace ErrorCodes
extern
const
int
FUNCTION_THROW_IF_VALUE_IS_NON_ZERO
=
395
;
extern
const
int
TOO_MANY_ROWS_OR_BYTES
=
396
;
extern
const
int
QUERY_IS_NOT_SUPPORTED_IN_MATERIALIZED_VIEW
=
397
;
extern
const
int
UNKNOWN_MUTATION_COMMAND
=
398
;
extern
const
int
KEEPER_EXCEPTION
=
999
;
...
...
dbms/src/Storages/MergeTree/ReplicatedMergeTreeMutationEntry.cpp
0 → 100644
浏览文件 @
49439aa2
#include <Storages/MergeTree/ReplicatedMergeTreeMutationEntry.h>
#include <IO/Operators.h>
#include <IO/ReadBufferFromString.h>
#include <IO/WriteBufferFromString.h>
namespace
DB
{
void
ReplicatedMergeTreeMutationEntry
::
writeText
(
WriteBuffer
&
out
)
const
{
out
<<
"format version: 1
\n
"
<<
"create time: "
<<
LocalDateTime
(
create_time
?
create_time
:
time
(
nullptr
))
<<
"
\n
"
<<
"source replica: "
<<
source_replica
<<
"
\n
"
<<
"block numbers count: "
<<
block_numbers
.
size
()
<<
"
\n
"
;
for
(
const
auto
&
kv
:
block_numbers
)
{
const
String
&
partition_id
=
kv
.
first
;
Int64
number
=
kv
.
second
;
out
<<
partition_id
<<
"
\t
"
<<
number
<<
"
\n
"
;
}
out
<<
"mutation commands:
\n
"
;
commands
.
writeText
(
out
);
}
void
ReplicatedMergeTreeMutationEntry
::
readText
(
ReadBuffer
&
in
)
{
in
>>
"format version: 1
\n
"
;
LocalDateTime
create_time_dt
;
in
>>
"create time: "
>>
create_time_dt
>>
"
\n
"
;
create_time
=
create_time_dt
;
in
>>
"source replica: "
>>
source_replica
>>
"
\n
"
;
size_t
count
;
in
>>
"block numbers count: "
>>
count
>>
"
\n
"
;
for
(
size_t
i
=
0
;
i
<
count
;
++
i
)
{
String
partition_id
;
Int64
number
;
in
>>
partition_id
>>
"
\t
"
>>
number
>>
"
\n
"
;
block_numbers
[
partition_id
]
=
number
;
}
in
>>
"mutation commands:
\n
"
;
commands
.
readText
(
in
);
}
String
ReplicatedMergeTreeMutationEntry
::
toString
()
const
{
WriteBufferFromOwnString
out
;
writeText
(
out
);
return
out
.
str
();
}
ReplicatedMergeTreeMutationEntry
ReplicatedMergeTreeMutationEntry
::
parse
(
const
String
&
str
)
{
ReadBufferFromString
in
(
str
);
ReplicatedMergeTreeMutationEntry
res
;
res
.
readText
(
in
);
assertEOF
(
in
);
return
res
;
}
}
dbms/src/Storages/MergeTree/ReplicatedMergeTreeMutationEntry.h
0 → 100644
浏览文件 @
49439aa2
#pragma once
#include <Common/Exception.h>
#include <Core/Types.h>
#include <IO/WriteHelpers.h>
#include <Storages/MutationCommands.h>
namespace
DB
{
class
ReadBuffer
;
class
WriteBuffer
;
struct
ReplicatedMergeTreeMutationEntry
{
void
writeText
(
WriteBuffer
&
out
)
const
;
void
readText
(
ReadBuffer
&
in
);
String
toString
()
const
;
static
ReplicatedMergeTreeMutationEntry
parse
(
const
String
&
str
);
String
znode_name
;
time_t
create_time
=
0
;
String
source_replica
;
std
::
unordered_map
<
String
,
Int64
>
block_numbers
;
MutationCommands
commands
;
};
}
dbms/src/Storages/MutationCommands.cpp
浏览文件 @
49439aa2
...
...
@@ -2,11 +2,68 @@
#include <Storages/IStorage.h>
#include <Interpreters/ExpressionAnalyzer.h>
#include <Columns/FilterDescription.h>
#include <IO/Operators.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/formatAST.h>
#include <Parsers/parseQuery.h>
namespace
DB
{
namespace
ErrorCodes
{
extern
const
int
UNKNOWN_MUTATION_COMMAND
;
}
static
String
typeToString
(
MutationCommand
::
Type
type
)
{
switch
(
type
)
{
case
MutationCommand
::
DELETE
:
return
"DELETE"
;
default:
throw
Exception
(
"Bad mutation type: "
+
toString
<
int
>
(
type
),
ErrorCodes
::
LOGICAL_ERROR
);
}
}
void
MutationCommand
::
writeText
(
WriteBuffer
&
out
)
const
{
out
<<
typeToString
(
type
)
<<
"
\n
"
;
switch
(
type
)
{
case
MutationCommand
::
DELETE
:
{
std
::
stringstream
ss
;
formatAST
(
*
predicate
,
ss
,
/* hilite = */
false
,
/* one_line = */
true
);
out
<<
"predicate: "
<<
ss
.
str
()
<<
"
\n
"
;
break
;
}
default:
throw
Exception
(
"Bad mutation type: "
+
toString
<
int
>
(
type
),
ErrorCodes
::
LOGICAL_ERROR
);
}
}
void
MutationCommand
::
readText
(
ReadBuffer
&
in
)
{
String
type_str
;
in
>>
type_str
>>
"
\n
"
;
if
(
type_str
==
"DELETE"
)
{
type
=
DELETE
;
String
predicate_str
;
in
>>
"predicate: "
>>
predicate_str
>>
"
\n
"
;
ParserExpressionWithOptionalAlias
p_expr
(
false
);
predicate
=
parseQuery
(
p_expr
,
predicate_str
.
data
(),
predicate_str
.
data
()
+
predicate_str
.
length
(),
"mutation predicate"
,
0
);
}
else
throw
Exception
(
"Unknown mutation command: `"
+
type_str
+
"'"
,
ErrorCodes
::
UNKNOWN_MUTATION_COMMAND
);
}
void
MutationCommands
::
validate
(
const
IStorage
&
table
,
const
Context
&
context
)
{
auto
all_columns
=
table
.
getColumns
().
getAll
();
...
...
@@ -29,4 +86,29 @@ void MutationCommands::validate(const IStorage & table, const Context & context)
}
}
void
MutationCommands
::
writeText
(
WriteBuffer
&
out
)
const
{
out
<<
"format version: 1
\n
"
<<
"count: "
<<
commands
.
size
()
<<
"
\n
"
;
for
(
const
MutationCommand
&
command
:
commands
)
{
command
.
writeText
(
out
);
}
}
void
MutationCommands
::
readText
(
ReadBuffer
&
in
)
{
in
>>
"format version: 1
\n
"
;
size_t
count
;
in
>>
"count: "
>>
count
>>
"
\n
"
;
for
(
size_t
i
=
0
;
i
<
count
;
++
i
)
{
MutationCommand
command
;
command
.
readText
(
in
);
commands
.
push_back
(
std
::
move
(
command
));
}
}
}
dbms/src/Storages/MutationCommands.h
浏览文件 @
49439aa2
#pragma once
#include <Parsers/IAST.h>
#include <IO/WriteHelpers.h>
namespace
DB
...
...
@@ -28,6 +29,9 @@ struct MutationCommand
res
.
predicate
=
predicate
;
return
res
;
}
void
writeText
(
WriteBuffer
&
out
)
const
;
void
readText
(
ReadBuffer
&
in
);
};
struct
MutationCommands
...
...
@@ -35,6 +39,9 @@ struct MutationCommands
std
::
vector
<
MutationCommand
>
commands
;
void
validate
(
const
IStorage
&
table
,
const
Context
&
context
);
void
writeText
(
WriteBuffer
&
out
)
const
;
void
readText
(
ReadBuffer
&
in
);
};
}
dbms/src/Storages/StorageReplicatedMergeTree.cpp
浏览文件 @
49439aa2
...
...
@@ -8,6 +8,7 @@
#include <Storages/MergeTree/MergeTreeDataPart.h>
#include <Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h>
#include <Storages/MergeTree/ReplicatedMergeTreeQuorumEntry.h>
#include <Storages/MergeTree/ReplicatedMergeTreeMutationEntry.h>
#include <Storages/MergeTree/MergeList.h>
#include <Storages/MergeTree/ReplicatedMergeTreeAddress.h>
...
...
@@ -278,13 +279,16 @@ void StorageReplicatedMergeTree::createNewZooKeeperNodes()
auto
zookeeper
=
getZooKeeper
();
/// Working with quorum.
zookeeper
->
createIfNotExists
(
zookeeper_path
+
"/quorum"
,
""
);
zookeeper
->
createIfNotExists
(
zookeeper_path
+
"/quorum/last_part"
,
""
);
zookeeper
->
createIfNotExists
(
zookeeper_path
+
"/quorum/failed_parts"
,
""
);
zookeeper
->
createIfNotExists
(
zookeeper_path
+
"/quorum"
,
String
()
);
zookeeper
->
createIfNotExists
(
zookeeper_path
+
"/quorum/last_part"
,
String
()
);
zookeeper
->
createIfNotExists
(
zookeeper_path
+
"/quorum/failed_parts"
,
String
()
);
/// Tracking lag of replicas.
zookeeper
->
createIfNotExists
(
replica_path
+
"/min_unprocessed_insert_time"
,
""
);
zookeeper
->
createIfNotExists
(
replica_path
+
"/max_processed_insert_time"
,
""
);
zookeeper
->
createIfNotExists
(
replica_path
+
"/min_unprocessed_insert_time"
,
String
());
zookeeper
->
createIfNotExists
(
replica_path
+
"/max_processed_insert_time"
,
String
());
/// Mutations
zookeeper
->
createIfNotExists
(
zookeeper_path
+
"/mutations"
,
String
());
}
...
...
@@ -3392,6 +3396,53 @@ void StorageReplicatedMergeTree::freezePartition(const ASTPtr & partition, const
}
void
StorageReplicatedMergeTree
::
mutate
(
const
MutationCommands
&
commands
,
const
Context
&
)
{
ReplicatedMergeTreeMutationEntry
entry
;
entry
.
source_replica
=
replica_name
;
entry
.
commands
=
commands
;
String
mutations_path
=
zookeeper_path
+
"/mutations"
;
/// Update the mutations_path node when creating the mutation and check its version to ensure that
/// nodes for mutations are created in the same order as the corresponding block numbers.
/// Should work well if the number of concurrent mutation requests is small.
while
(
true
)
{
auto
zookeeper
=
getZooKeeper
();
zkutil
::
Stat
mutations_stat
;
zookeeper
->
get
(
mutations_path
,
&
mutations_stat
);
EphemeralLocksInAllPartitions
block_number_locks
(
zookeeper_path
+
"/block_numbers"
,
"block-"
,
zookeeper_path
+
"/temp"
,
*
zookeeper
);
for
(
const
auto
&
lock
:
block_number_locks
.
getLocks
())
entry
.
block_numbers
[
lock
.
partition_id
]
=
lock
.
number
;
entry
.
create_time
=
time
(
nullptr
);
zkutil
::
Requests
requests
;
requests
.
emplace_back
(
zkutil
::
makeSetRequest
(
mutations_path
,
String
(),
mutations_stat
.
version
));
requests
.
emplace_back
(
zkutil
::
makeCreateRequest
(
mutations_path
+
"/"
,
entry
.
toString
(),
zkutil
::
CreateMode
::
PersistentSequential
));
zkutil
::
Responses
responses
;
int32_t
rc
=
zookeeper
->
tryMulti
(
requests
,
responses
);
if
(
rc
==
ZooKeeperImpl
::
ZooKeeper
::
ZOK
)
break
;
else
if
(
rc
==
ZooKeeperImpl
::
ZooKeeper
::
ZBADVERSION
)
{
LOG_TRACE
(
log
,
"Version conflict when trying to create a mutation node, retrying..."
);
continue
;
}
else
throw
zkutil
::
KeeperException
(
"Unable to create a mutation znode"
,
rc
);
}
}
void
StorageReplicatedMergeTree
::
clearOldPartsAndRemoveFromZK
()
{
/// Critical section is not required (since grabOldParts() returns unique part set on each call)
...
...
dbms/src/Storages/StorageReplicatedMergeTree.h
浏览文件 @
49439aa2
...
...
@@ -117,6 +117,8 @@ public:
void
fetchPartition
(
const
ASTPtr
&
partition
,
const
String
&
from
,
const
Context
&
context
)
override
;
void
freezePartition
(
const
ASTPtr
&
partition
,
const
String
&
with_name
,
const
Context
&
context
)
override
;
void
mutate
(
const
MutationCommands
&
commands
,
const
Context
&
context
)
override
;
/** Removes a replica from ZooKeeper. If there are no other replicas, it deletes the entire table from ZooKeeper.
*/
void
drop
()
override
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录