Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
85c722ca
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,发现更多精彩内容 >>
提交
85c722ca
编写于
7月 25, 2014
作者:
M
Michael Kolupaev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Merge
上级
a6e8c35b
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
108 addition
and
69 deletion
+108
-69
dbms/include/DB/Storages/MergeTree/MergeTreeData.h
dbms/include/DB/Storages/MergeTree/MergeTreeData.h
+10
-5
dbms/include/DB/Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h
...Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h
+37
-21
dbms/src/Storages/MergeTree/MergeTreeData.cpp
dbms/src/Storages/MergeTree/MergeTreeData.cpp
+34
-22
dbms/src/Storages/StorageReplicatedMergeTree.cpp
dbms/src/Storages/StorageReplicatedMergeTree.cpp
+27
-21
未找到文件。
dbms/include/DB/Storages/MergeTree/MergeTreeData.h
浏览文件 @
85c722ca
...
@@ -617,9 +617,17 @@ public:
...
@@ -617,9 +617,17 @@ public:
*/
*/
void
renameAndDetachPart
(
DataPartPtr
part
,
const
String
&
prefix
);
void
renameAndDetachPart
(
DataPartPtr
part
,
const
String
&
prefix
);
/**
Удалить неактуальные куски. Возвращает имена удаленных кусков
.
/**
Возвращает старые неактуальные куски, которые можно удалить. Одновременно удаляет их из списка кусков, но не с диска
.
*/
*/
Strings
clearOldParts
();
DataPartsVector
grabOldParts
();
/** Обращает изменения, сделанные grabOldParts().
*/
void
addOldParts
(
const
DataPartsVector
&
parts
);
/** Удалить неактуальные куски.
*/
void
clearOldParts
();
/** После вызова dropAllData больше ничего вызывать нельзя.
/** После вызова dropAllData больше ничего вызывать нельзя.
* Удаляет директорию с данными и сбрасывает кеши разжатых блоков и засечек.
* Удаляет директорию с данными и сбрасывает кеши разжатых блоков и засечек.
...
@@ -703,9 +711,6 @@ private:
...
@@ -703,9 +711,6 @@ private:
/// Загрузить множество кусков с данными с диска. Вызывается один раз - при создании объекта.
/// Загрузить множество кусков с данными с диска. Вызывается один раз - при создании объекта.
void
loadDataParts
();
void
loadDataParts
();
/// Определить, не битые ли данные в директории. Проверяет индекс и засечеки, но не сами данные.
bool
isBrokenPart
(
const
String
&
path
);
/** Выражение, преобразующее типы столбцов.
/** Выражение, преобразующее типы столбцов.
* Если преобразований типов нет, out_expression=nullptr.
* Если преобразований типов нет, out_expression=nullptr.
* out_rename_map отображает файлы-столбцы на выходе выражения в новые файлы таблицы.
* out_rename_map отображает файлы-столбцы на выходе выражения в новые файлы таблицы.
...
...
dbms/include/DB/Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h
浏览文件 @
85c722ca
...
@@ -86,36 +86,52 @@ public:
...
@@ -86,36 +86,52 @@ public:
zkutil
::
CreateMode
::
PersistentSequential
));
zkutil
::
CreateMode
::
PersistentSequential
));
block_number_lock
.
getUnlockOps
(
ops
);
block_number_lock
.
getUnlockOps
(
ops
);
auto
code
=
storage
.
zookeeper
->
tryMulti
(
ops
);
try
if
(
code
==
ZOK
)
{
{
transaction
.
commit
();
auto
code
=
storage
.
zookeeper
->
tryMulti
(
ops
);
storage
.
merge_selecting_event
.
set
();
if
(
code
==
ZOK
)
}
else
if
(
code
==
ZNODEEXISTS
)
{
/// Если блок с таким ID уже есть в таблице, откатим его вставку.
String
expected_checksums_str
;
if
(
!
block_id
.
empty
()
&&
storage
.
zookeeper
->
tryGet
(
storage
.
zookeeper_path
+
"/blocks/"
+
block_id
+
"/checksums"
,
expected_checksums_str
))
{
{
LOG_INFO
(
log
,
"Block with ID "
<<
block_id
<<
" already exists; ignoring it (removing part "
<<
part
->
name
<<
")"
);
transaction
.
commit
();
storage
.
merge_selecting_event
.
set
();
auto
expected_checksums
=
MergeTreeData
::
DataPart
::
Checksums
::
parse
(
expected_checksums_str
);
}
else
if
(
code
==
ZNODEEXISTS
)
/// Если данные отличались от тех, что были вставлены ранее с тем же ID, бросим исключение.
{
expected_checksums
.
checkEqual
(
part
->
checksums
,
true
);
/// Если блок с таким ID уже есть в таблице, откатим его вставку.
String
expected_checksums_str
;
if
(
!
block_id
.
empty
()
&&
storage
.
zookeeper
->
tryGet
(
storage
.
zookeeper_path
+
"/blocks/"
+
block_id
+
"/checksums"
,
expected_checksums_str
))
{
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
);
/// Если данные отличались от тех, что были вставлены ранее с тем же ID, бросим исключение.
expected_checksums
.
checkEqual
(
part
->
checksums
,
true
);
}
else
{
throw
Exception
(
"Unexpected ZNODEEXISTS while adding block "
+
toString
(
part_number
)
+
" with ID "
+
block_id
+
": "
+
zkutil
::
ZooKeeper
::
error2string
(
code
),
ErrorCodes
::
UNEXPECTED_ZOOKEEPER_ERROR
);
}
}
}
else
else
{
{
throw
Exception
(
"Unexpected
ZNODEEXISTS
while adding block "
+
toString
(
part_number
)
+
" with ID "
+
block_id
+
": "
throw
Exception
(
"Unexpected
error
while adding block "
+
toString
(
part_number
)
+
" with ID "
+
block_id
+
": "
+
zkutil
::
ZooKeeper
::
error2string
(
code
),
ErrorCodes
::
UNEXPECTED_ZOOKEEPER_ERROR
);
+
zkutil
::
ZooKeeper
::
error2string
(
code
),
ErrorCodes
::
UNEXPECTED_ZOOKEEPER_ERROR
);
}
}
}
}
else
catch
(
zkutil
::
KeeperException
&
e
)
{
{
throw
Exception
(
"Unexpected error while adding block "
+
toString
(
part_number
)
+
" with ID "
+
block_id
+
": "
/** Если потерялось соединение, и мы не знаем, применились ли изменения, нельзя удалять локальный кусок:
+
zkutil
::
ZooKeeper
::
error2string
(
code
),
ErrorCodes
::
UNEXPECTED_ZOOKEEPER_ERROR
);
* если изменения применились, в /blocks/ появился вставленный блок, и его нельзя будет вставить снова.
*/
if
(
e
.
code
==
ZOPERATIONTIMEOUT
||
e
.
code
==
ZCONNECTIONLOSS
)
{
transaction
.
commit
();
}
throw
;
}
}
}
}
}
}
...
...
dbms/src/Storages/MergeTree/MergeTreeData.cpp
浏览文件 @
85c722ca
...
@@ -251,34 +251,14 @@ void MergeTreeData::loadDataParts()
...
@@ -251,34 +251,14 @@ void MergeTreeData::loadDataParts()
}
}
Strings
MergeTreeData
::
clear
OldParts
()
MergeTreeData
::
DataPartsVector
MergeTreeData
::
grab
OldParts
()
{
{
Poco
::
ScopedTry
<
Poco
::
FastMutex
>
lock
;
Poco
::
ScopedTry
<
Poco
::
FastMutex
>
lock
;
Strings
res
;
DataPartsVector
res
;
/// Если метод уже вызван из другого потока (или если all_data_parts прямо сейчас меняют), то можно ничего не делать.
/// Если метод уже вызван из другого потока (или если all_data_parts прямо сейчас меняют), то можно ничего не делать.
if
(
!
lock
.
lock
(
&
all_data_parts_mutex
))
if
(
!
lock
.
lock
(
&
all_data_parts_mutex
))
{
return
res
;
return
res
;
}
time_t
now
=
time
(
0
);
for
(
DataParts
::
iterator
it
=
all_data_parts
.
begin
();
it
!=
all_data_parts
.
end
();)
{
int
ref_count
=
it
->
use_count
();
if
(
ref_count
==
1
&&
/// После этого ref_count не может увеличиться.
(
*
it
)
->
remove_time
<
now
&&
now
-
(
*
it
)
->
remove_time
>
settings
.
old_parts_lifetime
)
{
LOG_DEBUG
(
log
,
"Removing part "
<<
(
*
it
)
->
name
);
res
.
push_back
((
*
it
)
->
name
);
(
*
it
)
->
remove
();
all_data_parts
.
erase
(
it
++
);
}
else
++
it
;
}
/// Удаляем временные директории старше суток.
/// Удаляем временные директории старше суток.
Strings
all_file_names
;
Strings
all_file_names
;
...
@@ -302,9 +282,41 @@ Strings MergeTreeData::clearOldParts()
...
@@ -302,9 +282,41 @@ Strings MergeTreeData::clearOldParts()
}
}
}
}
time_t
now
=
time
(
0
);
for
(
DataParts
::
iterator
it
=
all_data_parts
.
begin
();
it
!=
all_data_parts
.
end
();)
{
int
ref_count
=
it
->
use_count
();
if
(
ref_count
==
1
&&
/// После этого ref_count не может увеличиться.
(
*
it
)
->
remove_time
<
now
&&
now
-
(
*
it
)
->
remove_time
>
settings
.
old_parts_lifetime
)
{
res
.
push_back
(
*
it
);
all_data_parts
.
erase
(
it
++
);
}
else
++
it
;
}
return
res
;
return
res
;
}
}
void
MergeTreeData
::
addOldParts
(
const
MergeTreeData
::
DataPartsVector
&
parts
)
{
Poco
::
ScopedLock
<
Poco
::
FastMutex
>
lock
(
all_data_parts_mutex
);
all_data_parts
.
insert
(
parts
.
begin
(),
parts
.
end
());
}
void
MergeTreeData
::
clearOldParts
()
{
auto
parts_to_remove
=
grabOldParts
();
for
(
DataPartPtr
part
:
parts_to_remove
)
{
LOG_DEBUG
(
log
,
"Removing part "
<<
part
->
name
);
part
->
remove
();
}
}
void
MergeTreeData
::
setPath
(
const
String
&
new_full_path
)
void
MergeTreeData
::
setPath
(
const
String
&
new_full_path
)
{
{
Poco
::
File
(
full_path
).
renameTo
(
new_full_path
);
Poco
::
File
(
full_path
).
renameTo
(
new_full_path
);
...
...
dbms/src/Storages/StorageReplicatedMergeTree.cpp
浏览文件 @
85c722ca
...
@@ -522,21 +522,35 @@ void StorageReplicatedMergeTree::checkPartAndAddToZooKeeper(MergeTreeData::DataP
...
@@ -522,21 +522,35 @@ void StorageReplicatedMergeTree::checkPartAndAddToZooKeeper(MergeTreeData::DataP
void
StorageReplicatedMergeTree
::
clearOldParts
()
void
StorageReplicatedMergeTree
::
clearOldParts
()
{
{
Strings
parts
=
data
.
clearOldParts
();
MergeTreeData
::
DataPartsVector
parts
=
data
.
grabOldParts
();
size_t
count
=
parts
.
size
();
for
(
const
String
&
name
:
parts
)
if
(
!
count
)
return
;
try
{
{
zkutil
::
Ops
ops
;
while
(
!
parts
.
empty
())
ops
.
push_back
(
new
zkutil
::
Op
::
Remove
(
replica_path
+
"/parts/"
+
name
+
"/columns"
,
-
1
));
{
ops
.
push_back
(
new
zkutil
::
Op
::
Remove
(
replica_path
+
"/parts/"
+
name
+
"/checksums"
,
-
1
));
MergeTreeData
::
DataPartPtr
part
=
parts
.
back
();
ops
.
push_back
(
new
zkutil
::
Op
::
Remove
(
replica_path
+
"/parts/"
+
name
,
-
1
));
int32_t
code
=
zookeeper
->
tryMulti
(
ops
);
zkutil
::
Ops
ops
;
if
(
code
!=
ZOK
)
ops
.
push_back
(
new
zkutil
::
Op
::
Remove
(
replica_path
+
"/parts/"
+
part
->
name
+
"/columns"
,
-
1
));
LOG_DEBUG
(
log
,
"Couldn't remove part "
<<
name
<<
" from ZooKeeper: "
<<
zkutil
::
ZooKeeper
::
error2string
(
code
));
ops
.
push_back
(
new
zkutil
::
Op
::
Remove
(
replica_path
+
"/parts/"
+
part
->
name
+
"/checksums"
,
-
1
));
ops
.
push_back
(
new
zkutil
::
Op
::
Remove
(
replica_path
+
"/parts/"
+
part
->
name
,
-
1
));
zookeeper
->
multi
(
ops
);
part
->
remove
();
parts
.
pop_back
();
}
}
catch
(...)
{
data
.
addOldParts
(
parts
);
throw
;
}
}
if
(
!
parts
.
empty
())
LOG_DEBUG
(
log
,
"Removed "
<<
count
<<
" old parts"
);
LOG_DEBUG
(
log
,
"Removed "
<<
parts
.
size
()
<<
" old parts"
);
}
}
void
StorageReplicatedMergeTree
::
clearOldLogs
()
void
StorageReplicatedMergeTree
::
clearOldLogs
()
...
@@ -1462,16 +1476,8 @@ void StorageReplicatedMergeTree::partCheckThread()
...
@@ -1462,16 +1476,8 @@ void StorageReplicatedMergeTree::partCheckThread()
{
{
ProfileEvents
::
increment
(
ProfileEvents
::
ReplicatedPartChecksFailed
);
ProfileEvents
::
increment
(
ProfileEvents
::
ReplicatedPartChecksFailed
);
/// Если этот кусок еще и получен в результате слияния, это уже чересчур странно.
LOG_ERROR
(
log
,
"Unexpected part "
<<
part_name
<<
". Removing."
);
if
(
part
->
left
!=
part
->
right
)
data
.
renameAndDetachPart
(
part
,
"unexpected_"
);
{
LOG_ERROR
(
log
,
"Unexpected part "
<<
part_name
<<
" is a result of a merge. You have to resolve this manually."
);
}
else
{
LOG_ERROR
(
log
,
"Unexpected part "
<<
part_name
<<
". Removing."
);
data
.
renameAndDetachPart
(
part
,
"unexpected_"
);
}
}
}
}
}
else
else
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录