Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
faafb365
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,发现更多精彩内容 >>
提交
faafb365
编写于
7月 01, 2014
作者:
M
Michael Kolupaev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Merge
上级
201e6318
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
118 addition
and
37 deletion
+118
-37
dbms/include/DB/Storages/MergeTree/MergeTreeData.h
dbms/include/DB/Storages/MergeTree/MergeTreeData.h
+44
-2
dbms/include/DB/Storages/MergeTree/MergeTreeDataMerger.h
dbms/include/DB/Storages/MergeTree/MergeTreeDataMerger.h
+2
-1
dbms/include/DB/Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h
...Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h
+23
-26
dbms/src/Storages/MergeTree/MergeTreeData.cpp
dbms/src/Storages/MergeTree/MergeTreeData.cpp
+31
-3
dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp
dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp
+3
-2
dbms/src/Storages/StorageReplicatedMergeTree.cpp
dbms/src/Storages/StorageReplicatedMergeTree.cpp
+7
-2
libs/libzkutil/include/zkutil/LeaderElection.h
libs/libzkutil/include/zkutil/LeaderElection.h
+7
-0
libs/libzkutil/src/ZooKeeper.cpp
libs/libzkutil/src/ZooKeeper.cpp
+1
-1
未找到文件。
dbms/include/DB/Storages/MergeTree/MergeTreeData.h
浏览文件 @
faafb365
...
...
@@ -353,6 +353,43 @@ public:
typedef
std
::
vector
<
DataPartPtr
>
DataPartsVector
;
/// Некоторые операции над множеством кусков могут возвращать такой объект.
/// Если не был вызван commit, деструктор откатывает операцию.
class
Transaction
:
private
boost
::
noncopyable
{
public:
Transaction
()
{}
void
commit
()
{
data
=
nullptr
;
removed_parts
.
clear
();
added_parts
.
clear
();
}
~
Transaction
()
{
try
{
if
(
data
&&
(
!
removed_parts
.
empty
()
||
!
added_parts
.
empty
()))
{
LOG_DEBUG
(
data
->
log
,
"Undoing transaction"
);
data
->
replaceParts
(
removed_parts
,
added_parts
);
}
}
catch
(...)
{
tryLogCurrentException
(
"~MergeTreeData::Transaction"
);
}
}
private:
friend
class
MergeTreeData
;
MergeTreeData
*
data
=
nullptr
;
DataPartsVector
removed_parts
;
DataPartsVector
added_parts
;
};
/// Режим работы. См. выше.
enum
Mode
{
...
...
@@ -422,13 +459,18 @@ public:
/** Переименовывает временный кусок в постоянный и добавляет его в рабочий набор.
* Если increment!=nullptr, индекс куска берется из инкремента. Иначе индекс куска не меняется.
* Предполагается, что кусок не пересекается с существующими.
* Если out_transaction не nullptr, присваивает туда объект, позволяющий откатить добавление куска (но не переименование).
*/
void
renameTempPartAndAdd
(
MutableDataPartPtr
part
,
Increment
*
increment
=
nullptr
);
void
renameTempPartAndAdd
(
MutableDataPartPtr
part
,
Increment
*
increment
=
nullptr
,
Transaction
*
out_transaction
=
nullptr
);
/** То же, что renameTempPartAndAdd, но кусок может покрывать существующие куски.
* Удаляет и возвращает все куски, покрытые добавляемым (в возрастающем порядке).
*/
DataPartsVector
renameTempPartAndReplace
(
MutableDataPartPtr
part
,
Increment
*
increment
=
nullptr
);
DataPartsVector
renameTempPartAndReplace
(
MutableDataPartPtr
part
,
Increment
*
increment
=
nullptr
,
Transaction
*
out_transaction
=
nullptr
);
/** Убирает из рабочего набора куски remove и добавляет куски add.
*/
void
replaceParts
(
const
DataPartsVector
&
remove
,
const
DataPartsVector
&
add
);
/** Переименовывает кусок в prefix_кусок и убирает его из рабочего набора.
* Лучше использовать только когда никто не может читать или писать этот кусок
...
...
dbms/include/DB/Storages/MergeTree/MergeTreeDataMerger.h
浏览文件 @
faafb365
...
...
@@ -35,7 +35,8 @@ public:
const
AllowedMergingPredicate
&
can_merge
);
/// Сливает куски.
MergeTreeData
::
DataPartPtr
mergeParts
(
const
MergeTreeData
::
DataPartsVector
&
parts
,
const
String
&
merged_name
);
MergeTreeData
::
DataPartPtr
mergeParts
(
const
MergeTreeData
::
DataPartsVector
&
parts
,
const
String
&
merged_name
,
MergeTreeData
::
Transaction
*
out_transaction
=
nullptr
);
/// Примерное количество места на диске, нужное для мерджа. С запасом.
size_t
estimateDiskSpaceForMerge
(
const
MergeTreeData
::
DataPartsVector
&
parts
);
...
...
dbms/include/DB/Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h
浏览文件 @
faafb365
...
...
@@ -45,7 +45,8 @@ public:
LOG_DEBUG
(
log
,
"Wrote block "
<<
part_number
<<
" with ID "
<<
block_id
);
storage
.
data
.
renameTempPartAndAdd
(
part
);
MergeTreeData
::
Transaction
transaction
;
/// Если не получится добавить кусок в ZK, снова уберем его из рабочего набора.
storage
.
data
.
renameTempPartAndAdd
(
part
,
nullptr
,
&
transaction
);
StorageReplicatedMergeTree
::
LogEntry
log_entry
;
log_entry
.
type
=
StorageReplicatedMergeTree
::
LogEntry
::
GET_PART
;
...
...
@@ -81,13 +82,13 @@ public:
block_number_lock
.
getUnlockOps
(
ops
);
auto
code
=
storage
.
zookeeper
->
tryMulti
(
ops
);
if
(
code
!
=
ZOK
)
if
(
code
=
=
ZOK
)
{
if
(
code
==
ZNODEEXISTS
)
transaction
.
commit
();
}
else
if
(
code
==
ZNODEEXISTS
)
{
/// Если блок с таким ID уже есть в таблице, не будем его вставлять, и удалим только что записанные данные.
/// NOTE: В короткое время между renameTempPartAndAdd и deletePart в таблице на этой реплике доступны
/// продублированные данные.
/// Если блок с таким ID уже есть в таблице, откатим его вставку.
String
expected_checksums_str
;
if
(
!
block_id
.
empty
()
&&
storage
.
zookeeper
->
tryGet
(
storage
.
zookeeper_path
+
"/blocks/"
+
block_id
+
"/checksums"
,
expected_checksums_str
))
...
...
@@ -95,9 +96,6 @@ public:
LOG_INFO
(
log
,
"Block with ID "
<<
block_id
<<
" already exists; ignoring it (removing part "
<<
part
->
name
<<
")"
);
auto
expected_checksums
=
MergeTreeData
::
DataPart
::
Checksums
::
parse
(
expected_checksums_str
);
auto
found_checksums
=
part
->
checksums
;
storage
.
data
.
deletePart
(
part
);
/// Если данные отличались от тех, что были вставлены ранее с тем же ID, бросим исключение.
expected_checksums
.
checkEqual
(
part
->
checksums
,
true
);
...
...
@@ -115,7 +113,6 @@ public:
}
}
}
}
private:
StorageReplicatedMergeTree
&
storage
;
...
...
dbms/src/Storages/MergeTree/MergeTreeData.cpp
浏览文件 @
faafb365
...
...
@@ -584,9 +584,9 @@ void MergeTreeData::commitAlterModify(const ASTAlterQuery::Parameters & params)
}
void
MergeTreeData
::
renameTempPartAndAdd
(
MutableDataPartPtr
part
,
Increment
*
increment
)
void
MergeTreeData
::
renameTempPartAndAdd
(
MutableDataPartPtr
part
,
Increment
*
increment
,
Transaction
*
out_transaction
)
{
auto
removed
=
renameTempPartAndReplace
(
part
,
increment
);
auto
removed
=
renameTempPartAndReplace
(
part
,
increment
,
out_transaction
);
if
(
!
removed
.
empty
())
{
LOG_ERROR
(
log
,
"Added part "
<<
part
->
name
<<
+
" covers "
<<
toString
(
removed
.
size
())
...
...
@@ -594,8 +594,12 @@ void MergeTreeData::renameTempPartAndAdd(MutableDataPartPtr part, Increment * in
}
}
MergeTreeData
::
DataPartsVector
MergeTreeData
::
renameTempPartAndReplace
(
MutableDataPartPtr
part
,
Increment
*
increment
)
MergeTreeData
::
DataPartsVector
MergeTreeData
::
renameTempPartAndReplace
(
MutableDataPartPtr
part
,
Increment
*
increment
,
Transaction
*
out_transaction
)
{
if
(
out_transaction
&&
out_transaction
->
data
)
throw
Exception
(
"Using the same MergeTreeData::Transaction for overlapping transactions is invalid"
);
LOG_TRACE
(
log
,
"Renaming "
<<
part
->
name
<<
"."
);
Poco
::
ScopedLock
<
Poco
::
FastMutex
>
lock
(
data_parts_mutex
);
...
...
@@ -665,9 +669,33 @@ MergeTreeData::DataPartsVector MergeTreeData::renameTempPartAndReplace(MutableDa
all_data_parts
.
insert
(
part
);
if
(
out_transaction
)
{
out_transaction
->
data
=
this
;
out_transaction
->
added_parts
=
res
;
out_transaction
->
removed_parts
=
DataPartsVector
(
1
,
part
);
}
return
res
;
}
void
MergeTreeData
::
replaceParts
(
const
DataPartsVector
&
remove
,
const
DataPartsVector
&
add
)
{
LOG_TRACE
(
log
,
"Removing "
<<
remove
.
size
()
<<
" parts and adding "
<<
add
.
size
()
<<
" parts."
);
Poco
::
ScopedLock
<
Poco
::
FastMutex
>
lock
(
data_parts_mutex
);
for
(
const
DataPartPtr
&
part
:
remove
)
{
part
->
remove_time
=
time
(
0
);
data_parts
.
erase
(
part
);
}
for
(
const
DataPartPtr
&
part
:
add
)
{
data_parts
.
insert
(
part
);
}
}
void
MergeTreeData
::
renameAndDetachPart
(
DataPartPtr
part
,
const
String
&
prefix
)
{
Poco
::
ScopedLock
<
Poco
::
FastMutex
>
lock
(
data_parts_mutex
);
...
...
dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp
浏览文件 @
faafb365
...
...
@@ -248,7 +248,8 @@ bool MergeTreeDataMerger::selectPartsToMerge(MergeTreeData::DataPartsVector & pa
/// parts должны быть отсортированы.
MergeTreeData
::
DataPartPtr
MergeTreeDataMerger
::
mergeParts
(
const
MergeTreeData
::
DataPartsVector
&
parts
,
const
String
&
merged_name
)
MergeTreeData
::
DataPartPtr
MergeTreeDataMerger
::
mergeParts
(
const
MergeTreeData
::
DataPartsVector
&
parts
,
const
String
&
merged_name
,
MergeTreeData
::
Transaction
*
out_transaction
)
{
LOG_DEBUG
(
log
,
"Merging "
<<
parts
.
size
()
<<
" parts: from "
<<
parts
.
front
()
->
name
<<
" to "
<<
parts
.
back
()
->
name
<<
" into "
<<
merged_name
);
...
...
@@ -329,7 +330,7 @@ MergeTreeData::DataPartPtr MergeTreeDataMerger::mergeParts(const MergeTreeData::
new_data_part
->
size_in_bytes
=
MergeTreeData
::
DataPart
::
calcTotalSize
(
new_part_tmp_path
);
/// Переименовываем новый кусок, добавляем в набор и убираем исходные куски.
auto
replaced_parts
=
data
.
renameTempPartAndReplace
(
new_data_part
);
auto
replaced_parts
=
data
.
renameTempPartAndReplace
(
new_data_part
,
nullptr
,
out_transaction
);
if
(
new_data_part
->
name
!=
merged_name
)
LOG_ERROR
(
log
,
"Unexpected part name: "
<<
new_data_part
->
name
<<
" instead of "
<<
merged_name
);
...
...
dbms/src/Storages/StorageReplicatedMergeTree.cpp
浏览文件 @
faafb365
...
...
@@ -776,12 +776,14 @@ void StorageReplicatedMergeTree::executeLogEntry(const LogEntry & entry)
}
else
{
MergeTreeData
::
DataPartPtr
part
=
merger
.
mergeParts
(
parts
,
entry
.
new_part_name
);
MergeTreeData
::
Transaction
transaction
;
MergeTreeData
::
DataPartPtr
part
=
merger
.
mergeParts
(
parts
,
entry
.
new_part_name
,
&
transaction
);
zkutil
::
Ops
ops
;
checkPartAndAddToZooKeeper
(
part
,
ops
);
zookeeper
->
multi
(
ops
);
transaction
.
commit
();
ProfileEvents
::
increment
(
ProfileEvents
::
ReplicatedPartMerges
);
}
...
...
@@ -1183,12 +1185,15 @@ void StorageReplicatedMergeTree::fetchPart(const String & part_name, const Strin
assertEOF
(
buf
);
MergeTreeData
::
MutableDataPartPtr
part
=
fetcher
.
fetchPart
(
part_name
,
zookeeper_path
+
"/replicas/"
+
replica_name
,
host
,
port
);
auto
removed_parts
=
data
.
renameTempPartAndReplace
(
part
);
MergeTreeData
::
Transaction
transaction
;
auto
removed_parts
=
data
.
renameTempPartAndReplace
(
part
,
nullptr
,
&
transaction
);
zkutil
::
Ops
ops
;
checkPartAndAddToZooKeeper
(
part
,
ops
);
zookeeper
->
multi
(
ops
);
transaction
.
commit
();
for
(
const
auto
&
removed_part
:
removed_parts
)
{
...
...
libs/libzkutil/include/zkutil/LeaderElection.h
浏览文件 @
faafb365
...
...
@@ -89,6 +89,8 @@ private:
{
while
(
!
shutdown
)
{
bool
success
=
false
;
try
{
Strings
children
=
zookeeper
.
getChildren
(
path
);
...
...
@@ -106,6 +108,8 @@ private:
if
(
zookeeper
.
exists
(
path
+
"/"
+
*
(
it
-
1
),
nullptr
,
event
))
event
->
tryWait
(
60
*
1000
);
success
=
true
;
}
catch
(
const
DB
::
Exception
&
e
)
{
...
...
@@ -126,6 +130,9 @@ private:
{
LOG_ERROR
(
log
,
"Unknown exception in LeaderElection"
);
}
if
(
!
success
)
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
seconds
(
10
));
}
}
};
...
...
libs/libzkutil/src/ZooKeeper.cpp
浏览文件 @
faafb365
...
...
@@ -294,7 +294,7 @@ std::string ZooKeeper::get(const std::string & path, Stat * stat, EventPtr watch
if
(
tryGet
(
path
,
res
,
stat
,
watch
))
return
res
;
else
throw
KeeperException
(
"
Fail to get data for node "
+
path
);
throw
KeeperException
(
"
Can't get data for node "
+
path
+
": node doesn't exist"
);
}
bool
ZooKeeper
::
tryGet
(
const
std
::
string
&
path
,
std
::
string
&
res
,
Stat
*
stat_
,
EventPtr
watch
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录