Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
6571769d
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,发现更多精彩内容 >>
提交
6571769d
编写于
9月 20, 2015
作者:
A
Alexey Milovidov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dbms: added setting 'select_sequential_consistency' [#METR-16779].
上级
3b5a3e73
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
56 addition
and
8 deletion
+56
-8
dbms/include/DB/Core/ErrorCodes.h
dbms/include/DB/Core/ErrorCodes.h
+1
-0
dbms/include/DB/Interpreters/Settings.h
dbms/include/DB/Interpreters/Settings.h
+3
-0
dbms/include/DB/Storages/MergeTree/MergeTreeDataSelectExecutor.h
...clude/DB/Storages/MergeTree/MergeTreeDataSelectExecutor.h
+5
-3
dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp
dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp
+7
-2
dbms/src/Storages/StorageMergeTree.cpp
dbms/src/Storages/StorageMergeTree.cpp
+1
-1
dbms/src/Storages/StorageReplicatedMergeTree.cpp
dbms/src/Storages/StorageReplicatedMergeTree.cpp
+39
-2
未找到文件。
dbms/include/DB/Core/ErrorCodes.h
浏览文件 @
6571769d
...
...
@@ -291,6 +291,7 @@ namespace ErrorCodes
UNSATISFIED_QUORUM_FOR_PREVIOUS_WRITE
=
286
,
UNKNOWN_FORMAT_VERSION
=
287
,
DISTRIBUTED_IN_JOIN_SUBQUERY_DENIED
=
288
,
REPLICA_IS_NOT_IN_QUORUM
=
289
,
KEEPER_EXCEPTION
=
999
,
POCO_EXCEPTION
=
1000
,
...
...
dbms/include/DB/Interpreters/Settings.h
浏览文件 @
6571769d
...
...
@@ -163,6 +163,9 @@ struct Settings
\
/** Для запросов INSERT в реплицируемую таблицу, ждать записи на указанное число реплик и лианеризовать добавление данных. 0 - отключено. */
\
M(SettingUInt64, insert_quorum, 0) \
/** Для запросов SELECT из реплицируемой таблицы, кидать исключение, если на реплике нет куска, записанного с кворумом; \
* не читать куски, которые ещё не были записаны с кворумом. */
\
M(SettingUInt64, select_sequential_consistency, 0) \
/// Всевозможные ограничения на выполнение запроса.
Limits
limits
;
...
...
dbms/include/DB/Storages/MergeTree/MergeTreeDataSelectExecutor.h
浏览文件 @
6571769d
...
...
@@ -18,6 +18,7 @@ public:
/** При чтении, выбирается набор кусков, покрывающий нужный диапазон индекса.
* Если inout_part_index != nullptr, из этого счетчика берутся значения для виртуального столбца _part_index.
* max_block_number_to_read - если не ноль - не читать все куски, у которых правая граница больше этого порога.
*/
BlockInputStreams
read
(
const
Names
&
column_names
,
...
...
@@ -25,9 +26,10 @@ public:
const
Context
&
context
,
const
Settings
&
settings
,
QueryProcessingStage
::
Enum
&
processed_stage
,
size_t
max_block_size
=
DEFAULT_BLOCK_SIZE
,
unsigned
threads
=
1
,
size_t
*
inout_part_index
=
nullptr
);
size_t
max_block_size
,
unsigned
threads
,
size_t
*
inout_part_index
,
Int64
max_block_number_to_read
);
private:
MergeTreeData
&
data
;
...
...
dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp
浏览文件 @
6571769d
...
...
@@ -44,7 +44,8 @@ BlockInputStreams MergeTreeDataSelectExecutor::read(
QueryProcessingStage
::
Enum
&
processed_stage
,
const
size_t
max_block_size
,
const
unsigned
threads
,
size_t
*
part_index
)
size_t
*
part_index
,
Int64
max_block_number_to_read
)
{
size_t
part_index_var
=
0
;
if
(
!
part_index
)
...
...
@@ -82,7 +83,8 @@ BlockInputStreams MergeTreeDataSelectExecutor::read(
if
(
settings
.
force_index_by_date
&&
date_condition
.
alwaysUnknown
())
throw
Exception
(
"Index by date is not used and setting 'force_index_by_date' is set."
,
ErrorCodes
::
INDEX_NOT_USED
);
/// Выберем куски, в которых могут быть данные, удовлетворяющие date_condition, и которые подходят под условие на _part.
/// Выберем куски, в которых могут быть данные, удовлетворяющие date_condition, и которые подходят под условие на _part,
/// а также max_block_number_to_read.
{
auto
prev_parts
=
parts
;
parts
.
clear
();
...
...
@@ -98,6 +100,9 @@ BlockInputStreams MergeTreeDataSelectExecutor::read(
if
(
!
date_condition
.
mayBeTrueInRange
(
&
left
,
&
right
))
continue
;
if
(
part
->
right
>
max_block_number_to_read
)
continue
;
parts
.
push_back
(
part
);
}
}
...
...
dbms/src/Storages/StorageMergeTree.cpp
浏览文件 @
6571769d
...
...
@@ -125,7 +125,7 @@ BlockInputStreams StorageMergeTree::read(
if
(
select
.
where_expression
&&
!
select
.
prewhere_expression
)
MergeTreeWhereOptimizer
{
select
,
data
,
column_names
,
log
};
return
reader
.
read
(
column_names
,
query
,
context
,
settings
,
processed_stage
,
max_block_size
,
threads
);
return
reader
.
read
(
column_names
,
query
,
context
,
settings
,
processed_stage
,
max_block_size
,
threads
,
nullptr
,
0
);
}
BlockOutputStreamPtr
StorageMergeTree
::
write
(
ASTPtr
query
,
const
Settings
&
settings
)
...
...
dbms/src/Storages/StorageReplicatedMergeTree.cpp
浏览文件 @
6571769d
...
...
@@ -2435,7 +2435,7 @@ BlockInputStreams StorageReplicatedMergeTree::read(
{
res
=
unreplicated_reader
->
read
(
real_column_names
,
query
,
context
,
settings
,
processed_stage
,
max_block_size
,
threads
,
&
part_index
);
max_block_size
,
threads
,
&
part_index
,
0
);
for
(
auto
&
virtual_column
:
virt_column_names
)
{
...
...
@@ -2449,7 +2449,44 @@ BlockInputStreams StorageReplicatedMergeTree::read(
if
(
values
.
count
(
1
))
{
auto
res2
=
reader
.
read
(
real_column_names
,
query
,
context
,
settings
,
processed_stage
,
max_block_size
,
threads
,
&
part_index
);
/** Настройка select_sequential_consistency имеет два смысла:
* 1. Кидать исключение, если на реплике есть не все куски, которые были записаны на кворум остальных реплик.
* 2. Не читать куски, которые ещё не были записаны на кворум реплик.
* Для этого приходится синхронно сходить в ZooKeeper.
*/
Int64
max_block_number_to_read
=
0
;
if
(
settings
.
select_sequential_consistency
)
{
auto
zookeeper
=
getZooKeeper
();
String
last_part
;
zookeeper
->
tryGet
(
zookeeper_path
+
"/quorum/last_part"
,
last_part
);
if
(
!
last_part
.
empty
()
&&
!
data
.
getPartIfExists
(
last_part
))
/// TODO Отключение реплики при распределённых запросах.
throw
Exception
(
"Replica doesn't have part "
+
last_part
+
" which was successfully written to quorum of other replicas."
" Send query to another replica or disable 'select_sequential_consistency' setting."
,
ErrorCodes
::
REPLICA_IS_NOT_IN_QUORUM
);
if
(
last_part
.
empty
())
/// Если ещё ни один кусок не был записан с кворумом.
{
String
quorum_str
;
if
(
zookeeper
->
tryGet
(
zookeeper_path
+
"/quorum/status"
,
quorum_str
))
{
ReplicatedMergeTreeQuorumEntry
quorum_entry
;
quorum_entry
.
fromString
(
quorum_str
);
ActiveDataPartSet
::
Part
part_info
;
ActiveDataPartSet
::
parsePartName
(
quorum_entry
.
part_name
,
part_info
);
max_block_number_to_read
=
part_info
.
left
-
1
;
}
}
else
{
ActiveDataPartSet
::
Part
part_info
;
ActiveDataPartSet
::
parsePartName
(
last_part
,
part_info
);
max_block_number_to_read
=
part_info
.
right
;
}
}
auto
res2
=
reader
.
read
(
real_column_names
,
query
,
context
,
settings
,
processed_stage
,
max_block_size
,
threads
,
&
part_index
,
max_block_number_to_read
);
for
(
auto
&
virtual_column
:
virt_column_names
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录