mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Merge remote-tracking branch 'upstream/master' into HEAD
This commit is contained in:
commit
3e92c7f61a
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -17,6 +17,7 @@
|
||||
[submodule "contrib/zlib-ng"]
|
||||
path = contrib/zlib-ng
|
||||
url = https://github.com/ClickHouse-Extras/zlib-ng.git
|
||||
branch = clickhouse-new
|
||||
[submodule "contrib/googletest"]
|
||||
path = contrib/googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
@ -227,3 +228,7 @@
|
||||
[submodule "contrib/datasketches-cpp"]
|
||||
path = contrib/datasketches-cpp
|
||||
url = https://github.com/ClickHouse-Extras/datasketches-cpp.git
|
||||
|
||||
[submodule "contrib/yaml-cpp"]
|
||||
path = contrib/yaml-cpp
|
||||
url = https://github.com/ClickHouse-Extras/yaml-cpp.git
|
||||
|
139
CHANGELOG.md
139
CHANGELOG.md
@ -1,3 +1,142 @@
|
||||
## ClickHouse release 21.5, 2021-05-20
|
||||
|
||||
#### Backward Incompatible Change
|
||||
|
||||
* Change comparison of integers and floating point numbers when integer is not exactly representable in the floating point data type. In new version comparison will return false as the rounding error will occur. Example: `9223372036854775808.0 != 9223372036854775808`, because the number `9223372036854775808` is not representable as floating point number exactly (and `9223372036854775808.0` is rounded to `9223372036854776000.0`). But in previous version the comparison will return as the numbers are equal, because if the floating point number `9223372036854776000.0` get converted back to UInt64, it will yield `9223372036854775808`. For the reference, the Python programming language also treats these numbers as equal. But this behaviour was dependend on CPU model (different results on AMD64 and AArch64 for some out-of-range numbers), so we make the comparison more precise. It will treat int and float numbers equal only if int is represented in floating point type exactly. [#22595](https://github.com/ClickHouse/ClickHouse/pull/22595) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Remove support for `argMin` and `argMax` for single `Tuple` argument. The code was not memory-safe. The feature was added by mistake and it is confusing for people. These functions can be reintroduced under different names later. This fixes [#22384](https://github.com/ClickHouse/ClickHouse/issues/22384) and reverts [#17359](https://github.com/ClickHouse/ClickHouse/issues/17359). [#23393](https://github.com/ClickHouse/ClickHouse/pull/23393) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
|
||||
#### New Feature
|
||||
|
||||
* Added functions `dictGetChildren(dictionary, key)`, `dictGetDescendants(dictionary, key, level)`. Function `dictGetChildren` return all children as an array if indexes. It is a inverse transformation for `dictGetHierarchy`. Function `dictGetDescendants` return all descendants as if `dictGetChildren` was applied `level` times recursively. Zero `level` value is equivalent to infinity. Improved performance of `dictGetHierarchy`, `dictIsIn` functions. Closes [#14656](https://github.com/ClickHouse/ClickHouse/issues/14656). [#22096](https://github.com/ClickHouse/ClickHouse/pull/22096) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Added function `dictGetOrNull`. It works like `dictGet`, but return `Null` in case key was not found in dictionary. Closes [#22375](https://github.com/ClickHouse/ClickHouse/issues/22375). [#22413](https://github.com/ClickHouse/ClickHouse/pull/22413) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Added a table function `s3Cluster`, which allows to process files from `s3` in parallel on every node of a specified cluster. [#22012](https://github.com/ClickHouse/ClickHouse/pull/22012) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||
* Added support for replicas and shards in MySQL/PostgreSQL table engine / table function. You can write `SELECT * FROM mysql('host{1,2}-{1|2}', ...)`. Closes [#20969](https://github.com/ClickHouse/ClickHouse/issues/20969). [#22217](https://github.com/ClickHouse/ClickHouse/pull/22217) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||
* Added `ALTER TABLE ... FETCH PART ...` query. It's similar to `FETCH PARTITION`, but fetches only one part. [#22706](https://github.com/ClickHouse/ClickHouse/pull/22706) ([turbo jason](https://github.com/songenjie)).
|
||||
* Added a setting `max_distributed_depth` that limits the depth of recursive queries to `Distributed` tables. Closes [#20229](https://github.com/ClickHouse/ClickHouse/issues/20229). [#21942](https://github.com/ClickHouse/ClickHouse/pull/21942) ([flynn](https://github.com/ucasFL)).
|
||||
|
||||
#### Performance Improvement
|
||||
|
||||
* Improved performance of `intDiv` by dynamic dispatch for AVX2. This closes [#22314](https://github.com/ClickHouse/ClickHouse/issues/22314). [#23000](https://github.com/ClickHouse/ClickHouse/pull/23000) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Improved performance of reading from `ArrowStream` input format for sources other then local file (e.g. URL). [#22673](https://github.com/ClickHouse/ClickHouse/pull/22673) ([nvartolomei](https://github.com/nvartolomei)).
|
||||
* Disabled compression by default when interacting with localhost (with clickhouse-client or server to server with distributed queries) via native protocol. It may improve performance of some import/export operations. This closes [#22234](https://github.com/ClickHouse/ClickHouse/issues/22234). [#22237](https://github.com/ClickHouse/ClickHouse/pull/22237) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Exclude values that does not belong to the shard from right part of IN section for distributed queries (under `optimize_skip_unused_shards_rewrite_in`, enabled by default, since it still requires `optimize_skip_unused_shards`). [#21511](https://github.com/ClickHouse/ClickHouse/pull/21511) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Improved performance of reading a subset of columns with File-like table engine and column-oriented format like Parquet, Arrow or ORC. This closes [#issue:20129](https://github.com/ClickHouse/ClickHouse/issues/20129). [#21302](https://github.com/ClickHouse/ClickHouse/pull/21302) ([keenwolf](https://github.com/keen-wolf)).
|
||||
* Allow to move more conditions to `PREWHERE` as it was before version 21.1 (adjustment of internal heuristics). Insufficient number of moved condtions could lead to worse performance. [#23397](https://github.com/ClickHouse/ClickHouse/pull/23397) ([Anton Popov](https://github.com/CurtizJ)).
|
||||
* Improved performance of ODBC connections and fixed all the outstanding issues from the backlog. Using `nanodbc` library instead of `Poco::ODBC`. Closes [#9678](https://github.com/ClickHouse/ClickHouse/issues/9678). Add support for DateTime64 and Decimal* for ODBC table engine. Closes [#21961](https://github.com/ClickHouse/ClickHouse/issues/21961). Fixed issue with cyrillic text being truncated. Closes [#16246](https://github.com/ClickHouse/ClickHouse/issues/16246). Added connection pools for odbc bridge. [#21972](https://github.com/ClickHouse/ClickHouse/pull/21972) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||
|
||||
#### Improvement
|
||||
|
||||
* Increase `max_uri_size` (the maximum size of URL in HTTP interface) to 1 MiB by default. This closes [#21197](https://github.com/ClickHouse/ClickHouse/issues/21197). [#22997](https://github.com/ClickHouse/ClickHouse/pull/22997) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Set `background_fetches_pool_size` to `8` that is better for production usage with frequent small insertions or slow ZooKeeper cluster. [#22945](https://github.com/ClickHouse/ClickHouse/pull/22945) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* FlatDictionary added `initial_array_size`, `max_array_size` options. [#22521](https://github.com/ClickHouse/ClickHouse/pull/22521) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Add new setting `non_replicated_deduplication_window` for non-replicated MergeTree inserts deduplication. [#22514](https://github.com/ClickHouse/ClickHouse/pull/22514) ([alesapin](https://github.com/alesapin)).
|
||||
* Update paths to the `CatBoost` model configs in config reloading. [#22434](https://github.com/ClickHouse/ClickHouse/pull/22434) ([Kruglov Pavel](https://github.com/Avogar)).
|
||||
* Added `Decimal256` type support in dictionaries. `Decimal256` is experimental feature. Closes [#20979](https://github.com/ClickHouse/ClickHouse/issues/20979). [#22960](https://github.com/ClickHouse/ClickHouse/pull/22960) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Enabled `async_socket_for_remote` by default (using less amount of OS threads for distributed queries). [#23683](https://github.com/ClickHouse/ClickHouse/pull/23683) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||
* Fixed `quantile(s)TDigest`. Added special handling of singleton centroids according to tdunning/t-digest 3.2+. Also a bug with over-compression of centroids in implementation of earlier version of the algorithm was fixed. [#23314](https://github.com/ClickHouse/ClickHouse/pull/23314) ([Vladimir Chebotarev](https://github.com/excitoon)).
|
||||
* Make function name `unhex` case insensitive for compatibility with MySQL. [#23229](https://github.com/ClickHouse/ClickHouse/pull/23229) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Implement functions `arrayHasAny`, `arrayHasAll`, `has`, `indexOf`, `countEqual` for generic case when types of array elements are different. In previous versions the functions `arrayHasAny`, `arrayHasAll` returned false and `has`, `indexOf`, `countEqual` thrown exception. Also add support for `Decimal` and big integer types in functions `has` and similar. This closes [#20272](https://github.com/ClickHouse/ClickHouse/issues/20272). [#23044](https://github.com/ClickHouse/ClickHouse/pull/23044) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Raised the threshold on max number of matches in result of the function `extractAllGroupsHorizontal`. [#23036](https://github.com/ClickHouse/ClickHouse/pull/23036) ([Vasily Nemkov](https://github.com/Enmk)).
|
||||
* Do not perform `optimize_skip_unused_shards` for cluster with one node. [#22999](https://github.com/ClickHouse/ClickHouse/pull/22999) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Added ability to run clickhouse-keeper (experimental drop-in replacement to ZooKeeper) with SSL. Config settings `keeper_server.tcp_port_secure` can be used for secure interaction between client and keeper-server. `keeper_server.raft_configuration.secure` can be used to enable internal secure communication between nodes. [#22992](https://github.com/ClickHouse/ClickHouse/pull/22992) ([alesapin](https://github.com/alesapin)).
|
||||
* Added ability to flush buffer only in background for `Buffer` tables. [#22986](https://github.com/ClickHouse/ClickHouse/pull/22986) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* When selecting from MergeTree table with NULL in WHERE condition, in rare cases, exception was thrown. This closes [#20019](https://github.com/ClickHouse/ClickHouse/issues/20019). [#22978](https://github.com/ClickHouse/ClickHouse/pull/22978) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Fix error handling in Poco HTTP Client for AWS. [#22973](https://github.com/ClickHouse/ClickHouse/pull/22973) ([kreuzerkrieg](https://github.com/kreuzerkrieg)).
|
||||
* Respect `max_part_removal_threads` for `ReplicatedMergeTree`. [#22971](https://github.com/ClickHouse/ClickHouse/pull/22971) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Fix obscure corner case of MergeTree settings inactive_parts_to_throw_insert = 0 with inactive_parts_to_delay_insert > 0. [#22947](https://github.com/ClickHouse/ClickHouse/pull/22947) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* `dateDiff` now works with `DateTime64` arguments (even for values outside of `DateTime` range) [#22931](https://github.com/ClickHouse/ClickHouse/pull/22931) ([Vasily Nemkov](https://github.com/Enmk)).
|
||||
* MaterializeMySQL (experimental feature): added an ability to replicate MySQL databases containing views without failing. This is accomplished by ignoring the views. [#22760](https://github.com/ClickHouse/ClickHouse/pull/22760) ([Christian](https://github.com/cfroystad)).
|
||||
* Allow RBAC row policy via postgresql protocol. Closes [#22658](https://github.com/ClickHouse/ClickHouse/issues/22658). PostgreSQL protocol is enabled in configuration by default. [#22755](https://github.com/ClickHouse/ClickHouse/pull/22755) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||
* Add metric to track how much time is spend during waiting for Buffer layer lock. [#22725](https://github.com/ClickHouse/ClickHouse/pull/22725) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Allow to use CTE in VIEW definition. This closes [#22491](https://github.com/ClickHouse/ClickHouse/issues/22491). [#22657](https://github.com/ClickHouse/ClickHouse/pull/22657) ([Amos Bird](https://github.com/amosbird)).
|
||||
* Clear the rest of the screen and show cursor in `clickhouse-client` if previous program has left garbage in terminal. This closes [#16518](https://github.com/ClickHouse/ClickHouse/issues/16518). [#22634](https://github.com/ClickHouse/ClickHouse/pull/22634) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Make `round` function to behave consistently on non-x86_64 platforms. Rounding half to nearest even (Banker's rounding) is used. [#22582](https://github.com/ClickHouse/ClickHouse/pull/22582) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Correctly check structure of blocks of data that are sending by Distributed tables. [#22325](https://github.com/ClickHouse/ClickHouse/pull/22325) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Allow publishing Kafka errors to a virtual column of Kafka engine, controlled by the `kafka_handle_error_mode` setting. [#21850](https://github.com/ClickHouse/ClickHouse/pull/21850) ([fastio](https://github.com/fastio)).
|
||||
* Add aliases `simpleJSONExtract/simpleJSONHas` to `visitParam/visitParamExtract{UInt, Int, Bool, Float, Raw, String}`. Fixes [#21383](https://github.com/ClickHouse/ClickHouse/issues/21383). [#21519](https://github.com/ClickHouse/ClickHouse/pull/21519) ([fastio](https://github.com/fastio)).
|
||||
* Add `clickhouse-library-bridge` for library dictionary source. Closes [#9502](https://github.com/ClickHouse/ClickHouse/issues/9502). [#21509](https://github.com/ClickHouse/ClickHouse/pull/21509) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||
* Forbid to drop a column if it's referenced by materialized view. Closes [#21164](https://github.com/ClickHouse/ClickHouse/issues/21164). [#21303](https://github.com/ClickHouse/ClickHouse/pull/21303) ([flynn](https://github.com/ucasFL)).
|
||||
* Support dynamic interserver credentials (rotating credentials without downtime). [#14113](https://github.com/ClickHouse/ClickHouse/pull/14113) ([johnskopis](https://github.com/johnskopis)).
|
||||
* Add support for Kafka storage with `Arrow` and `ArrowStream` format messages. [#23415](https://github.com/ClickHouse/ClickHouse/pull/23415) ([Chao Ma](https://github.com/godliness)).
|
||||
* Fixed missing semicolon in exception message. The user may find this exception message unpleasant to read. [#23208](https://github.com/ClickHouse/ClickHouse/pull/23208) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Fixed missing whitespace in some exception messages about `LowCardinality` type. [#23207](https://github.com/ClickHouse/ClickHouse/pull/23207) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Some values were formatted with alignment in center in table cells in `Markdown` format. Not anymore. [#23096](https://github.com/ClickHouse/ClickHouse/pull/23096) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Remove non-essential details from suggestions in clickhouse-client. This closes [#22158](https://github.com/ClickHouse/ClickHouse/issues/22158). [#23040](https://github.com/ClickHouse/ClickHouse/pull/23040) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Correct calculation of `bytes_allocated` field in system.dictionaries for sparse_hashed dictionaries. [#22867](https://github.com/ClickHouse/ClickHouse/pull/22867) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Fixed approximate total rows accounting for reverse reading from MergeTree. [#22726](https://github.com/ClickHouse/ClickHouse/pull/22726) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Fix the case when it was possible to configure dictionary with clickhouse source that was looking to itself that leads to infinite loop. Closes [#14314](https://github.com/ClickHouse/ClickHouse/issues/14314). [#22479](https://github.com/ClickHouse/ClickHouse/pull/22479) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
|
||||
#### Bug Fix
|
||||
|
||||
* Multiple fixes for hedged requests. Fixed an error `Can't initialize pipeline with empty pipe` for queries with `GLOBAL IN/JOIN` when the setting `use_hedged_requests` is enabled. Fixes [#23431](https://github.com/ClickHouse/ClickHouse/issues/23431). [#23805](https://github.com/ClickHouse/ClickHouse/pull/23805) ([Nikolai Kochetov](https://github.com/KochetovNicolai)). Fixed a race condition in hedged connections which leads to crash. This fixes [#22161](https://github.com/ClickHouse/ClickHouse/issues/22161). [#22443](https://github.com/ClickHouse/ClickHouse/pull/22443) ([Kruglov Pavel](https://github.com/Avogar)). Fix possible crash in case if `unknown packet` was received from remote query (with `async_socket_for_remote` enabled). Fixes [#21167](https://github.com/ClickHouse/ClickHouse/issues/21167). [#23309](https://github.com/ClickHouse/ClickHouse/pull/23309) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||
* Fixed the behavior when disabling `input_format_with_names_use_header ` setting discards all the input with CSVWithNames format. This fixes [#22406](https://github.com/ClickHouse/ClickHouse/issues/22406). [#23202](https://github.com/ClickHouse/ClickHouse/pull/23202) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||
* Fixed remote JDBC bridge timeout connection issue. Closes [#9609](https://github.com/ClickHouse/ClickHouse/issues/9609). [#23771](https://github.com/ClickHouse/ClickHouse/pull/23771) ([Maksim Kita](https://github.com/kitaisreal), [alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Fix the logic of initial load of `complex_key_hashed` if `update_field` is specified. Closes [#23800](https://github.com/ClickHouse/ClickHouse/issues/23800). [#23824](https://github.com/ClickHouse/ClickHouse/pull/23824) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Fixed crash when `PREWHERE` and row policy filter are both in effect with empty result. [#23763](https://github.com/ClickHouse/ClickHouse/pull/23763) ([Amos Bird](https://github.com/amosbird)).
|
||||
* Avoid possible "Cannot schedule a task" error (in case some exception had been occurred) on INSERT into Distributed. [#23744](https://github.com/ClickHouse/ClickHouse/pull/23744) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Added an exception in case of completely the same values in both samples in aggregate function `mannWhitneyUTest`. This fixes [#23646](https://github.com/ClickHouse/ClickHouse/issues/23646). [#23654](https://github.com/ClickHouse/ClickHouse/pull/23654) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||
* Fixed server fault when inserting data through HTTP caused an exception. This fixes [#23512](https://github.com/ClickHouse/ClickHouse/issues/23512). [#23643](https://github.com/ClickHouse/ClickHouse/pull/23643) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||
* Fixed misinterpretation of some `LIKE` expressions with escape sequences. [#23610](https://github.com/ClickHouse/ClickHouse/pull/23610) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Fixed restart / stop command hanging. Closes [#20214](https://github.com/ClickHouse/ClickHouse/issues/20214). [#23552](https://github.com/ClickHouse/ClickHouse/pull/23552) ([filimonov](https://github.com/filimonov)).
|
||||
* Fixed `COLUMNS` matcher in case of multiple JOINs in select query. Closes [#22736](https://github.com/ClickHouse/ClickHouse/issues/22736). [#23501](https://github.com/ClickHouse/ClickHouse/pull/23501) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Fixed a crash when modifying column's default value when a column itself is used as `ReplacingMergeTree`'s parameter. [#23483](https://github.com/ClickHouse/ClickHouse/pull/23483) ([hexiaoting](https://github.com/hexiaoting)).
|
||||
* Fixed corner cases in vertical merges with `ReplacingMergeTree`. In rare cases they could lead to fails of merges with exceptions like `Incomplete granules are not allowed while blocks are granules size`. [#23459](https://github.com/ClickHouse/ClickHouse/pull/23459) ([Anton Popov](https://github.com/CurtizJ)).
|
||||
* Fixed bug that does not allow cast from empty array literal, to array with dimensions greater than 1, e.g. `CAST([] AS Array(Array(String)))`. Closes [#14476](https://github.com/ClickHouse/ClickHouse/issues/14476). [#23456](https://github.com/ClickHouse/ClickHouse/pull/23456) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Fixed a bug when `deltaSum` aggregate function produced incorrect result after resetting the counter. [#23437](https://github.com/ClickHouse/ClickHouse/pull/23437) ([Russ Frank](https://github.com/rf)).
|
||||
* Fixed `Cannot unlink file` error on unsuccessful creation of ReplicatedMergeTree table with multidisk configuration. This closes [#21755](https://github.com/ClickHouse/ClickHouse/issues/21755). [#23433](https://github.com/ClickHouse/ClickHouse/pull/23433) ([tavplubix](https://github.com/tavplubix)).
|
||||
* Fixed incompatible constant expression generation during partition pruning based on virtual columns. This fixes https://github.com/ClickHouse/ClickHouse/pull/21401#discussion_r611888913. [#23366](https://github.com/ClickHouse/ClickHouse/pull/23366) ([Amos Bird](https://github.com/amosbird)).
|
||||
* Fixed a crash when setting join_algorithm is set to 'auto' and Join is performed with a Dictionary. Close [#23002](https://github.com/ClickHouse/ClickHouse/issues/23002). [#23312](https://github.com/ClickHouse/ClickHouse/pull/23312) ([Vladimir](https://github.com/vdimir)).
|
||||
* Don't relax NOT conditions during partition pruning. This fixes [#23305](https://github.com/ClickHouse/ClickHouse/issues/23305) and [#21539](https://github.com/ClickHouse/ClickHouse/issues/21539). [#23310](https://github.com/ClickHouse/ClickHouse/pull/23310) ([Amos Bird](https://github.com/amosbird)).
|
||||
* Fixed very rare race condition on background cleanup of old blocks. It might cause a block not to be deduplicated if it's too close to the end of deduplication window. [#23301](https://github.com/ClickHouse/ClickHouse/pull/23301) ([tavplubix](https://github.com/tavplubix)).
|
||||
* Fixed very rare (distributed) race condition between creation and removal of ReplicatedMergeTree tables. It might cause exceptions like `node doesn't exist` on attempt to create replicated table. Fixes [#21419](https://github.com/ClickHouse/ClickHouse/issues/21419). [#23294](https://github.com/ClickHouse/ClickHouse/pull/23294) ([tavplubix](https://github.com/tavplubix)).
|
||||
* Fixed simple key dictionary from DDL creation if primary key is not first attribute. Fixes [#23236](https://github.com/ClickHouse/ClickHouse/issues/23236). [#23262](https://github.com/ClickHouse/ClickHouse/pull/23262) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Fixed reading from ODBC when there are many long column names in a table. Closes [#8853](https://github.com/ClickHouse/ClickHouse/issues/8853). [#23215](https://github.com/ClickHouse/ClickHouse/pull/23215) ([Kseniia Sumarokova](https://github.com/kssenii)).
|
||||
* MaterializeMySQL (experimental feature): fixed `Not found column` error when selecting from `MaterializeMySQL` with condition on key column. Fixes [#22432](https://github.com/ClickHouse/ClickHouse/issues/22432). [#23200](https://github.com/ClickHouse/ClickHouse/pull/23200) ([tavplubix](https://github.com/tavplubix)).
|
||||
* Correct aliases handling if subquery was optimized to constant. Fixes [#22924](https://github.com/ClickHouse/ClickHouse/issues/22924). Fixes [#10401](https://github.com/ClickHouse/ClickHouse/issues/10401). [#23191](https://github.com/ClickHouse/ClickHouse/pull/23191) ([Maksim Kita](https://github.com/kitaisreal)).
|
||||
* Server might fail to start if `data_type_default_nullable` setting is enabled in default profile, it's fixed. Fixes [#22573](https://github.com/ClickHouse/ClickHouse/issues/22573). [#23185](https://github.com/ClickHouse/ClickHouse/pull/23185) ([tavplubix](https://github.com/tavplubix)).
|
||||
* Fixed a crash on shutdown which happened because of wrong accounting of current connections. [#23154](https://github.com/ClickHouse/ClickHouse/pull/23154) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||
* Fixed `Table .inner_id... doesn't exist` error when selecting from Materialized View after detaching it from Atomic database and attaching back. [#23047](https://github.com/ClickHouse/ClickHouse/pull/23047) ([tavplubix](https://github.com/tavplubix)).
|
||||
* Fix error `Cannot find column in ActionsDAG result` which may happen if subquery uses `untuple`. Fixes [#22290](https://github.com/ClickHouse/ClickHouse/issues/22290). [#22991](https://github.com/ClickHouse/ClickHouse/pull/22991) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||
* Fix usage of constant columns of type `Map` with nullable values. [#22939](https://github.com/ClickHouse/ClickHouse/pull/22939) ([Anton Popov](https://github.com/CurtizJ)).
|
||||
* fixed `formatDateTime()` on `DateTime64` and "%C" format specifier fixed `toDateTime64()` for large values and non-zero scale. [#22937](https://github.com/ClickHouse/ClickHouse/pull/22937) ([Vasily Nemkov](https://github.com/Enmk)).
|
||||
* Fixed a crash when using `mannWhitneyUTest` and `rankCorr` with window functions. This fixes [#22728](https://github.com/ClickHouse/ClickHouse/issues/22728). [#22876](https://github.com/ClickHouse/ClickHouse/pull/22876) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||
* LIVE VIEW (experimental feature): fixed possible hanging in concurrent DROP/CREATE of TEMPORARY LIVE VIEW in `TemporaryLiveViewCleaner`, [see](https://gist.github.com/vzakaznikov/0c03195960fc86b56bfe2bc73a90019e). [#22858](https://github.com/ClickHouse/ClickHouse/pull/22858) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||
* Fixed pushdown of `HAVING` in case, when filter column is used in aggregation. [#22763](https://github.com/ClickHouse/ClickHouse/pull/22763) ([Anton Popov](https://github.com/CurtizJ)).
|
||||
* Fixed possible hangs in Zookeeper requests in case of OOM exception. Fixes [#22438](https://github.com/ClickHouse/ClickHouse/issues/22438). [#22684](https://github.com/ClickHouse/ClickHouse/pull/22684) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||
* Fixed wait for mutations on several replicas for ReplicatedMergeTree table engines. Previously, mutation/alter query may finish before mutation actually executed on other replicas. [#22669](https://github.com/ClickHouse/ClickHouse/pull/22669) ([alesapin](https://github.com/alesapin)).
|
||||
* Fixed exception for Log with nested types without columns in the SELECT clause. [#22654](https://github.com/ClickHouse/ClickHouse/pull/22654) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Fix unlimited wait for auxiliary AWS requests. [#22594](https://github.com/ClickHouse/ClickHouse/pull/22594) ([Vladimir Chebotarev](https://github.com/excitoon)).
|
||||
* Fixed a crash when client closes connection very early [#22579](https://github.com/ClickHouse/ClickHouse/issues/22579). [#22591](https://github.com/ClickHouse/ClickHouse/pull/22591) ([nvartolomei](https://github.com/nvartolomei)).
|
||||
* `Map` data type (experimental feature): fixed an incorrect formatting of function `map` in distributed queries. [#22588](https://github.com/ClickHouse/ClickHouse/pull/22588) ([foolchi](https://github.com/foolchi)).
|
||||
* Fixed deserialization of empty string without newline at end of TSV format. This closes [#20244](https://github.com/ClickHouse/ClickHouse/issues/20244). Possible workaround without version update: set `input_format_null_as_default` to zero. It was zero in old versions. [#22527](https://github.com/ClickHouse/ClickHouse/pull/22527) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Fixed wrong cast of a column of `LowCardinality` type in Merge Join algorithm. Close [#22386](https://github.com/ClickHouse/ClickHouse/issues/22386), close [#22388](https://github.com/ClickHouse/ClickHouse/issues/22388). [#22510](https://github.com/ClickHouse/ClickHouse/pull/22510) ([Vladimir](https://github.com/vdimir)).
|
||||
* Buffer overflow (on read) was possible in `tokenbf_v1` full text index. The excessive bytes are not used but the read operation may lead to crash in rare cases. This closes [#19233](https://github.com/ClickHouse/ClickHouse/issues/19233). [#22421](https://github.com/ClickHouse/ClickHouse/pull/22421) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Do not limit HTTP chunk size. Fixes [#21907](https://github.com/ClickHouse/ClickHouse/issues/21907). [#22322](https://github.com/ClickHouse/ClickHouse/pull/22322) ([Ivan](https://github.com/abyss7)).
|
||||
* Fixed a bug, which leads to underaggregation of data in case of enabled `optimize_aggregation_in_order` and many parts in table. Slightly improve performance of aggregation with enabled `optimize_aggregation_in_order`. [#21889](https://github.com/ClickHouse/ClickHouse/pull/21889) ([Anton Popov](https://github.com/CurtizJ)).
|
||||
* Check if table function view is used as a column. This complements #20350. [#21465](https://github.com/ClickHouse/ClickHouse/pull/21465) ([Amos Bird](https://github.com/amosbird)).
|
||||
* Fix "unknown column" error for tables with `Merge` engine in queris with `JOIN` and aggregation. Closes [#18368](https://github.com/ClickHouse/ClickHouse/issues/18368), close [#22226](https://github.com/ClickHouse/ClickHouse/issues/22226). [#21370](https://github.com/ClickHouse/ClickHouse/pull/21370) ([Vladimir](https://github.com/vdimir)).
|
||||
* Fixed name clashes in pushdown optimization. It caused incorrect `WHERE` filtration after FULL JOIN. Close [#20497](https://github.com/ClickHouse/ClickHouse/issues/20497). [#20622](https://github.com/ClickHouse/ClickHouse/pull/20622) ([Vladimir](https://github.com/vdimir)).
|
||||
* Fixed very rare bug when quorum insert with `quorum_parallel=1` is not really "quorum" because of deduplication. [#18215](https://github.com/ClickHouse/ClickHouse/pull/18215) ([filimonov](https://github.com/filimonov) - reported, [alesapin](https://github.com/alesapin) - fixed).
|
||||
|
||||
#### Build/Testing/Packaging Improvement
|
||||
|
||||
* Run stateless tests in parallel in CI. [#22300](https://github.com/ClickHouse/ClickHouse/pull/22300) ([alesapin](https://github.com/alesapin)).
|
||||
* Simplify debian packages. This fixes [#21698](https://github.com/ClickHouse/ClickHouse/issues/21698). [#22976](https://github.com/ClickHouse/ClickHouse/pull/22976) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Added support for ClickHouse build on Apple M1. [#21639](https://github.com/ClickHouse/ClickHouse/pull/21639) ([changvvb](https://github.com/changvvb)).
|
||||
* Fixed ClickHouse Keeper build for MacOS. [#22860](https://github.com/ClickHouse/ClickHouse/pull/22860) ([alesapin](https://github.com/alesapin)).
|
||||
* Fixed some tests on AArch64 platform. [#22596](https://github.com/ClickHouse/ClickHouse/pull/22596) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Added function alignment for possibly better performance. [#21431](https://github.com/ClickHouse/ClickHouse/pull/21431) ([Danila Kutenin](https://github.com/danlark1)).
|
||||
* Adjust some tests to output identical results on amd64 and aarch64 (qemu). The result was depending on implementation specific CPU behaviour. [#22590](https://github.com/ClickHouse/ClickHouse/pull/22590) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Allow query profiling only on x86_64. See [#15174](https://github.com/ClickHouse/ClickHouse/issues/15174#issuecomment-812954965) and [#15638](https://github.com/ClickHouse/ClickHouse/issues/15638#issuecomment-703805337). This closes [#15638](https://github.com/ClickHouse/ClickHouse/issues/15638). [#22580](https://github.com/ClickHouse/ClickHouse/pull/22580) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||
* Allow building with unbundled xz (lzma) using `USE_INTERNAL_XZ_LIBRARY=OFF` CMake option. [#22571](https://github.com/ClickHouse/ClickHouse/pull/22571) ([Kfir Itzhak](https://github.com/mastertheknife)).
|
||||
* Enable bundled `openldap` on `ppc64le` [#22487](https://github.com/ClickHouse/ClickHouse/pull/22487) ([Kfir Itzhak](https://github.com/mastertheknife)).
|
||||
* Disable incompatible libraries (platform specific typically) on `ppc64le` [#22475](https://github.com/ClickHouse/ClickHouse/pull/22475) ([Kfir Itzhak](https://github.com/mastertheknife)).
|
||||
* Add Jepsen test in CI for clickhouse Keeper. [#22373](https://github.com/ClickHouse/ClickHouse/pull/22373) ([alesapin](https://github.com/alesapin)).
|
||||
* Build `jemalloc` with support for [heap profiling](https://github.com/jemalloc/jemalloc/wiki/Use-Case%3A-Heap-Profiling). [#22834](https://github.com/ClickHouse/ClickHouse/pull/22834) ([nvartolomei](https://github.com/nvartolomei)).
|
||||
* Avoid UB in `*Log` engines for rwlock unlock due to unlock from another thread. [#22583](https://github.com/ClickHouse/ClickHouse/pull/22583) ([Azat Khuzhin](https://github.com/azat)).
|
||||
* Fixed UB by unlocking the rwlock of the TinyLog from the same thread. [#22560](https://github.com/ClickHouse/ClickHouse/pull/22560) ([Azat Khuzhin](https://github.com/azat)).
|
||||
|
||||
|
||||
## ClickHouse release 21.4
|
||||
|
||||
### ClickHouse release 21.4.1 2021-04-12
|
||||
|
@ -36,7 +36,7 @@ option(FAIL_ON_UNSUPPORTED_OPTIONS_COMBINATION
|
||||
if(FAIL_ON_UNSUPPORTED_OPTIONS_COMBINATION)
|
||||
set(RECONFIGURE_MESSAGE_LEVEL FATAL_ERROR)
|
||||
else()
|
||||
set(RECONFIGURE_MESSAGE_LEVEL STATUS)
|
||||
set(RECONFIGURE_MESSAGE_LEVEL WARNING)
|
||||
endif()
|
||||
|
||||
enable_language(C CXX ASM)
|
||||
@ -504,7 +504,6 @@ include (cmake/find/libuv.cmake) # for amqpcpp and cassandra
|
||||
include (cmake/find/amqpcpp.cmake)
|
||||
include (cmake/find/capnp.cmake)
|
||||
include (cmake/find/llvm.cmake)
|
||||
include (cmake/find/termcap.cmake) # for external static llvm
|
||||
include (cmake/find/h3.cmake)
|
||||
include (cmake/find/libxml2.cmake)
|
||||
include (cmake/find/brotli.cmake)
|
||||
@ -527,6 +526,7 @@ include (cmake/find/nanodbc.cmake)
|
||||
include (cmake/find/rocksdb.cmake)
|
||||
include (cmake/find/libpqxx.cmake)
|
||||
include (cmake/find/nuraft.cmake)
|
||||
include (cmake/find/yaml-cpp.cmake)
|
||||
|
||||
|
||||
if(NOT USE_INTERNAL_PARQUET_LIBRARY)
|
||||
|
@ -8,7 +8,7 @@ ClickHouse® is an open-source column-oriented database management system that a
|
||||
* [Tutorial](https://clickhouse.tech/docs/en/getting_started/tutorial/) shows how to set up and query small ClickHouse cluster.
|
||||
* [Documentation](https://clickhouse.tech/docs/en/) provides more in-depth information.
|
||||
* [YouTube channel](https://www.youtube.com/c/ClickHouseDB) has a lot of content about ClickHouse in video format.
|
||||
* [Slack](https://join.slack.com/t/clickhousedb/shared_invite/zt-nwwakmk4-xOJ6cdy0sJC3It8j348~IA) and [Telegram](https://telegram.me/clickhouse_en) allow to chat with ClickHouse users in real-time.
|
||||
* [Slack](https://join.slack.com/t/clickhousedb/shared_invite/zt-qfort0u8-TWqK4wIP0YSdoDE0btKa1w) and [Telegram](https://telegram.me/clickhouse_en) allow to chat with ClickHouse users in real-time.
|
||||
* [Blog](https://clickhouse.yandex/blog/en/) contains various ClickHouse-related articles, as well as announcements and reports about events.
|
||||
* [Code Browser](https://clickhouse.tech/codebrowser/html_report/ClickHouse/index.html) with syntax highlight and navigation.
|
||||
* [Contacts](https://clickhouse.tech/#contacts) can help to get your questions answered if there are any.
|
||||
|
@ -3,5 +3,11 @@ add_library (bridge
|
||||
)
|
||||
|
||||
target_include_directories (daemon PUBLIC ..)
|
||||
target_link_libraries (bridge PRIVATE daemon dbms Poco::Data Poco::Data::ODBC)
|
||||
target_link_libraries (bridge
|
||||
PRIVATE
|
||||
daemon
|
||||
dbms
|
||||
Poco::Data
|
||||
Poco::Data::ODBC
|
||||
)
|
||||
|
||||
|
@ -468,7 +468,7 @@ void BaseDaemon::reloadConfiguration()
|
||||
* instead of using files specified in config.xml.
|
||||
* (It's convenient to log in console when you start server without any command line parameters.)
|
||||
*/
|
||||
config_path = config().getString("config-file", "config.xml");
|
||||
config_path = config().getString("config-file", getDefaultConfigFileName());
|
||||
DB::ConfigProcessor config_processor(config_path, false, true);
|
||||
config_processor.setConfigPath(Poco::Path(config_path).makeParent().toString());
|
||||
loaded_config = config_processor.loadConfig(/* allow_zk_includes = */ true);
|
||||
@ -516,6 +516,11 @@ std::string BaseDaemon::getDefaultCorePath() const
|
||||
return "/opt/cores/";
|
||||
}
|
||||
|
||||
std::string BaseDaemon::getDefaultConfigFileName() const
|
||||
{
|
||||
return "config.xml";
|
||||
}
|
||||
|
||||
void BaseDaemon::closeFDs()
|
||||
{
|
||||
#if defined(OS_FREEBSD) || defined(OS_DARWIN)
|
||||
|
@ -149,6 +149,8 @@ protected:
|
||||
|
||||
virtual std::string getDefaultCorePath() const;
|
||||
|
||||
virtual std::string getDefaultConfigFileName() const;
|
||||
|
||||
std::optional<DB::StatusFile> pid_file;
|
||||
|
||||
std::atomic_bool is_cancelled{false};
|
||||
|
@ -78,6 +78,8 @@ PoolWithFailover::PoolWithFailover(
|
||||
const RemoteDescription & addresses,
|
||||
const std::string & user,
|
||||
const std::string & password,
|
||||
unsigned default_connections_,
|
||||
unsigned max_connections_,
|
||||
size_t max_tries_)
|
||||
: max_tries(max_tries_)
|
||||
, shareable(false)
|
||||
@ -85,7 +87,13 @@ PoolWithFailover::PoolWithFailover(
|
||||
/// Replicas have the same priority, but traversed replicas are moved to the end of the queue.
|
||||
for (const auto & [host, port] : addresses)
|
||||
{
|
||||
replicas_by_priority[0].emplace_back(std::make_shared<Pool>(database, host, user, password, port));
|
||||
replicas_by_priority[0].emplace_back(std::make_shared<Pool>(database,
|
||||
host, user, password, port,
|
||||
/* socket_ = */ "",
|
||||
MYSQLXX_DEFAULT_TIMEOUT,
|
||||
MYSQLXX_DEFAULT_RW_TIMEOUT,
|
||||
default_connections_,
|
||||
max_connections_));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,8 @@ namespace mysqlxx
|
||||
const RemoteDescription & addresses,
|
||||
const std::string & user,
|
||||
const std::string & password,
|
||||
unsigned default_connections_ = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS,
|
||||
unsigned max_connections_ = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_CONNECTIONS,
|
||||
size_t max_tries_ = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES);
|
||||
|
||||
PoolWithFailover(const PoolWithFailover & other);
|
||||
|
@ -1,9 +1,9 @@
|
||||
# This strings autochanged from release_lib.sh:
|
||||
SET(VERSION_REVISION 54451)
|
||||
SET(VERSION_REVISION 54452)
|
||||
SET(VERSION_MAJOR 21)
|
||||
SET(VERSION_MINOR 6)
|
||||
SET(VERSION_MINOR 7)
|
||||
SET(VERSION_PATCH 1)
|
||||
SET(VERSION_GITHASH 96fced4c3cf432fb0b401d2ab01f0c56e5f74a96)
|
||||
SET(VERSION_DESCRIBE v21.6.1.1-prestable)
|
||||
SET(VERSION_STRING 21.6.1.1)
|
||||
SET(VERSION_GITHASH 976ccc2e908ac3bc28f763bfea8134ea0a121b40)
|
||||
SET(VERSION_DESCRIBE v21.7.1.1-prestable)
|
||||
SET(VERSION_STRING 21.7.1.1)
|
||||
# end of autochange
|
||||
|
@ -1,102 +1,34 @@
|
||||
if (APPLE OR SPLIT_SHARED_LIBRARIES OR NOT ARCH_AMD64)
|
||||
if (APPLE OR SPLIT_SHARED_LIBRARIES OR NOT ARCH_AMD64 OR SANITIZE STREQUAL "undefined")
|
||||
set (ENABLE_EMBEDDED_COMPILER OFF CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
option (ENABLE_EMBEDDED_COMPILER "Enable support for 'compile_expressions' option for query execution" ON)
|
||||
# Broken in macos. TODO: update clang, re-test, enable on Apple
|
||||
if (ENABLE_EMBEDDED_COMPILER AND NOT SPLIT_SHARED_LIBRARIES AND ARCH_AMD64 AND NOT (SANITIZE STREQUAL "undefined"))
|
||||
option (USE_INTERNAL_LLVM_LIBRARY "Use bundled or system LLVM library." ${NOT_UNBUNDLED})
|
||||
endif()
|
||||
|
||||
if (NOT ENABLE_EMBEDDED_COMPILER)
|
||||
if(USE_INTERNAL_LLVM_LIBRARY)
|
||||
message (${RECONFIGURE_MESSAGE_LEVEL} "Cannot use internal LLVM library with ENABLE_EMBEDDED_COMPILER=OFF")
|
||||
endif()
|
||||
set (USE_EMBEDDED_COMPILER 0)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/llvm/llvm/CMakeLists.txt")
|
||||
if (USE_INTERNAL_LLVM_LIBRARY)
|
||||
message (WARNING "submodule contrib/llvm is missing. to fix try run: \n git submodule update --init --recursive")
|
||||
message (${RECONFIGURE_MESSAGE_LEVEL} "Can't fidd internal LLVM library")
|
||||
endif()
|
||||
set (MISSING_INTERNAL_LLVM_LIBRARY 1)
|
||||
message (${RECONFIGURE_MESSAGE_LEVEL} "submodule /contrib/llvm is missing. to fix try run: \n git submodule update --init --recursive")
|
||||
endif ()
|
||||
|
||||
if (NOT USE_INTERNAL_LLVM_LIBRARY)
|
||||
set (LLVM_PATHS "/usr/local/lib/llvm" "/usr/lib/llvm")
|
||||
set (USE_EMBEDDED_COMPILER 1)
|
||||
|
||||
foreach(llvm_v 11.1 11)
|
||||
if (NOT LLVM_FOUND)
|
||||
find_package (LLVM ${llvm_v} CONFIG PATHS ${LLVM_PATHS})
|
||||
endif ()
|
||||
endforeach ()
|
||||
set (LLVM_FOUND 1)
|
||||
set (LLVM_VERSION "12.0.0bundled")
|
||||
set (LLVM_INCLUDE_DIRS
|
||||
"${ClickHouse_SOURCE_DIR}/contrib/llvm/llvm/include"
|
||||
"${ClickHouse_BINARY_DIR}/contrib/llvm/llvm/include"
|
||||
)
|
||||
set (LLVM_LIBRARY_DIRS "${ClickHouse_BINARY_DIR}/contrib/llvm/llvm")
|
||||
|
||||
if (LLVM_FOUND)
|
||||
# Remove dynamically-linked zlib and libedit from LLVM's dependencies:
|
||||
set_target_properties(LLVMSupport PROPERTIES INTERFACE_LINK_LIBRARIES "-lpthread;LLVMDemangle;${ZLIB_LIBRARIES}")
|
||||
set_target_properties(LLVMLineEditor PROPERTIES INTERFACE_LINK_LIBRARIES "LLVMSupport")
|
||||
|
||||
option(LLVM_HAS_RTTI "Enable if LLVM was build with RTTI enabled" ON)
|
||||
set (USE_EMBEDDED_COMPILER 1)
|
||||
else()
|
||||
message (${RECONFIGURE_MESSAGE_LEVEL} "Can't find system LLVM")
|
||||
set (USE_EMBEDDED_COMPILER 0)
|
||||
endif()
|
||||
|
||||
if (LLVM_FOUND AND OS_LINUX AND USE_LIBCXX AND NOT FORCE_LLVM_WITH_LIBCXX)
|
||||
message(WARNING "Option USE_INTERNAL_LLVM_LIBRARY is not set but the LLVM library from OS packages "
|
||||
"in Linux is incompatible with libc++ ABI. LLVM Will be disabled. Force: -DFORCE_LLVM_WITH_LIBCXX=ON")
|
||||
message (${RECONFIGURE_MESSAGE_LEVEL} "Unsupported LLVM configuration, cannot enable LLVM")
|
||||
set (LLVM_FOUND 0)
|
||||
set (USE_EMBEDDED_COMPILER 0)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if(NOT LLVM_FOUND AND NOT MISSING_INTERNAL_LLVM_LIBRARY)
|
||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||
message(WARNING "Option ENABLE_EMBEDDED_COMPILER is set but internal LLVM library cannot build if build directory is the same as source directory.")
|
||||
set (LLVM_FOUND 0)
|
||||
set (USE_EMBEDDED_COMPILER 0)
|
||||
elseif (SPLIT_SHARED_LIBRARIES)
|
||||
# llvm-tablegen cannot find shared libraries that we build. Probably can be easily fixed.
|
||||
message(WARNING "Option USE_INTERNAL_LLVM_LIBRARY is not compatible with SPLIT_SHARED_LIBRARIES. Build of LLVM will be disabled.")
|
||||
set (LLVM_FOUND 0)
|
||||
set (USE_EMBEDDED_COMPILER 0)
|
||||
elseif (NOT ARCH_AMD64)
|
||||
# It's not supported yet, but you can help.
|
||||
message(WARNING "Option USE_INTERNAL_LLVM_LIBRARY is only available for x86_64. Build of LLVM will be disabled.")
|
||||
set (LLVM_FOUND 0)
|
||||
set (USE_EMBEDDED_COMPILER 0)
|
||||
elseif (SANITIZE STREQUAL "undefined")
|
||||
# llvm-tblgen, that is used during LLVM build, doesn't work with UBSan.
|
||||
message(WARNING "Option USE_INTERNAL_LLVM_LIBRARY does not work with UBSan, because 'llvm-tblgen' tool from LLVM has undefined behaviour. Build of LLVM will be disabled.")
|
||||
set (LLVM_FOUND 0)
|
||||
set (USE_EMBEDDED_COMPILER 0)
|
||||
else ()
|
||||
set (USE_INTERNAL_LLVM_LIBRARY ON)
|
||||
set (LLVM_FOUND 1)
|
||||
set (USE_EMBEDDED_COMPILER 1)
|
||||
set (LLVM_VERSION "9.0.0bundled")
|
||||
set (LLVM_INCLUDE_DIRS
|
||||
"${ClickHouse_SOURCE_DIR}/contrib/llvm/llvm/include"
|
||||
"${ClickHouse_BINARY_DIR}/contrib/llvm/llvm/include"
|
||||
)
|
||||
set (LLVM_LIBRARY_DIRS "${ClickHouse_BINARY_DIR}/contrib/llvm/llvm")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (LLVM_FOUND)
|
||||
message(STATUS "LLVM include Directory: ${LLVM_INCLUDE_DIRS}")
|
||||
message(STATUS "LLVM library Directory: ${LLVM_LIBRARY_DIRS}")
|
||||
message(STATUS "LLVM C++ compiler flags: ${LLVM_CXXFLAGS}")
|
||||
else()
|
||||
message (${RECONFIGURE_MESSAGE_LEVEL} "Can't enable LLVM")
|
||||
endif()
|
||||
message(STATUS "LLVM include Directory: ${LLVM_INCLUDE_DIRS}")
|
||||
message(STATUS "LLVM library Directory: ${LLVM_LIBRARY_DIRS}")
|
||||
message(STATUS "LLVM C++ compiler flags: ${LLVM_CXXFLAGS}")
|
||||
|
||||
# This list was generated by listing all LLVM libraries, compiling the binary and removing all libraries while it still compiles.
|
||||
set (REQUIRED_LLVM_LIBRARIES
|
||||
LLVMOrcJIT
|
||||
LLVMExecutionEngine
|
||||
LLVMRuntimeDyld
|
||||
LLVMX86CodeGen
|
||||
|
@ -1,17 +0,0 @@
|
||||
if (ENABLE_EMBEDDED_COMPILER AND NOT USE_INTERNAL_LLVM_LIBRARY AND USE_STATIC_LIBRARIES)
|
||||
find_library (TERMCAP_LIBRARY tinfo)
|
||||
if (NOT TERMCAP_LIBRARY)
|
||||
find_library (TERMCAP_LIBRARY ncurses)
|
||||
endif()
|
||||
if (NOT TERMCAP_LIBRARY)
|
||||
find_library (TERMCAP_LIBRARY termcap)
|
||||
endif()
|
||||
|
||||
if (NOT TERMCAP_LIBRARY)
|
||||
message (FATAL_ERROR "Statically Linking external LLVM requires termcap")
|
||||
endif()
|
||||
|
||||
target_link_libraries(LLVMSupport INTERFACE ${TERMCAP_LIBRARY})
|
||||
|
||||
message (STATUS "Using termcap: ${TERMCAP_LIBRARY}")
|
||||
endif()
|
9
cmake/find/yaml-cpp.cmake
Normal file
9
cmake/find/yaml-cpp.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
option(USE_YAML_CPP "Enable yaml-cpp" ${ENABLE_LIBRARIES})
|
||||
|
||||
if (NOT USE_YAML_CPP)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/yaml-cpp")
|
||||
message (ERROR "submodule contrib/yaml-cpp is missing. to fix try run: \n git submodule update --init --recursive")
|
||||
endif()
|
9
contrib/CMakeLists.txt
vendored
9
contrib/CMakeLists.txt
vendored
@ -50,6 +50,10 @@ add_subdirectory (replxx-cmake)
|
||||
add_subdirectory (unixodbc-cmake)
|
||||
add_subdirectory (nanodbc-cmake)
|
||||
|
||||
if (USE_YAML_CPP)
|
||||
add_subdirectory (yaml-cpp-cmake)
|
||||
endif()
|
||||
|
||||
if (USE_INTERNAL_XZ_LIBRARY)
|
||||
add_subdirectory (xz)
|
||||
endif()
|
||||
@ -205,11 +209,12 @@ elseif(GTEST_SRC_DIR)
|
||||
target_compile_definitions(gtest INTERFACE GTEST_HAS_POSIX_RE=0)
|
||||
endif()
|
||||
|
||||
if (USE_EMBEDDED_COMPILER AND USE_INTERNAL_LLVM_LIBRARY)
|
||||
if (USE_EMBEDDED_COMPILER)
|
||||
# ld: unknown option: --color-diagnostics
|
||||
if (APPLE)
|
||||
set (LINKER_SUPPORTS_COLOR_DIAGNOSTICS 0 CACHE INTERNAL "")
|
||||
endif ()
|
||||
|
||||
set (LLVM_ENABLE_EH 1 CACHE INTERNAL "")
|
||||
set (LLVM_ENABLE_RTTI 1 CACHE INTERNAL "")
|
||||
set (LLVM_ENABLE_PIC 0 CACHE INTERNAL "")
|
||||
@ -224,8 +229,6 @@ if (USE_EMBEDDED_COMPILER AND USE_INTERNAL_LLVM_LIBRARY)
|
||||
|
||||
set (CMAKE_CXX_STANDARD ${CMAKE_CXX_STANDARD_bak})
|
||||
unset (CMAKE_CXX_STANDARD_bak)
|
||||
|
||||
target_include_directories(LLVMSupport SYSTEM BEFORE PRIVATE ${ZLIB_INCLUDE_DIR})
|
||||
endif ()
|
||||
|
||||
if (USE_INTERNAL_LIBGSASL_LIBRARY)
|
||||
|
2
contrib/boringssl
vendored
2
contrib/boringssl
vendored
@ -1 +1 @@
|
||||
Subproject commit 83c1cda8a0224dc817cbad2966c7ed4acc35f02a
|
||||
Subproject commit a6a2e2ab3e44d97ce98e51c558e989f211de7eb3
|
2
contrib/cppkafka
vendored
2
contrib/cppkafka
vendored
@ -1 +1 @@
|
||||
Subproject commit b06e64ef5bffd636d918a742c689f69130c1dbab
|
||||
Subproject commit 57a599d99c540e647bcd0eb9ea77c523cca011b3
|
2
contrib/grpc
vendored
2
contrib/grpc
vendored
@ -1 +1 @@
|
||||
Subproject commit 1085a941238e66b13e3fb89c310533745380acbc
|
||||
Subproject commit 60c986e15cae70aade721d26badabab1f822fdd6
|
2
contrib/libunwind
vendored
2
contrib/libunwind
vendored
@ -1 +1 @@
|
||||
Subproject commit 8fe25d7dc70f2a4ea38c3e5a33fa9d4199b67a5a
|
||||
Subproject commit a491c27b33109a842d577c0f7ac5f5f218859181
|
2
contrib/llvm
vendored
2
contrib/llvm
vendored
@ -1 +1 @@
|
||||
Subproject commit cfaf365cf96918999d09d976ec736b4518cf5d02
|
||||
Subproject commit e5751459412bce1391fb7a2e9bbc01e131bf72f1
|
2
contrib/poco
vendored
2
contrib/poco
vendored
@ -1 +1 @@
|
||||
Subproject commit b7d9ec16ee33ca76643d5fcd907ea9a33285640a
|
||||
Subproject commit 5994506908028612869fee627d68d8212dfe7c1e
|
2
contrib/re2
vendored
2
contrib/re2
vendored
@ -1 +1 @@
|
||||
Subproject commit 7cf8b88e8f70f97fd4926b56aa87e7f53b2717e0
|
||||
Subproject commit 13ebb377c6ad763ca61d12dd6f88b1126bd0b911
|
@ -1,7 +1,7 @@
|
||||
file (READ ${SOURCE_FILENAME} CONTENT)
|
||||
string (REGEX REPLACE "using re2::RE2;" "" CONTENT "${CONTENT}")
|
||||
string (REGEX REPLACE "using re2::LazyRE2;" "" CONTENT "${CONTENT}")
|
||||
string (REGEX REPLACE "namespace re2" "namespace re2_st" CONTENT "${CONTENT}")
|
||||
string (REGEX REPLACE "namespace re2 {" "namespace re2_st {" CONTENT "${CONTENT}")
|
||||
string (REGEX REPLACE "re2::" "re2_st::" CONTENT "${CONTENT}")
|
||||
string (REGEX REPLACE "\"re2/" "\"re2_st/" CONTENT "${CONTENT}")
|
||||
string (REGEX REPLACE "(.\\*?_H)" "\\1_ST" CONTENT "${CONTENT}")
|
||||
|
2
contrib/rocksdb
vendored
2
contrib/rocksdb
vendored
@ -1 +1 @@
|
||||
Subproject commit 54a0decabbcf4c0bb5cf7befa9c597f28289bff5
|
||||
Subproject commit 07c77549a20b63ff6981b400085eba36bb5c80c4
|
2
contrib/simdjson
vendored
2
contrib/simdjson
vendored
@ -1 +1 @@
|
||||
Subproject commit 95b4870e20be5f97d9dcf63b23b1c6f520c366c1
|
||||
Subproject commit 8df32cea3359cb30120795da6020b3b73da01d38
|
1
contrib/yaml-cpp
vendored
Submodule
1
contrib/yaml-cpp
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 0c86adac6d117ee2b4afcedb8ade19036ca0327d
|
39
contrib/yaml-cpp-cmake/CMakeLists.txt
Normal file
39
contrib/yaml-cpp-cmake/CMakeLists.txt
Normal file
@ -0,0 +1,39 @@
|
||||
set (LIBRARY_DIR ${ClickHouse_SOURCE_DIR}/contrib/yaml-cpp)
|
||||
|
||||
set (SRCS
|
||||
${LIBRARY_DIR}/src/binary.cpp
|
||||
${LIBRARY_DIR}/src/emitterutils.cpp
|
||||
${LIBRARY_DIR}/src/null.cpp
|
||||
${LIBRARY_DIR}/src/scantoken.cpp
|
||||
${LIBRARY_DIR}/src/convert.cpp
|
||||
${LIBRARY_DIR}/src/exceptions.cpp
|
||||
${LIBRARY_DIR}/src/ostream_wrapper.cpp
|
||||
${LIBRARY_DIR}/src/simplekey.cpp
|
||||
${LIBRARY_DIR}/src/depthguard.cpp
|
||||
${LIBRARY_DIR}/src/exp.cpp
|
||||
${LIBRARY_DIR}/src/parse.cpp
|
||||
${LIBRARY_DIR}/src/singledocparser.cpp
|
||||
${LIBRARY_DIR}/src/directives.cpp
|
||||
${LIBRARY_DIR}/src/memory.cpp
|
||||
${LIBRARY_DIR}/src/parser.cpp
|
||||
${LIBRARY_DIR}/src/stream.cpp
|
||||
${LIBRARY_DIR}/src/emit.cpp
|
||||
${LIBRARY_DIR}/src/nodebuilder.cpp
|
||||
${LIBRARY_DIR}/src/regex_yaml.cpp
|
||||
${LIBRARY_DIR}/src/tag.cpp
|
||||
${LIBRARY_DIR}/src/emitfromevents.cpp
|
||||
${LIBRARY_DIR}/src/node.cpp
|
||||
${LIBRARY_DIR}/src/scanner.cpp
|
||||
${LIBRARY_DIR}/src/emitter.cpp
|
||||
${LIBRARY_DIR}/src/node_data.cpp
|
||||
${LIBRARY_DIR}/src/scanscalar.cpp
|
||||
${LIBRARY_DIR}/src/emitterstate.cpp
|
||||
${LIBRARY_DIR}/src/nodeevents.cpp
|
||||
${LIBRARY_DIR}/src/scantag.cpp
|
||||
)
|
||||
|
||||
add_library (yaml-cpp ${SRCS})
|
||||
|
||||
|
||||
target_include_directories(yaml-cpp PRIVATE ${LIBRARY_DIR}/include/yaml-cpp)
|
||||
target_include_directories(yaml-cpp SYSTEM BEFORE PUBLIC ${LIBRARY_DIR}/include)
|
2
contrib/zlib-ng
vendored
2
contrib/zlib-ng
vendored
@ -1 +1 @@
|
||||
Subproject commit 5cc4d232020dc66d1d6c5438834457e2a2f6127b
|
||||
Subproject commit db232d30b4c72fd58e6d7eae2d12cebf9c3d90db
|
2
contrib/zstd
vendored
2
contrib/zstd
vendored
@ -1 +1 @@
|
||||
Subproject commit 10f0e6993f9d2f682da6d04aa2385b7d53cbb4ee
|
||||
Subproject commit a488ba114ec17ea1054b9057c26a046fc122b3b6
|
@ -66,6 +66,7 @@ SET(Sources
|
||||
"${LIBRARY_DIR}/compress/zstd_compress.c"
|
||||
"${LIBRARY_DIR}/compress/zstd_compress_literals.c"
|
||||
"${LIBRARY_DIR}/compress/zstd_compress_sequences.c"
|
||||
"${LIBRARY_DIR}/compress/zstd_compress_superblock.c"
|
||||
"${LIBRARY_DIR}/compress/zstd_double_fast.c"
|
||||
"${LIBRARY_DIR}/compress/zstd_fast.c"
|
||||
"${LIBRARY_DIR}/compress/zstd_lazy.c"
|
||||
@ -95,16 +96,19 @@ SET(Headers
|
||||
"${LIBRARY_DIR}/common/pool.h"
|
||||
"${LIBRARY_DIR}/common/threading.h"
|
||||
"${LIBRARY_DIR}/common/xxhash.h"
|
||||
"${LIBRARY_DIR}/common/zstd_errors.h"
|
||||
"${LIBRARY_DIR}/common/zstd_deps.h"
|
||||
"${LIBRARY_DIR}/common/zstd_internal.h"
|
||||
"${LIBRARY_DIR}/common/zstd_trace.h"
|
||||
"${LIBRARY_DIR}/compress/hist.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_compress_internal.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_compress_literals.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_compress_sequences.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_compress_superblock.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_cwksp.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_double_fast.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_fast.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_lazy.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_ldm_geartab.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_ldm.h"
|
||||
"${LIBRARY_DIR}/compress/zstdmt_compress.h"
|
||||
"${LIBRARY_DIR}/compress/zstd_opt.h"
|
||||
@ -113,7 +117,8 @@ SET(Headers
|
||||
"${LIBRARY_DIR}/decompress/zstd_decompress_internal.h"
|
||||
"${LIBRARY_DIR}/dictBuilder/cover.h"
|
||||
"${LIBRARY_DIR}/dictBuilder/divsufsort.h"
|
||||
"${LIBRARY_DIR}/dictBuilder/zdict.h"
|
||||
"${LIBRARY_DIR}/zdict.h"
|
||||
"${LIBRARY_DIR}/zstd_errors.h"
|
||||
"${LIBRARY_DIR}/zstd.h")
|
||||
|
||||
SET(ZSTD_LEGACY_SUPPORT true)
|
||||
|
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -1,5 +1,5 @@
|
||||
clickhouse (21.6.1.1) unstable; urgency=low
|
||||
clickhouse (21.7.1.1) unstable; urgency=low
|
||||
|
||||
* Modified source code
|
||||
|
||||
-- clickhouse-release <clickhouse-release@yandex-team.ru> Tue, 20 Apr 2021 01:48:16 +0300
|
||||
-- clickhouse-release <clickhouse-release@yandex-team.ru> Thu, 20 May 2021 22:23:29 +0300
|
||||
|
@ -1,7 +1,7 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
||||
ARG version=21.6.1.*
|
||||
ARG version=21.7.1.*
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --yes --no-install-recommends \
|
||||
|
@ -1,7 +1,7 @@
|
||||
FROM ubuntu:20.04
|
||||
|
||||
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
||||
ARG version=21.6.1.*
|
||||
ARG version=21.7.1.*
|
||||
ARG gosu_ver=1.10
|
||||
|
||||
# set non-empty deb_location_url url to create a docker image
|
||||
|
@ -1,7 +1,7 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
||||
ARG version=21.6.1.*
|
||||
ARG version=21.7.1.*
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y apt-transport-https dirmngr && \
|
||||
|
@ -73,7 +73,7 @@ function start_server
|
||||
--path "$FASTTEST_DATA"
|
||||
--user_files_path "$FASTTEST_DATA/user_files"
|
||||
--top_level_domains_path "$FASTTEST_DATA/top_level_domains"
|
||||
--keeper_server.log_storage_path "$FASTTEST_DATA/coordination"
|
||||
--keeper_server.storage_path "$FASTTEST_DATA/coordination"
|
||||
)
|
||||
clickhouse-server "${opts[@]}" &>> "$FASTTEST_OUTPUT/server.log" &
|
||||
server_pid=$!
|
||||
@ -376,35 +376,14 @@ function run_tests
|
||||
# Depends on LLVM JIT
|
||||
01852_jit_if
|
||||
01865_jit_comparison_constant_result
|
||||
01871_merge_tree_compile_expressions
|
||||
)
|
||||
|
||||
(time clickhouse-test --hung-check -j 8 --order=random --use-skip-list --no-long --testname --shard --zookeeper --skip "${TESTS_TO_SKIP[@]}" -- "$FASTTEST_FOCUS" 2>&1 ||:) | ts '%Y-%m-%d %H:%M:%S' | tee "$FASTTEST_OUTPUT/test_log.txt"
|
||||
|
||||
# substr is to remove semicolon after test name
|
||||
readarray -t FAILED_TESTS < <(awk '/\[ FAIL|TIMEOUT|ERROR \]/ { print substr($3, 1, length($3)-1) }' "$FASTTEST_OUTPUT/test_log.txt" | tee "$FASTTEST_OUTPUT/failed-parallel-tests.txt")
|
||||
|
||||
# We will rerun sequentially any tests that have failed during parallel run.
|
||||
# They might have failed because there was some interference from other tests
|
||||
# running concurrently. If they fail even in seqential mode, we will report them.
|
||||
# FIXME All tests that require exclusive access to the server must be
|
||||
# explicitly marked as `sequential`, and `clickhouse-test` must detect them and
|
||||
# run them in a separate group after all other tests. This is faster and also
|
||||
# explicit instead of guessing.
|
||||
if [[ -n "${FAILED_TESTS[*]}" ]]
|
||||
then
|
||||
stop_server ||:
|
||||
|
||||
# Clean the data so that there is no interference from the previous test run.
|
||||
rm -rf "$FASTTEST_DATA"/{{meta,}data,user_files,coordination} ||:
|
||||
|
||||
start_server
|
||||
|
||||
echo "Going to run again: ${FAILED_TESTS[*]}"
|
||||
|
||||
clickhouse-test --hung-check --order=random --no-long --testname --shard --zookeeper "${FAILED_TESTS[@]}" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee -a "$FASTTEST_OUTPUT/test_log.txt"
|
||||
else
|
||||
echo "No failed tests"
|
||||
fi
|
||||
time clickhouse-test --hung-check -j 8 --order=random --use-skip-list \
|
||||
--no-long --testname --shard --zookeeper --skip "${TESTS_TO_SKIP[@]}" \
|
||||
-- "$FASTTEST_FOCUS" 2>&1 \
|
||||
| ts '%Y-%m-%d %H:%M:%S' \
|
||||
| tee "$FASTTEST_OUTPUT/test_log.txt"
|
||||
}
|
||||
|
||||
case "$stage" in
|
||||
|
@ -0,0 +1,92 @@
|
||||
version: '2.3'
|
||||
services:
|
||||
zoo1:
|
||||
image: ${image:-yandex/clickhouse-integration-test}
|
||||
restart: always
|
||||
user: ${user:-}
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ${keeper_binary:-}
|
||||
target: /usr/bin/clickhouse
|
||||
- type: bind
|
||||
source: ${keeper_config_dir1:-}
|
||||
target: /etc/clickhouse-keeper
|
||||
- type: bind
|
||||
source: ${keeper_logs_dir1:-}
|
||||
target: /var/log/clickhouse-keeper
|
||||
- type: ${keeper_fs:-tmpfs}
|
||||
source: ${keeper_db_dir1:-}
|
||||
target: /var/lib/clickhouse-keeper
|
||||
entrypoint: "clickhouse keeper --config=/etc/clickhouse-keeper/keeper_config1.xml --log-file=/var/log/clickhouse-keeper/clickhouse-keeper.log --errorlog-file=/var/log/clickhouse-keeper/clickhouse-keeper.err.log"
|
||||
cap_add:
|
||||
- SYS_PTRACE
|
||||
- NET_ADMIN
|
||||
- IPC_LOCK
|
||||
- SYS_NICE
|
||||
security_opt:
|
||||
- label:disable
|
||||
dns_opt:
|
||||
- attempts:2
|
||||
- timeout:1
|
||||
- inet6
|
||||
- rotate
|
||||
zoo2:
|
||||
image: ${image:-yandex/clickhouse-integration-test}
|
||||
restart: always
|
||||
user: ${user:-}
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ${keeper_binary:-}
|
||||
target: /usr/bin/clickhouse
|
||||
- type: bind
|
||||
source: ${keeper_config_dir2:-}
|
||||
target: /etc/clickhouse-keeper
|
||||
- type: bind
|
||||
source: ${keeper_logs_dir2:-}
|
||||
target: /var/log/clickhouse-keeper
|
||||
- type: ${keeper_fs:-tmpfs}
|
||||
source: ${keeper_db_dir2:-}
|
||||
target: /var/lib/clickhouse-keeper
|
||||
entrypoint: "clickhouse keeper --config=/etc/clickhouse-keeper/keeper_config2.xml --log-file=/var/log/clickhouse-keeper/clickhouse-keeper.log --errorlog-file=/var/log/clickhouse-keeper/clickhouse-keeper.err.log"
|
||||
cap_add:
|
||||
- SYS_PTRACE
|
||||
- NET_ADMIN
|
||||
- IPC_LOCK
|
||||
- SYS_NICE
|
||||
security_opt:
|
||||
- label:disable
|
||||
dns_opt:
|
||||
- attempts:2
|
||||
- timeout:1
|
||||
- inet6
|
||||
- rotate
|
||||
zoo3:
|
||||
image: ${image:-yandex/clickhouse-integration-test}
|
||||
restart: always
|
||||
user: ${user:-}
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ${keeper_binary:-}
|
||||
target: /usr/bin/clickhouse
|
||||
- type: bind
|
||||
source: ${keeper_config_dir3:-}
|
||||
target: /etc/clickhouse-keeper
|
||||
- type: bind
|
||||
source: ${keeper_logs_dir3:-}
|
||||
target: /var/log/clickhouse-keeper
|
||||
- type: ${keeper_fs:-tmpfs}
|
||||
source: ${keeper_db_dir3:-}
|
||||
target: /var/lib/clickhouse-keeper
|
||||
entrypoint: "clickhouse keeper --config=/etc/clickhouse-keeper/keeper_config3.xml --log-file=/var/log/clickhouse-keeper/clickhouse-keeper.log --errorlog-file=/var/log/clickhouse-keeper/clickhouse-keeper.err.log"
|
||||
cap_add:
|
||||
- SYS_PTRACE
|
||||
- NET_ADMIN
|
||||
- IPC_LOCK
|
||||
- SYS_NICE
|
||||
security_opt:
|
||||
- label:disable
|
||||
dns_opt:
|
||||
- attempts:2
|
||||
- timeout:1
|
||||
- inet6
|
||||
- rotate
|
@ -44,7 +44,7 @@ parser.add_argument('--port', nargs='*', default=[9000], help="Space-separated l
|
||||
parser.add_argument('--runs', type=int, default=1, help='Number of query runs per server.')
|
||||
parser.add_argument('--max-queries', type=int, default=None, help='Test no more than this number of queries, chosen at random.')
|
||||
parser.add_argument('--queries-to-run', nargs='*', type=int, default=None, help='Space-separated list of indexes of queries to test.')
|
||||
parser.add_argument('--max-query-seconds', type=int, default=10, help='For how many seconds at most a query is allowed to run. The script finishes with error if this time is exceeded.')
|
||||
parser.add_argument('--max-query-seconds', type=int, default=15, help='For how many seconds at most a query is allowed to run. The script finishes with error if this time is exceeded.')
|
||||
parser.add_argument('--profile-seconds', type=int, default=0, help='For how many seconds to profile a query for which the performance has changed.')
|
||||
parser.add_argument('--long', action='store_true', help='Do not skip the tests tagged as long.')
|
||||
parser.add_argument('--print-queries', action='store_true', help='Print test queries and exit.')
|
||||
@ -273,8 +273,14 @@ for query_index in queries_to_run:
|
||||
prewarm_id = f'{query_prefix}.prewarm0'
|
||||
|
||||
try:
|
||||
# Will also detect too long queries during warmup stage
|
||||
res = c.execute(q, query_id = prewarm_id, settings = {'max_execution_time': args.max_query_seconds})
|
||||
# During the warmup runs, we will also:
|
||||
# * detect queries that are exceedingly long, to fail fast,
|
||||
# * collect profiler traces, which might be helpful for analyzing
|
||||
# test coverage. We disable profiler for normal runs because
|
||||
# it makes the results unstable.
|
||||
res = c.execute(q, query_id = prewarm_id,
|
||||
settings = {'max_execution_time': args.max_query_seconds,
|
||||
'query_profiler_real_time_period_ns': 10000000})
|
||||
except clickhouse_driver.errors.Error as e:
|
||||
# Add query id to the exception to make debugging easier.
|
||||
e.args = (prewarm_id, *e.args)
|
||||
@ -359,10 +365,11 @@ for query_index in queries_to_run:
|
||||
# For very short queries we have a special mode where we run them for at
|
||||
# least some time. The recommended lower bound of run time for "normal"
|
||||
# queries is about 0.1 s, and we run them about 10 times, giving the
|
||||
# time per query per server of about one second. Use this value as a
|
||||
# reference for "short" queries.
|
||||
# time per query per server of about one second. Run "short" queries
|
||||
# for longer time, because they have a high percentage of overhead and
|
||||
# might give less stable results.
|
||||
if is_short[query_index]:
|
||||
if server_seconds >= 2 * len(this_query_connections):
|
||||
if server_seconds >= 8 * len(this_query_connections):
|
||||
break
|
||||
# Also limit the number of runs, so that we don't go crazy processing
|
||||
# the results -- 'eqmed.sql' is really suboptimal.
|
||||
|
@ -446,6 +446,9 @@ if args.report == 'main':
|
||||
attrs[3] = f'style="background: {color_bad}"'
|
||||
else:
|
||||
attrs[3] = ''
|
||||
# Just don't add the slightly unstable queries we don't consider
|
||||
# errors. It's not clear what the user should do with them.
|
||||
continue
|
||||
|
||||
text += tableRow(r, attrs, anchor)
|
||||
|
||||
@ -553,12 +556,11 @@ if args.report == 'main':
|
||||
error_tests += unstable_partial_queries
|
||||
status = 'failure'
|
||||
|
||||
if unstable_queries:
|
||||
message_array.append(str(unstable_queries) + ' unstable')
|
||||
|
||||
# Disabled before fix.
|
||||
# if very_unstable_queries:
|
||||
# status = 'failure'
|
||||
# Don't show mildly unstable queries, only the very unstable ones we
|
||||
# treat as errors.
|
||||
if very_unstable_queries:
|
||||
status = 'failure'
|
||||
message_array.append(str(very_unstable_queries) + ' unstable')
|
||||
|
||||
error_tests += slow_average_tests
|
||||
if error_tests:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# How to add test queries to ClickHouse CI
|
||||
|
||||
ClickHouse has hundreds (or even thousands) of features. Every commit get checked by a complex set of tests containing many thousands of test cases.
|
||||
ClickHouse has hundreds (or even thousands) of features. Every commit gets checked by a complex set of tests containing many thousands of test cases.
|
||||
|
||||
The core functionality is very well tested, but some corner-cases and different combinations of features can be uncovered with ClickHouse CI.
|
||||
|
||||
@ -105,13 +105,13 @@ clickhouse-client -nmT < tests/queries/0_stateless/01521_dummy_test.sql | tee te
|
||||
|
||||
5) ensure everything is correct, if the test output is incorrect (due to some bug for example), adjust the reference file using text editor.
|
||||
|
||||
#### How create good test
|
||||
#### How to create good test
|
||||
|
||||
- test should be
|
||||
- minimal - create only tables related to tested functionality, remove unrelated columns and parts of query
|
||||
- fast - should not take longer than few seconds (better subseconds)
|
||||
- correct - fails then feature is not working
|
||||
- deteministic
|
||||
- deterministic
|
||||
- isolated / stateless
|
||||
- don't rely on some environment things
|
||||
- don't rely on timing when possible
|
||||
@ -124,7 +124,7 @@ clickhouse-client -nmT < tests/queries/0_stateless/01521_dummy_test.sql | tee te
|
||||
- clean up the created objects after test and before the test (DROP IF EXISTS) - in case of some dirty state
|
||||
- prefer sync mode of operations (mutations, merges, etc.)
|
||||
- use other SQL files in the `0_stateless` folder as an example
|
||||
- ensure the feature / feature combination you want to tests is not covered yet with existsing tests
|
||||
- ensure the feature / feature combination you want to tests is not covered yet with existing tests
|
||||
|
||||
#### Commit / push / create PR.
|
||||
|
||||
|
@ -15,7 +15,12 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
|
||||
...
|
||||
) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause']);
|
||||
) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause'])
|
||||
SETTINGS
|
||||
[connection_pool_size=16, ]
|
||||
[connection_max_tries=3, ]
|
||||
[connection_auto_close=true ]
|
||||
;
|
||||
```
|
||||
|
||||
See a detailed description of the [CREATE TABLE](../../../sql-reference/statements/create/table.md#create-table-query) query.
|
||||
|
@ -101,6 +101,8 @@ For very large clusters, you can use different ZooKeeper clusters for different
|
||||
|
||||
Replication is asynchronous and multi-master. `INSERT` queries (as well as `ALTER`) can be sent to any available server. Data is inserted on the server where the query is run, and then it is copied to the other servers. Because it is asynchronous, recently inserted data appears on the other replicas with some latency. If part of the replicas are not available, the data is written when they become available. If a replica is available, the latency is the amount of time it takes to transfer the block of compressed data over the network. The number of threads performing background tasks for replicated tables can be set by [background_schedule_pool_size](../../../operations/settings/settings.md#background_schedule_pool_size) setting.
|
||||
|
||||
`ReplicatedMergeTree` engine uses a separate thread pool for replicated fetches. Size of the pool is limited by the [background_fetches_pool_size](../../../operations/settings/settings.md#background_fetches_pool_size) setting which can be tuned with a server restart.
|
||||
|
||||
By default, an INSERT query waits for confirmation of writing the data from only one replica. If the data was successfully written to only one replica and the server with this replica ceases to exist, the stored data will be lost. To enable getting confirmation of data writes from multiple replicas, use the `insert_quorum` option.
|
||||
|
||||
Each block of data is written atomically. The INSERT query is divided into blocks up to `max_insert_block_size = 1048576` rows. In other words, if the `INSERT` query has less than 1048576 rows, it is made atomically.
|
||||
@ -284,6 +286,7 @@ If the data in ZooKeeper was lost or damaged, you can save data by moving it to
|
||||
**See Also**
|
||||
|
||||
- [background_schedule_pool_size](../../../operations/settings/settings.md#background_schedule_pool_size)
|
||||
- [background_fetches_pool_size](../../../operations/settings/settings.md#background_fetches_pool_size)
|
||||
- [execute_merges_on_single_replica_time_threshold](../../../operations/settings/settings.md#execute-merges-on-single-replica-time-threshold)
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/operations/table_engines/replication/) <!--hide-->
|
||||
|
@ -5,9 +5,9 @@ toc_title: Configuration Files
|
||||
|
||||
# Configuration Files {#configuration_files}
|
||||
|
||||
ClickHouse supports multi-file configuration management. The main server configuration file is `/etc/clickhouse-server/config.xml`. Other files must be in the `/etc/clickhouse-server/config.d` directory.
|
||||
ClickHouse supports multi-file configuration management. The main server configuration file is `/etc/clickhouse-server/config.xml` or `/etc/clickhouse-server/config.yaml`. Other files must be in the `/etc/clickhouse-server/config.d` directory. Note, that any configuration file can be written either in XML or YAML, but mixing formats in one file is not supported. For example, you can have main configs as `config.xml` and `users.xml` and write additional files in `config.d` and `users.d` directories in `.yaml`.
|
||||
|
||||
All the configuration files should be in XML format. Also, they should have the same root element, usually `<yandex>`.
|
||||
All the configuration files should be in XML or YAML formats. All XML files should have the same root element, usually `<yandex>`. As for YAML, `yandex:` should not be present, the parser will insert it automatically.
|
||||
|
||||
## Override {#override}
|
||||
|
||||
@ -32,7 +32,7 @@ Users configuration can be splitted into separate files similar to `config.xml`
|
||||
Directory name is defined as `users_config` setting without `.xml` postfix concatenated with `.d`.
|
||||
Directory `users.d` is used by default, as `users_config` defaults to `users.xml`.
|
||||
|
||||
## Example {#example}
|
||||
## XML example {#example}
|
||||
|
||||
For example, you can have separate config file for each user like this:
|
||||
|
||||
@ -55,6 +55,70 @@ $ cat /etc/clickhouse-server/users.d/alice.xml
|
||||
</yandex>
|
||||
```
|
||||
|
||||
## YAML examples {#example}
|
||||
|
||||
Here you can see default config written in YAML: [config.yaml.example](https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.yaml.example).
|
||||
|
||||
There are some differences between YAML and XML formats in terms of ClickHouse configurations. Here are some tips for writing a configuration in YAML format.
|
||||
|
||||
You should use a Scalar node to write a key-value pair:
|
||||
``` yaml
|
||||
key: value
|
||||
```
|
||||
|
||||
To create a node, containing other nodes you should use a Map:
|
||||
``` yaml
|
||||
map_key:
|
||||
key1: val1
|
||||
key2: val2
|
||||
key3: val3
|
||||
```
|
||||
|
||||
To create a list of values or nodes assigned to one tag you should use a Sequence:
|
||||
``` yaml
|
||||
seq_key:
|
||||
- val1
|
||||
- val2
|
||||
- key1: val3
|
||||
- map:
|
||||
key2: val4
|
||||
key3: val5
|
||||
```
|
||||
|
||||
If you want to write an attribute for a Sequence or Map node, you should use a @ prefix before the attribute key. Note, that @ is reserved by YAML standard, so you should also to wrap it into double quotes:
|
||||
|
||||
``` yaml
|
||||
map:
|
||||
"@attr1": value1
|
||||
"@attr2": value2
|
||||
key: 123
|
||||
```
|
||||
|
||||
From that Map we will get these XML nodes:
|
||||
|
||||
``` xml
|
||||
<map attr1="value1" attr2="value2">
|
||||
<key>123</key>
|
||||
</map>
|
||||
```
|
||||
|
||||
You can also set attributes for Sequence:
|
||||
|
||||
``` yaml
|
||||
seq:
|
||||
- "@attr1": value1
|
||||
- "@attr2": value2
|
||||
- 123
|
||||
- abc
|
||||
```
|
||||
|
||||
So, we can get YAML config equal to this XML one:
|
||||
|
||||
``` xml
|
||||
<seq attr1="value1" attr2="value2">123</seq>
|
||||
<seq attr1="value1" attr2="value2">abc</seq>
|
||||
```
|
||||
|
||||
## Implementation Details {#implementation-details}
|
||||
|
||||
For each config file, the server also generates `file-preprocessed.xml` files when starting. These files contain all the completed substitutions and overrides, and they are intended for informational use. If ZooKeeper substitutions were used in the config files but ZooKeeper is not available on the server start, the server loads the configuration from the preprocessed file.
|
||||
|
@ -17,6 +17,7 @@ To define LDAP server you must add `ldap_servers` section to the `config.xml`.
|
||||
<yandex>
|
||||
<!- ... -->
|
||||
<ldap_servers>
|
||||
<!- Typical LDAP server. -->
|
||||
<my_ldap_server>
|
||||
<host>localhost</host>
|
||||
<port>636</port>
|
||||
@ -31,6 +32,18 @@ To define LDAP server you must add `ldap_servers` section to the `config.xml`.
|
||||
<tls_ca_cert_dir>/path/to/tls_ca_cert_dir</tls_ca_cert_dir>
|
||||
<tls_cipher_suite>ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384</tls_cipher_suite>
|
||||
</my_ldap_server>
|
||||
|
||||
<!- Typical Active Directory with configured user DN detection for further role mapping. -->
|
||||
<my_ad_server>
|
||||
<host>localhost</host>
|
||||
<port>389</port>
|
||||
<bind_dn>EXAMPLE\{user_name}</bind_dn>
|
||||
<user_dn_detection>
|
||||
<base_dn>CN=Users,DC=example,DC=com</base_dn>
|
||||
<search_filter>(&(objectClass=user)(sAMAccountName={user_name}))</search_filter>
|
||||
</user_dn_detection>
|
||||
<enable_tls>no</enable_tls>
|
||||
</my_ad_server>
|
||||
</ldap_servers>
|
||||
</yandex>
|
||||
```
|
||||
@ -43,6 +56,15 @@ Note, that you can define multiple LDAP servers inside the `ldap_servers` sectio
|
||||
- `port` — LDAP server port, default is `636` if `enable_tls` is set to `true`, `389` otherwise.
|
||||
- `bind_dn` — Template used to construct the DN to bind to.
|
||||
- The resulting DN will be constructed by replacing all `{user_name}` substrings of the template with the actual user name during each authentication attempt.
|
||||
- `user_dn_detection` - Section with LDAP search parameters for detecting the actual user DN of the bound user.
|
||||
- This is mainly used in search filters for further role mapping when the server is Active Directory. The resulting user DN will be used when replacing `{user_dn}` substrings wherever they are allowed. By default, user DN is set equal to bind DN, but once search is performed, it will be updated with to the actual detected user DN value.
|
||||
- `base_dn` - Template used to construct the base DN for the LDAP search.
|
||||
- The resulting DN will be constructed by replacing all `{user_name}` and `{bind_dn}` substrings of the template with the actual user name and bind DN during the LDAP search.
|
||||
- `scope` - Scope of the LDAP search.
|
||||
- Accepted values are: `base`, `one_level`, `children`, `subtree` (the default).
|
||||
- `search_filter` - Template used to construct the search filter for the LDAP search.
|
||||
- The resulting filter will be constructed by replacing all `{user_name}`, `{bind_dn}`, and `{base_dn}` substrings of the template with the actual user name, bind DN, and base DN during the LDAP search.
|
||||
- Note, that the special characters must be escaped properly in XML.
|
||||
- `verification_cooldown` — A period of time, in seconds, after a successful bind attempt, during which the user will be assumed to be successfully authenticated for all consecutive requests without contacting the LDAP server.
|
||||
- Specify `0` (the default) to disable caching and force contacting the LDAP server for each authentication request.
|
||||
- `enable_tls` — A flag to trigger the use of the secure connection to the LDAP server.
|
||||
@ -107,7 +129,7 @@ Goes into `config.xml`.
|
||||
<yandex>
|
||||
<!- ... -->
|
||||
<user_directories>
|
||||
<!- ... -->
|
||||
<!- Typical LDAP server. -->
|
||||
<ldap>
|
||||
<server>my_ldap_server</server>
|
||||
<roles>
|
||||
@ -122,6 +144,18 @@ Goes into `config.xml`.
|
||||
<prefix>clickhouse_</prefix>
|
||||
</role_mapping>
|
||||
</ldap>
|
||||
|
||||
<!- Typical Active Directory with role mapping that relies on the detected user DN. -->
|
||||
<ldap>
|
||||
<server>my_ad_server</server>
|
||||
<role_mapping>
|
||||
<base_dn>CN=Users,DC=example,DC=com</base_dn>
|
||||
<attribute>CN</attribute>
|
||||
<scope>subtree</scope>
|
||||
<search_filter>(&(objectClass=group)(member={user_dn}))</search_filter>
|
||||
<prefix>clickhouse_</prefix>
|
||||
</role_mapping>
|
||||
</ldap>
|
||||
</user_directories>
|
||||
</yandex>
|
||||
```
|
||||
@ -137,13 +171,13 @@ Note that `my_ldap_server` referred in the `ldap` section inside the `user_direc
|
||||
- When a user authenticates, while still bound to LDAP, an LDAP search is performed using `search_filter` and the name of the logged-in user. For each entry found during that search, the value of the specified attribute is extracted. For each attribute value that has the specified prefix, the prefix is removed, and the rest of the value becomes the name of a local role defined in ClickHouse, which is expected to be created beforehand by the [CREATE ROLE](../../sql-reference/statements/create/role.md#create-role-statement) statement.
|
||||
- There can be multiple `role_mapping` sections defined inside the same `ldap` section. All of them will be applied.
|
||||
- `base_dn` — Template used to construct the base DN for the LDAP search.
|
||||
- The resulting DN will be constructed by replacing all `{user_name}` and `{bind_dn}` substrings of the template with the actual user name and bind DN during each LDAP search.
|
||||
- The resulting DN will be constructed by replacing all `{user_name}`, `{bind_dn}`, and `{user_dn}` substrings of the template with the actual user name, bind DN, and user DN during each LDAP search.
|
||||
- `scope` — Scope of the LDAP search.
|
||||
- Accepted values are: `base`, `one_level`, `children`, `subtree` (the default).
|
||||
- `search_filter` — Template used to construct the search filter for the LDAP search.
|
||||
- The resulting filter will be constructed by replacing all `{user_name}`, `{bind_dn}` and `{base_dn}` substrings of the template with the actual user name, bind DN and base DN during each LDAP search.
|
||||
- The resulting filter will be constructed by replacing all `{user_name}`, `{bind_dn}`, `{user_dn}`, and `{base_dn}` substrings of the template with the actual user name, bind DN, user DN, and base DN during each LDAP search.
|
||||
- Note, that the special characters must be escaped properly in XML.
|
||||
- `attribute` — Attribute name whose values will be returned by the LDAP search.
|
||||
- `attribute` — Attribute name whose values will be returned by the LDAP search. `cn`, by default.
|
||||
- `prefix` — Prefix, that will be expected to be in front of each string in the original list of strings returned by the LDAP search. The prefix will be removed from the original strings and the resulting strings will be treated as local role names. Empty by default.
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/operations/external-authenticators/ldap/) <!--hide-->
|
||||
|
@ -135,6 +135,39 @@ Default value: 604800 (1 week).
|
||||
|
||||
Similar to [replicated_deduplication_window](#replicated-deduplication-window), `replicated_deduplication_window_seconds` specifies how long to store hash sums of blocks for insert deduplication. Hash sums older than `replicated_deduplication_window_seconds` are removed from Zookeeper, even if they are less than ` replicated_deduplication_window`.
|
||||
|
||||
## replicated_fetches_http_connection_timeout {#replicated_fetches_http_connection_timeout}
|
||||
|
||||
HTTP connection timeout (in seconds) for part fetch requests. Inherited from default profile [http_connection_timeout](./settings.md#http_connection_timeout) if not set explicitly.
|
||||
|
||||
Possible values:
|
||||
|
||||
- Any positive integer.
|
||||
- 0 - Use value of `http_connection_timeout`.
|
||||
|
||||
Default value: 0.
|
||||
|
||||
## replicated_fetches_http_send_timeout {#replicated_fetches_http_send_timeout}
|
||||
|
||||
HTTP send timeout (in seconds) for part fetch requests. Inherited from default profile [http_send_timeout](./settings.md#http_send_timeout) if not set explicitly.
|
||||
|
||||
Possible values:
|
||||
|
||||
- Any positive integer.
|
||||
- 0 - Use value of `http_send_timeout`.
|
||||
|
||||
Default value: 0.
|
||||
|
||||
## replicated_fetches_http_receive_timeout {#replicated_fetches_http_receive_timeout}
|
||||
|
||||
HTTP receive timeout (in seconds) for fetch part requests. Inherited from default profile [http_receive_timeout](./settings.md#http_receive_timeout) if not set explicitly.
|
||||
|
||||
Possible values:
|
||||
|
||||
- Any positive integer.
|
||||
- 0 - Use value of `http_receive_timeout`.
|
||||
|
||||
Default value: 0.
|
||||
|
||||
## old_parts_lifetime {#old-parts-lifetime}
|
||||
|
||||
The time (in seconds) of storing inactive parts to protect against data loss during spontaneous server reboots.
|
||||
|
@ -1520,8 +1520,8 @@ Do not merge aggregation states from different servers for distributed query pro
|
||||
Possible values:
|
||||
|
||||
- 0 — Disabled (final query processing is done on the initiator node).
|
||||
- 1 - Do not merge aggregation states from different servers for distributed query processing (query completelly processed on the shard, initiator only proxy the data).
|
||||
- 2 - Same as 1 but apply `ORDER BY` and `LIMIT` on the initiator (can be used for queries with `ORDER BY` and/or `LIMIT`).
|
||||
- 1 - Do not merge aggregation states from different servers for distributed query processing (query completelly processed on the shard, initiator only proxy the data), can be used in case it is for certain that there are different keys on different shards.
|
||||
- 2 - Same as `1` but applies `ORDER BY` and `LIMIT` (it is not possilbe when the query processed completelly on the remote node, like for `distributed_group_by_no_merge=1`) on the initiator (can be used for queries with `ORDER BY` and/or `LIMIT`).
|
||||
|
||||
**Example**
|
||||
|
||||
@ -2034,6 +2034,16 @@ Possible values:
|
||||
|
||||
Default value: 16.
|
||||
|
||||
## background_fetches_pool_size {#background_fetches_pool_size}
|
||||
|
||||
Sets the number of threads performing background fetches for [replicated](../../engines/table-engines/mergetree-family/replication.md) tables. This setting is applied at the ClickHouse server start and can’t be changed in a user session. For production usage with frequent small insertions or slow ZooKeeper cluster is recomended to use default value.
|
||||
|
||||
Possible values:
|
||||
|
||||
- Any positive integer.
|
||||
|
||||
Default value: 8.
|
||||
|
||||
## always_fetch_merged_part {#always_fetch_merged_part}
|
||||
|
||||
Prohibits data parts merging in [Replicated\*MergeTree](../../engines/table-engines/mergetree-family/replication.md)-engine tables.
|
||||
@ -2863,6 +2873,39 @@ Sets the interval in seconds after which periodically refreshed [live view](../.
|
||||
|
||||
Default value: `60`.
|
||||
|
||||
## http_connection_timeout {#http_connection_timeout}
|
||||
|
||||
HTTP connection timeout (in seconds).
|
||||
|
||||
Possible values:
|
||||
|
||||
- Any positive integer.
|
||||
- 0 - Disabled (infinite timeout).
|
||||
|
||||
Default value: 1.
|
||||
|
||||
## http_send_timeout {#http_send_timeout}
|
||||
|
||||
HTTP send timeout (in seconds).
|
||||
|
||||
Possible values:
|
||||
|
||||
- Any positive integer.
|
||||
- 0 - Disabled (infinite timeout).
|
||||
|
||||
Default value: 1800.
|
||||
|
||||
## http_receive_timeout {#http_receive_timeout}
|
||||
|
||||
HTTP receive timeout (in seconds).
|
||||
|
||||
Possible values:
|
||||
|
||||
- Any positive integer.
|
||||
- 0 - Disabled (infinite timeout).
|
||||
|
||||
Default value: 1800.
|
||||
|
||||
## check_query_single_value_result {#check_query_single_value_result}
|
||||
|
||||
Defines the level of detail for the [CHECK TABLE](../../sql-reference/statements/check-table.md#checking-mergetree-tables) query result for `MergeTree` family engines .
|
||||
|
@ -253,7 +253,7 @@ windowFunnel(window, [mode, [mode, ... ]])(timestamp, cond1, cond2, ..., condN)
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `window` — Length of the sliding window, it is the time interval between first condition and last condition. The unit of `window` depends on the `timestamp` itself and varies. Determined using the expression `timestamp of cond1 <= timestamp of cond2 <= ... <= timestamp of condN <= timestamp of cond1 + window`.
|
||||
- `window` — Length of the sliding window, it is the time interval between the first and the last condition. The unit of `window` depends on the `timestamp` itself and varies. Determined using the expression `timestamp of cond1 <= timestamp of cond2 <= ... <= timestamp of condN <= timestamp of cond1 + window`.
|
||||
- `mode` — It is an optional argument. One or more modes can be set.
|
||||
- `'strict'` — If same condition holds for sequence of events then such non-unique events would be skipped.
|
||||
- `'strict_order'` — Don't allow interventions of other events. E.g. in the case of `A->B->D->C`, it stops finding `A->B->C` at the `D` and the max event level is 2.
|
||||
@ -312,7 +312,7 @@ FROM
|
||||
GROUP BY user_id
|
||||
)
|
||||
GROUP BY level
|
||||
ORDER BY level ASC
|
||||
ORDER BY level ASC;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
@ -31,7 +31,7 @@ For example, Decimal32(4) can contain numbers from -99999.9999 to 99999.9999 wit
|
||||
|
||||
Internally data is represented as normal signed integers with respective bit width. Real value ranges that can be stored in memory are a bit larger than specified above, which are checked only on conversion from a string.
|
||||
|
||||
Because modern CPU’s do not support 128-bit integers natively, operations on Decimal128 are emulated. Because of this Decimal128 works significantly slower than Decimal32/Decimal64.
|
||||
Because modern CPUs do not support 128-bit integers natively, operations on Decimal128 are emulated. Because of this Decimal128 works significantly slower than Decimal32/Decimal64.
|
||||
|
||||
## Operations and Result Type {#operations-and-result-type}
|
||||
|
||||
|
@ -10,13 +10,14 @@ toc_title: External Dictionaries
|
||||
|
||||
For information on connecting and configuring external dictionaries, see [External dictionaries](../../sql-reference/dictionaries/external-dictionaries/external-dicts.md).
|
||||
|
||||
## dictGet, dictGetOrDefault {#dictget}
|
||||
## dictGet, dictGetOrDefault, dictGetOrNull {#dictget}
|
||||
|
||||
Retrieves values from an external dictionary.
|
||||
|
||||
``` sql
|
||||
dictGet('dict_name', attr_names, id_expr)
|
||||
dictGetOrDefault('dict_name', attr_names, id_expr, default_value_expr)
|
||||
dictGetOrNull('dict_name', attr_name, id_expr)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
@ -34,12 +35,13 @@ dictGetOrDefault('dict_name', attr_names, id_expr, default_value_expr)
|
||||
|
||||
- `dictGet` returns the content of the `<null_value>` element specified for the attribute in the dictionary configuration.
|
||||
- `dictGetOrDefault` returns the value passed as the `default_value_expr` parameter.
|
||||
- `dictGetOrNull` returns `NULL` in case key was not found in dictionary.
|
||||
|
||||
ClickHouse throws an exception if it cannot parse the value of the attribute or the value doesn’t match the attribute data type.
|
||||
|
||||
**Example for single attribute**
|
||||
**Example for simple key dictionary**
|
||||
|
||||
Create a text file `ext-dict-text.csv` containing the following:
|
||||
Create a text file `ext-dict-test.csv` containing the following:
|
||||
|
||||
``` text
|
||||
1,1
|
||||
@ -96,7 +98,7 @@ LIMIT 3
|
||||
└─────┴────────┘
|
||||
```
|
||||
|
||||
**Example for multiple attributes**
|
||||
**Example for complex key dictionary**
|
||||
|
||||
Create a text file `ext-dict-mult.csv` containing the following:
|
||||
|
||||
@ -161,6 +163,65 @@ LIMIT 3;
|
||||
└─────────┴───────────────────────┘
|
||||
```
|
||||
|
||||
**Example for range key dictionary**
|
||||
|
||||
Input table:
|
||||
|
||||
```sql
|
||||
CREATE TABLE range_key_dictionary_source_table
|
||||
(
|
||||
key UInt64,
|
||||
start_date Date,
|
||||
end_date Date,
|
||||
value String,
|
||||
value_nullable Nullable(String)
|
||||
)
|
||||
ENGINE = TinyLog();
|
||||
|
||||
INSERT INTO range_key_dictionary_source_table VALUES(1, toDate('2019-05-20'), toDate('2019-05-20'), 'First', 'First');
|
||||
INSERT INTO range_key_dictionary_source_table VALUES(2, toDate('2019-05-20'), toDate('2019-05-20'), 'Second', NULL);
|
||||
INSERT INTO range_key_dictionary_source_table VALUES(3, toDate('2019-05-20'), toDate('2019-05-20'), 'Third', 'Third');
|
||||
```
|
||||
|
||||
Create the external dictionary:
|
||||
|
||||
```sql
|
||||
CREATE DICTIONARY range_key_dictionary
|
||||
(
|
||||
key UInt64,
|
||||
start_date Date,
|
||||
end_date Date,
|
||||
value String,
|
||||
value_nullable Nullable(String)
|
||||
)
|
||||
PRIMARY KEY key
|
||||
SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() TABLE 'range_key_dictionary_source_table'))
|
||||
LIFETIME(MIN 1 MAX 1000)
|
||||
LAYOUT(RANGE_HASHED())
|
||||
RANGE(MIN start_date MAX end_date);
|
||||
```
|
||||
|
||||
Perform the query:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
(number, toDate('2019-05-20')),
|
||||
dictHas('range_key_dictionary', number, toDate('2019-05-20')),
|
||||
dictGetOrNull('range_key_dictionary', 'value', number, toDate('2019-05-20')),
|
||||
dictGetOrNull('range_key_dictionary', 'value_nullable', number, toDate('2019-05-20')),
|
||||
dictGetOrNull('range_key_dictionary', ('value', 'value_nullable'), number, toDate('2019-05-20'))
|
||||
FROM system.numbers LIMIT 5 FORMAT TabSeparated;
|
||||
```
|
||||
Result:
|
||||
|
||||
``` text
|
||||
(0,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(1,'2019-05-20') 1 First First ('First','First')
|
||||
(2,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(3,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(4,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
```
|
||||
|
||||
**See Also**
|
||||
|
||||
- [External Dictionaries](../../sql-reference/dictionaries/external-dictionaries/external-dicts.md)
|
||||
|
@ -422,7 +422,7 @@ Type: [UInt8](../../sql-reference/data-types/int-uint.md).
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT isIPAddressInRange('127.0.0.1', '127.0.0.0/8')
|
||||
SELECT isIPAddressInRange('127.0.0.1', '127.0.0.0/8');
|
||||
```
|
||||
|
||||
Result:
|
||||
@ -436,7 +436,7 @@ Result:
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT isIPAddressInRange('127.0.0.1', 'ffff::/16')
|
||||
SELECT isIPAddressInRange('127.0.0.1', 'ffff::/16');
|
||||
```
|
||||
|
||||
Result:
|
||||
|
@ -13,7 +13,7 @@ Returns an array of selected substrings. Empty substrings may be selected if the
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
splitByChar(<separator>, <s>)
|
||||
splitByChar(separator, s)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
@ -29,12 +29,12 @@ Returns an array of selected substrings. Empty substrings may be selected when:
|
||||
- There are multiple consecutive separators;
|
||||
- The original string `s` is empty.
|
||||
|
||||
Type: [Array](../../sql-reference/data-types/array.md) of [String](../../sql-reference/data-types/string.md).
|
||||
Type: [Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md)).
|
||||
|
||||
**Example**
|
||||
|
||||
``` sql
|
||||
SELECT splitByChar(',', '1,2,3,abcde')
|
||||
SELECT splitByChar(',', '1,2,3,abcde');
|
||||
```
|
||||
|
||||
``` text
|
||||
@ -50,7 +50,7 @@ Splits a string into substrings separated by a string. It uses a constant string
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
splitByString(<separator>, <s>)
|
||||
splitByString(separator, s)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
@ -62,7 +62,7 @@ splitByString(<separator>, <s>)
|
||||
|
||||
Returns an array of selected substrings. Empty substrings may be selected when:
|
||||
|
||||
Type: [Array](../../sql-reference/data-types/array.md) of [String](../../sql-reference/data-types/string.md).
|
||||
Type: [Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md)).
|
||||
|
||||
- A non-empty separator occurs at the beginning or end of the string;
|
||||
- There are multiple consecutive non-empty separators;
|
||||
@ -71,7 +71,7 @@ Type: [Array](../../sql-reference/data-types/array.md) of [String](../../sql-ref
|
||||
**Example**
|
||||
|
||||
``` sql
|
||||
SELECT splitByString(', ', '1, 2 3, 4,5, abcde')
|
||||
SELECT splitByString(', ', '1, 2 3, 4,5, abcde');
|
||||
```
|
||||
|
||||
``` text
|
||||
@ -81,7 +81,7 @@ SELECT splitByString(', ', '1, 2 3, 4,5, abcde')
|
||||
```
|
||||
|
||||
``` sql
|
||||
SELECT splitByString('', 'abcde')
|
||||
SELECT splitByString('', 'abcde');
|
||||
```
|
||||
|
||||
``` text
|
||||
@ -92,12 +92,12 @@ SELECT splitByString('', 'abcde')
|
||||
|
||||
## splitByRegexp(regexp, s) {#splitbyregexpseparator-s}
|
||||
|
||||
Splits a string into substrings separated by a regular expression. It uses a regular expression string `regexp` as the separator. If the `regexp` is empty, it will split the string s into an array of single characters. If no match is found for this regex expression, the string `s` won't be split.
|
||||
Splits a string into substrings separated by a regular expression. It uses a regular expression string `regexp` as the separator. If the `regexp` is empty, it will split the string `s` into an array of single characters. If no match is found for this regular expression, the string `s` won't be split.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
splitByRegexp(<regexp>, <s>)
|
||||
splitByRegexp(regexp, s)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
@ -109,28 +109,36 @@ splitByRegexp(<regexp>, <s>)
|
||||
|
||||
Returns an array of selected substrings. Empty substrings may be selected when:
|
||||
|
||||
|
||||
- A non-empty regular expression match occurs at the beginning or end of the string;
|
||||
- There are multiple consecutive non-empty regular expression matches;
|
||||
- The original string `s` is empty while the regular expression is not empty.
|
||||
|
||||
Type: [Array](../../sql-reference/data-types/array.md) of [String](../../sql-reference/data-types/string.md).
|
||||
Type: [Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md)).
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT splitByRegexp('\\d+', 'a12bc23de345f')
|
||||
SELECT splitByRegexp('\\d+', 'a12bc23de345f');
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─splitByRegexp('\\d+', 'a12bc23de345f')─┐
|
||||
│ ['a','bc','de','f'] │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT splitByRegexp('', 'abcde')
|
||||
SELECT splitByRegexp('', 'abcde');
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─splitByRegexp('', 'abcde')─┐
|
||||
│ ['a','b','c','d','e'] │
|
||||
@ -149,7 +157,7 @@ Selects substrings of consecutive bytes from the ranges a-z and A-Z.Returns an a
|
||||
**Example**
|
||||
|
||||
``` sql
|
||||
SELECT alphaTokens('abca1abc')
|
||||
SELECT alphaTokens('abca1abc');
|
||||
```
|
||||
|
||||
``` text
|
||||
|
@ -373,7 +373,7 @@ This function accepts a number or date or date with time, and returns a FixedStr
|
||||
|
||||
## reinterpretAsUUID {#reinterpretasuuid}
|
||||
|
||||
This function accepts 16 bytes string, and returns UUID containing bytes representing the corresponding value in network byte order (big-endian). If the string isn't long enough, the functions work as if the string is padded with the necessary number of null bytes to the end. If the string longer than 16 bytes, the extra bytes at the end are ignored.
|
||||
Accepts 16 bytes string and returns UUID containing bytes representing the corresponding value in network byte order (big-endian). If the string isn't long enough, the function works as if the string is padded with the necessary number of null bytes to the end. If the string longer than 16 bytes, the extra bytes at the end are ignored.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -429,7 +429,24 @@ Result:
|
||||
|
||||
## reinterpret(x, T) {#type_conversion_function-reinterpret}
|
||||
|
||||
Use the same source in-memory bytes sequence for `x` value and reinterpret it to destination type
|
||||
Uses the same source in-memory bytes sequence for `x` value and reinterprets it to destination type.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
reinterpret(x, type)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `x` — Any type.
|
||||
- `type` — Destination type. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- Destination type value.
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
```sql
|
||||
@ -448,11 +465,27 @@ Result:
|
||||
|
||||
## CAST(x, T) {#type_conversion_function-cast}
|
||||
|
||||
Converts input value `x` to the `T` data type. Unlike to `reinterpret` function use external representation of `x` value.
|
||||
Converts input value `x` to the `T` data type. Unlike to `reinterpret` function, type conversion is performed in a natural way.
|
||||
|
||||
The syntax `CAST(x AS t)` is also supported.
|
||||
|
||||
Note, that if value `x` does not fit the bounds of type T, the function overflows. For example, CAST(-1, 'UInt8') returns 255.
|
||||
!!! note "Note"
|
||||
If value `x` does not fit the bounds of type `T`, the function overflows. For example, `CAST(-1, 'UInt8')` returns `255`.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
CAST(x, T)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `x` — Any type.
|
||||
- `T` — Destination type. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- Destination type value.
|
||||
|
||||
**Examples**
|
||||
|
||||
@ -460,9 +493,9 @@ Query:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
cast(toInt8(-1), 'UInt8') AS cast_int_to_uint,
|
||||
cast(toInt8(1), 'Float32') AS cast_int_to_float,
|
||||
cast('1', 'UInt32') AS cast_string_to_int
|
||||
CAST(toInt8(-1), 'UInt8') AS cast_int_to_uint,
|
||||
CAST(toInt8(1), 'Float32') AS cast_int_to_float,
|
||||
CAST('1', 'UInt32') AS cast_string_to_int;
|
||||
```
|
||||
|
||||
Result:
|
||||
@ -492,7 +525,7 @@ Result:
|
||||
└─────────────────────┴─────────────────────┴────────────┴─────────────────────┴───────────────────────────┘
|
||||
```
|
||||
|
||||
Conversion to FixedString(N) only works for arguments of type String or FixedString(N).
|
||||
Conversion to FixedString(N) only works for arguments of type [String](../../sql-reference/data-types/string.md) or [FixedString](../../sql-reference/data-types/fixedstring.md).
|
||||
|
||||
Type conversion to [Nullable](../../sql-reference/data-types/nullable.md) and back is supported.
|
||||
|
||||
@ -1038,7 +1071,7 @@ Result:
|
||||
|
||||
## parseDateTime64BestEffort {#parsedatetime64besteffort}
|
||||
|
||||
Same as [parseDateTimeBestEffort](#parsedatetimebesteffort) function but also parse milliseconds and microseconds and return `DateTime64(3)` or `DateTime64(6)` data types.
|
||||
Same as [parseDateTimeBestEffort](#parsedatetimebesteffort) function but also parse milliseconds and microseconds and returns [DateTime](../../sql-reference/functions/type-conversion-functions.md#data_type-datetime) data type.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -1049,9 +1082,13 @@ parseDateTime64BestEffort(time_string [, precision [, time_zone]])
|
||||
**Parameters**
|
||||
|
||||
- `time_string` — String containing a date or date with time to convert. [String](../../sql-reference/data-types/string.md).
|
||||
- `precision` — `3` for milliseconds, `6` for microseconds. Default `3`. Optional [UInt8](../../sql-reference/data-types/int-uint.md).
|
||||
- `precision` — Required precision. `3` — for milliseconds, `6` — for microseconds. Default — `3`. Optional. [UInt8](../../sql-reference/data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone). The function parses `time_string` according to the timezone. Optional. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- `time_string` converted to the [DateTime](../../sql-reference/data-types/datetime.md) data type.
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
@ -1064,7 +1101,7 @@ UNION ALL
|
||||
SELECT parseDateTime64BestEffort('2021-01-01 01:01:00.12346',6) AS a, toTypeName(a) AS t
|
||||
UNION ALL
|
||||
SELECT parseDateTime64BestEffort('2021-01-01 01:01:00.12346',3,'Europe/Moscow') AS a, toTypeName(a) AS t
|
||||
FORMAT PrettyCompactMonoBlcok
|
||||
FORMAT PrettyCompactMonoBlock;
|
||||
```
|
||||
|
||||
Result:
|
||||
@ -1131,12 +1168,14 @@ Result:
|
||||
|
||||
## toUnixTimestamp64Nano {#tounixtimestamp64nano}
|
||||
|
||||
Converts a `DateTime64` to a `Int64` value with fixed sub-second precision.
|
||||
Input value is scaled up or down appropriately depending on it precision. Please note that output value is a timestamp in UTC, not in timezone of `DateTime64`.
|
||||
Converts a `DateTime64` to a `Int64` value with fixed sub-second precision. Input value is scaled up or down appropriately depending on it precision.
|
||||
|
||||
!!! info "Note"
|
||||
The output value is a timestamp in UTC, not in the timezone of `DateTime64`.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
toUnixTimestamp64Milli(value)
|
||||
```
|
||||
|
||||
@ -1152,7 +1191,7 @@ toUnixTimestamp64Milli(value)
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
WITH toDateTime64('2019-09-16 19:20:12.345678910', 6) AS dt64
|
||||
SELECT toUnixTimestamp64Milli(dt64);
|
||||
```
|
||||
@ -1298,4 +1337,3 @@ Result:
|
||||
│ 2,"good" │
|
||||
└───────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
|
@ -316,7 +316,7 @@ Allows executing [CREATE](../../sql-reference/statements/create/index.md) and [A
|
||||
|
||||
Allows executing [DROP](../../sql-reference/statements/misc.md#drop) and [DETACH](../../sql-reference/statements/misc.md#detach) queries according to the following hierarchy of privileges:
|
||||
|
||||
- `DROP`. Level:
|
||||
- `DROP`. Level: `GROUP`
|
||||
- `DROP DATABASE`. Level: `DATABASE`
|
||||
- `DROP TABLE`. Level: `TABLE`
|
||||
- `DROP VIEW`. Level: `VIEW`
|
||||
|
@ -16,6 +16,9 @@ A query may simultaneously specify `PREWHERE` and `WHERE`. In this case, `PREWHE
|
||||
|
||||
If the `optimize_move_to_prewhere` setting is set to 0, heuristics to automatically move parts of expressions from `WHERE` to `PREWHERE` are disabled.
|
||||
|
||||
!!! note "Attention"
|
||||
The `PREWHERE` section is executed before` FINAL`, so the results of `FROM FINAL` queries may be skewed when using` PREWHERE` with fields not in the `ORDER BY` section of a table.
|
||||
|
||||
## Limitations {#limitations}
|
||||
|
||||
`PREWHERE` is only supported by tables from the `*MergeTree` family.
|
||||
|
@ -183,7 +183,7 @@ CREATE TABLE big_table (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9
|
||||
#### Ограничения {#limitations}
|
||||
* hadoop\_security\_kerberos\_ticket\_cache\_path могут быть определены только на глобальном уровне
|
||||
|
||||
## Поддержика Kerberos {#kerberos-support}
|
||||
## Поддержка Kerberos {#kerberos-support}
|
||||
|
||||
Если hadoop\_security\_authentication параметр имеет значение 'kerberos', ClickHouse аутентифицируется с помощью Kerberos.
|
||||
[Расширенные параметры](#clickhouse-extras) и hadoop\_security\_kerberos\_ticket\_cache\_path помогают сделать это.
|
||||
|
@ -65,6 +65,8 @@ ClickHouse хранит метаинформацию о репликах в [Apa
|
||||
|
||||
Репликация асинхронная, мульти-мастер. Запросы `INSERT` и `ALTER` можно направлять на любой доступный сервер. Данные вставятся на сервер, где выполнен запрос, а затем скопируются на остальные серверы. В связи с асинхронностью, только что вставленные данные появляются на остальных репликах с небольшой задержкой. Если часть реплик недоступна, данные на них запишутся тогда, когда они станут доступны. Если реплика доступна, то задержка составляет столько времени, сколько требуется для передачи блока сжатых данных по сети. Количество потоков для выполнения фоновых задач можно задать с помощью настройки [background_schedule_pool_size](../../../operations/settings/settings.md#background_schedule_pool_size).
|
||||
|
||||
Движок `ReplicatedMergeTree` использует отдельный пул потоков для скачивания кусков данных. Размер пула ограничен настройкой [background_fetches_pool_size](../../../operations/settings/settings.md#background_fetches_pool_size), которую можно указать при перезапуске сервера.
|
||||
|
||||
По умолчанию, запрос INSERT ждёт подтверждения записи только от одной реплики. Если данные были успешно записаны только на одну реплику, и сервер с этой репликой перестал существовать, то записанные данные будут потеряны. Вы можете включить подтверждение записи от нескольких реплик, используя настройку `insert_quorum`.
|
||||
|
||||
Каждый блок данных записывается атомарно. Запрос INSERT разбивается на блоки данных размером до `max_insert_block_size = 1048576` строк. То есть, если в запросе `INSERT` менее 1048576 строк, то он делается атомарно.
|
||||
@ -249,5 +251,6 @@ $ sudo -u clickhouse touch /var/lib/clickhouse/flags/force_restore_data
|
||||
**Смотрите также**
|
||||
|
||||
- [background_schedule_pool_size](../../../operations/settings/settings.md#background_schedule_pool_size)
|
||||
- [background_fetches_pool_size](../../../operations/settings/settings.md#background_fetches_pool_size)
|
||||
- [execute_merges_on_single_replica_time_threshold](../../../operations/settings/settings.md#execute-merges-on-single-replica-time-threshold)
|
||||
|
||||
|
@ -6,9 +6,9 @@ toc_title: "Конфигурационные файлы"
|
||||
|
||||
# Конфигурационные файлы {#configuration_files}
|
||||
|
||||
Основной конфигурационный файл сервера - `config.xml`. Он расположен в директории `/etc/clickhouse-server/`.
|
||||
Основной конфигурационный файл сервера - `config.xml` или `config.yaml`. Он расположен в директории `/etc/clickhouse-server/`.
|
||||
|
||||
Отдельные настройки могут быть переопределены в файлах `*.xml` и `*.conf` из директории `config.d` рядом с конфигом.
|
||||
Отдельные настройки могут быть переопределены в файлах `*.xml` и `*.conf`, а также `.yaml` (для файлов в формате YAML) из директории `config.d` рядом с конфигом.
|
||||
|
||||
У элементов этих конфигурационных файлов могут быть указаны атрибуты `replace` или `remove`.
|
||||
|
||||
@ -25,7 +25,7 @@ toc_title: "Конфигурационные файлы"
|
||||
В элементе `users_config` файла `config.xml` можно указать относительный путь к конфигурационному файлу с настройками пользователей, профилей и квот. Значение `users_config` по умолчанию — `users.xml`. Если `users_config` не указан, то настройки пользователей, профилей и квот можно задать непосредственно в `config.xml`.
|
||||
|
||||
Настройки пользователя могут быть разделены в несколько отдельных файлов аналогичных `config.xml` и `config.d\`. Имя директории задаётся также как `users_config`.
|
||||
Имя директории задаётся так же, как имя файла в `users_config`, с подстановкой `.d` вместо `.xml`.
|
||||
Имя директории задаётся так же, как имя файла в `users_config`, с подстановкой `.d` вместо `.xml`/`.yaml`.
|
||||
Директория `users.d` используется по умолчанию, также как `users.xml` используется для `users_config`.
|
||||
Например, можно иметь по отдельному конфигурационному файлу для каждого пользователя:
|
||||
|
||||
@ -52,3 +52,66 @@ $ cat /etc/clickhouse-server/users.d/alice.xml
|
||||
|
||||
Сервер следит за изменениями конфигурационных файлов, а также файлов и ZooKeeper-узлов, которые были использованы при выполнении подстановок и переопределений, и перезагружает настройки пользователей и кластеров на лету. То есть, можно изменять кластера, пользователей и их настройки без перезапуска сервера.
|
||||
|
||||
## Примеры записи конфигурации на YAML {#example}
|
||||
|
||||
Здесь можно рассмотреть пример реальной конфигурации записанной на YAML: [config.yaml.example](https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.yaml.example).
|
||||
|
||||
Между стандартами XML и YAML имеются различия, поэтому в этом разделе будут перечислены некоторые подсказки для написания конфигурации на YMAL.
|
||||
|
||||
Для записи обычной пары ключ-значение следует использовать Scalar:
|
||||
``` yaml
|
||||
key: value
|
||||
```
|
||||
|
||||
Для создания тега, содержащего подтеги следует использовать Map:
|
||||
``` yaml
|
||||
map_key:
|
||||
key1: val1
|
||||
key2: val2
|
||||
key3: val3
|
||||
```
|
||||
|
||||
Для создания списка значений или подтегов, расположенных по определенному ключу, следует использовать Sequence:
|
||||
``` yaml
|
||||
seq_key:
|
||||
- val1
|
||||
- val2
|
||||
- key1: val3
|
||||
- map:
|
||||
key2: val4
|
||||
key3: val5
|
||||
```
|
||||
|
||||
В случае, усли необходимо объявить тег, аналогичный XML-атрибуту, необходимо задать скаляр, имеющий ключ с префиксом @ и заключенный в кавычки:
|
||||
|
||||
``` yaml
|
||||
map:
|
||||
"@attr1": value1
|
||||
"@attr2": value2
|
||||
key: 123
|
||||
```
|
||||
|
||||
Из такой Map мы получим после конвертации:
|
||||
|
||||
``` xml
|
||||
<map attr1="value1" attr2="value2">
|
||||
<key>123</key>
|
||||
</map>
|
||||
```
|
||||
|
||||
Помимо Map, можно задавать атрибуты для Sequence:
|
||||
|
||||
``` yaml
|
||||
seq:
|
||||
- "@attr1": value1
|
||||
- "@attr2": value2
|
||||
- 123
|
||||
- abc
|
||||
```
|
||||
|
||||
Таким образом получая аналог следующей записи на XML:
|
||||
|
||||
``` xml
|
||||
<seq attr1="value1" attr2="value2">123</seq>
|
||||
<seq attr1="value1" attr2="value2">abc</seq>
|
||||
```
|
||||
|
@ -149,6 +149,39 @@ Eсли суммарное число активных кусков во все
|
||||
|
||||
Стандартное значение Linux dirty_expire_centisecs - 30 секунд (максимальное время, которое записанные данные хранятся только в оперативной памяти), но при больших нагрузках на дисковую систему, данные могут быть записаны намного позже. Экспериментально было найдено время - 480 секунд, за которое гарантированно новый кусок будет записан на диск.
|
||||
|
||||
## replicated_fetches_http_connection_timeout {#replicated_fetches_http_connection_timeout}
|
||||
|
||||
Тайм-аут HTTP-соединения (в секундах) для запросов на скачивание кусков. Наследуется из профиля по умолчанию [http_connection_timeout](./settings.md#http_connection_timeout), если не задан явно.
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 - используется значение `http_connection_timeout`.
|
||||
- Любое положительное целое число.
|
||||
|
||||
Значение по умолчанию: `0`.
|
||||
|
||||
## replicated_fetches_http_send_timeout {#replicated_fetches_http_send_timeout}
|
||||
|
||||
Тайм-аут (в секундах) для отправки HTTP-запросов на скачивание кусков. Наследуется из профиля по умолчанию [http_send_timeout](./settings.md#http_send_timeout), если не задан явно.
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 - используется значение `http_send_timeout`.
|
||||
- Любое положительное целое число.
|
||||
|
||||
Значение по умолчанию: `0`.
|
||||
|
||||
## replicated_fetches_http_receive_timeout {#replicated_fetches_http_receive_timeout}
|
||||
|
||||
Тайм-аут (в секундах) для получения HTTP-запросов на скачивание кусков. Наследуется из профиля по умолчанию [http_receive_timeout](./settings.md#http_receive_timeout), если не задан явно.
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 - используется значение `http_receive_timeout`.
|
||||
- Любое положительное целое число.
|
||||
|
||||
Значение по умолчанию: `0`.
|
||||
|
||||
## max_bytes_to_merge_at_max_space_in_pool {#max-bytes-to-merge-at-max-space-in-pool}
|
||||
|
||||
Максимальный суммарный размер кусков (в байтах) в одном слиянии, при наличии свободных ресурсов в фоновом пуле.
|
||||
|
@ -2043,6 +2043,16 @@ SELECT idx, i FROM null_in WHERE i IN (1, NULL) SETTINGS transform_null_in = 1;
|
||||
|
||||
Значение по умолчанию: 16.
|
||||
|
||||
## background_fetches_pool_size {#background_fetches_pool_size}
|
||||
|
||||
Задает количество потоков для скачивания кусков данных для [реплицируемых](../../engines/table-engines/mergetree-family/replication.md) таблиц. Настройка применяется при запуске сервера ClickHouse и не может быть изменена в пользовательском сеансе. Для использования в продакшене с частыми небольшими вставками или медленным кластером ZooKeeper рекомендуется использовать значение по умолчанию.
|
||||
|
||||
Допустимые значения:
|
||||
|
||||
- Положительное целое число.
|
||||
|
||||
Значение по умолчанию: 8.
|
||||
|
||||
## background_distributed_schedule_pool_size {#background_distributed_schedule_pool_size}
|
||||
|
||||
Задает количество потоков для выполнения фоновых задач. Работает для таблиц с движком [Distributed](../../engines/table-engines/special/distributed.md). Настройка применяется при запуске сервера ClickHouse и не может быть изменена в пользовательском сеансе.
|
||||
@ -2857,5 +2867,37 @@ SELECT * FROM test LIMIT 10 OFFSET 100;
|
||||
│ 109 │
|
||||
└─────┘
|
||||
```
|
||||
## http_connection_timeout {#http_connection_timeout}
|
||||
|
||||
Тайм-аут для HTTP-соединения (в секундах).
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 - бесконечный тайм-аут.
|
||||
- Любое положительное целое число.
|
||||
|
||||
Значение по умолчанию: `1`.
|
||||
|
||||
## http_send_timeout {#http_send_timeout}
|
||||
|
||||
Тайм-аут для отправки данных через HTTP-интерфейс (в секундах).
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 - бесконечный тайм-аут.
|
||||
- Любое положительное целое число.
|
||||
|
||||
Значение по умолчанию: `1800`.
|
||||
|
||||
## http_receive_timeout {#http_receive_timeout}
|
||||
|
||||
Тайм-аут для получения данных через HTTP-интерфейс (в секундах).
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 - бесконечный тайм-аут.
|
||||
- Любое положительное целое число.
|
||||
|
||||
Значение по умолчанию: `1800`.
|
||||
|
||||
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/settings/settings/) <!--hide-->
|
||||
|
@ -253,7 +253,7 @@ windowFunnel(window, [mode, [mode, ... ]])(timestamp, cond1, cond2, ..., condN)
|
||||
|
||||
**Параметры**
|
||||
|
||||
- `window` — ширина скользящего окна по времени. Единица измерения зависит от `timestamp` и может варьироваться. Должно соблюдаться условие `timestamp события cond2 <= timestamp события cond1 + window`.
|
||||
- `window` — ширина скользящего окна по времени. Это время между первым и последним условием. Единица измерения зависит от `timestamp` и может варьироваться. Должно соблюдаться условие `timestamp события cond1 <= timestamp события cond2 <= ... <= timestamp события condN <= timestamp события cond1 + window`.
|
||||
- `mode` — необязательный параметр. Может быть установленно несколько значений одновременно.
|
||||
- `'strict'` — не учитывать подряд идущие повторяющиеся события.
|
||||
- `'strict_order'` — запрещает посторонние события в искомой последовательности. Например, при поиске цепочки `A->B->C` в `A->B->D->C` поиск будет остановлен на `D` и функция вернет 2.
|
||||
@ -311,7 +311,7 @@ FROM
|
||||
GROUP BY user_id
|
||||
)
|
||||
GROUP BY level
|
||||
ORDER BY level ASC
|
||||
ORDER BY level ASC;
|
||||
```
|
||||
|
||||
## retention {#retention}
|
||||
|
@ -12,6 +12,5 @@ ClickHouse поддерживает специальные функции для
|
||||
|
||||
ClickHouse поддерживает:
|
||||
|
||||
- [Встроенные словари](internal-dicts.md#internal_dicts) со специфическим [набором функций](../../sql-reference/dictionaries/external-dictionaries/index.md).
|
||||
- [Подключаемые (внешние) словари](external-dictionaries/external-dicts.md#dicts-external-dicts) с [набором функций](../../sql-reference/dictionaries/external-dictionaries/index.md).
|
||||
|
||||
- [Встроенные словари](internal-dicts.md#internal_dicts) со специфическим [набором функций](../../sql-reference/functions/ext-dict-functions.md).
|
||||
- [Подключаемые (внешние) словари](external-dictionaries/external-dicts.md#dicts-external-dicts) с [набором функций](../../sql-reference/functions/ext-dict-functions.md).
|
@ -5,11 +5,11 @@ toc_title: "Функции для шифрования"
|
||||
|
||||
# Функции шифрования {#encryption-functions}
|
||||
|
||||
Даннвые функции реализуют шифрование и расшифровку данных с помощью AES (Advanced Encryption Standard) алгоритма.
|
||||
Данные функции реализуют шифрование и расшифровку данных с помощью AES (Advanced Encryption Standard) алгоритма.
|
||||
|
||||
Длина ключа зависит от режима шифрования. Он может быть длинной в 16, 24 и 32 байта для режимов шифрования `-128-`, `-196-` и `-256-` соответственно.
|
||||
|
||||
Длина инициализирующего вектора всегда 16 байт (лишнии байты игнорируются).
|
||||
Длина инициализирующего вектора всегда 16 байт (лишние байты игнорируются).
|
||||
|
||||
Обратите внимание, что до версии Clickhouse 21.1 эти функции работали медленно.
|
||||
|
||||
|
@ -7,13 +7,14 @@ toc_title: "Функции для работы с внешними словар
|
||||
|
||||
Информацию о подключении и настройке внешних словарей смотрите в разделе [Внешние словари](../../sql-reference/dictionaries/external-dictionaries/external-dicts.md).
|
||||
|
||||
## dictGet, dictGetOrDefault {#dictget}
|
||||
## dictGet, dictGetOrDefault, dictGetOrNull {#dictget}
|
||||
|
||||
Извлекает значение из внешнего словаря.
|
||||
|
||||
``` sql
|
||||
dictGet('dict_name', attr_names, id_expr)
|
||||
dictGetOrDefault('dict_name', attr_names, id_expr, default_value_expr)
|
||||
dictGetOrNull('dict_name', attr_name, id_expr)
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
@ -31,6 +32,7 @@ dictGetOrDefault('dict_name', attr_names, id_expr, default_value_expr)
|
||||
|
||||
- `dictGet` возвращает содержимое элемента `<null_value>`, указанного для атрибута в конфигурации словаря.
|
||||
- `dictGetOrDefault` возвращает атрибут `default_value_expr`.
|
||||
- `dictGetOrNull` возвращает `NULL` в случае, если ключ не найден в словаре.
|
||||
|
||||
Если значение атрибута не удалось обработать или оно не соответствует типу данных атрибута, то ClickHouse генерирует исключение.
|
||||
|
||||
@ -158,6 +160,65 @@ LIMIT 3;
|
||||
└─────────┴───────────────────────┘
|
||||
```
|
||||
|
||||
**Пример для словаря с диапазоном ключей**
|
||||
|
||||
Создадим таблицу:
|
||||
|
||||
```sql
|
||||
CREATE TABLE range_key_dictionary_source_table
|
||||
(
|
||||
key UInt64,
|
||||
start_date Date,
|
||||
end_date Date,
|
||||
value String,
|
||||
value_nullable Nullable(String)
|
||||
)
|
||||
ENGINE = TinyLog();
|
||||
|
||||
INSERT INTO range_key_dictionary_source_table VALUES(1, toDate('2019-05-20'), toDate('2019-05-20'), 'First', 'First');
|
||||
INSERT INTO range_key_dictionary_source_table VALUES(2, toDate('2019-05-20'), toDate('2019-05-20'), 'Second', NULL);
|
||||
INSERT INTO range_key_dictionary_source_table VALUES(3, toDate('2019-05-20'), toDate('2019-05-20'), 'Third', 'Third');
|
||||
```
|
||||
|
||||
Создадим внешний словарь:
|
||||
|
||||
```sql
|
||||
CREATE DICTIONARY range_key_dictionary
|
||||
(
|
||||
key UInt64,
|
||||
start_date Date,
|
||||
end_date Date,
|
||||
value String,
|
||||
value_nullable Nullable(String)
|
||||
)
|
||||
PRIMARY KEY key
|
||||
SOURCE(CLICKHOUSE(HOST 'localhost' PORT tcpPort() TABLE 'range_key_dictionary_source_table'))
|
||||
LIFETIME(MIN 1 MAX 1000)
|
||||
LAYOUT(RANGE_HASHED())
|
||||
RANGE(MIN start_date MAX end_date);
|
||||
```
|
||||
|
||||
Выполним запрос:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
(number, toDate('2019-05-20')),
|
||||
dictHas('range_key_dictionary', number, toDate('2019-05-20')),
|
||||
dictGetOrNull('range_key_dictionary', 'value', number, toDate('2019-05-20')),
|
||||
dictGetOrNull('range_key_dictionary', 'value_nullable', number, toDate('2019-05-20')),
|
||||
dictGetOrNull('range_key_dictionary', ('value', 'value_nullable'), number, toDate('2019-05-20'))
|
||||
FROM system.numbers LIMIT 5 FORMAT TabSeparated;
|
||||
```
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
(0,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(1,'2019-05-20') 1 First First ('First','First')
|
||||
(2,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(3,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(4,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
```
|
||||
|
||||
**Смотрите также**
|
||||
|
||||
- [Внешние словари](../../sql-reference/functions/ext-dict-functions.md)
|
||||
|
@ -397,9 +397,9 @@ SELECT addr, isIPv6String(addr) FROM ( SELECT ['::', '1111::ffff', '::ffff:127.0
|
||||
|
||||
## isIPAddressInRange {#isipaddressinrange}
|
||||
|
||||
Проверяет попадает ли IP адрес в интервал, заданный в [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) нотации.
|
||||
Проверяет, попадает ли IP адрес в интервал, заданный в нотации [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing).
|
||||
|
||||
**Syntax**
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
isIPAddressInRange(address, prefix)
|
||||
@ -409,7 +409,7 @@ isIPAddressInRange(address, prefix)
|
||||
**Аргументы**
|
||||
|
||||
- `address` — IPv4 или IPv6 адрес. [String](../../sql-reference/data-types/string.md).
|
||||
- `prefix` — IPv4 или IPv6 подсеть, заданная в CIDR нотации. [String](../../sql-reference/data-types/string.md).
|
||||
- `prefix` — IPv4 или IPv6 подсеть, заданная в нотации CIDR. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
@ -422,7 +422,7 @@ isIPAddressInRange(address, prefix)
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT isIPAddressInRange('127.0.0.1', '127.0.0.0/8')
|
||||
SELECT isIPAddressInRange('127.0.0.1', '127.0.0.0/8');
|
||||
```
|
||||
|
||||
Результат:
|
||||
@ -436,7 +436,7 @@ SELECT isIPAddressInRange('127.0.0.1', '127.0.0.0/8')
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT isIPAddressInRange('127.0.0.1', 'ffff::/16')
|
||||
SELECT isIPAddressInRange('127.0.0.1', 'ffff::/16');
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
@ -18,37 +18,37 @@ toc_title: JSON
|
||||
|
||||
Проверяет наличие поля с именем `name`.
|
||||
|
||||
Алиас: `simpleJSONHas`.
|
||||
Синоним: `simpleJSONHas`.
|
||||
|
||||
## visitParamExtractUInt(params, name) {#visitparamextractuintparams-name}
|
||||
|
||||
Пытается выделить число типа UInt64 из значения поля с именем `name`. Если поле строковое, пытается выделить число из начала строки. Если такого поля нет, или если оно есть, но содержит не число, то возвращает 0.
|
||||
|
||||
Алиас: `simpleJSONExtractUInt`.
|
||||
Синоним: `simpleJSONExtractUInt`.
|
||||
|
||||
## visitParamExtractInt(params, name) {#visitparamextractintparams-name}
|
||||
|
||||
Аналогично для Int64.
|
||||
|
||||
Алиас: `simpleJSONExtractInt`.
|
||||
Синоним: `simpleJSONExtractInt`.
|
||||
|
||||
## visitParamExtractFloat(params, name) {#visitparamextractfloatparams-name}
|
||||
|
||||
Аналогично для Float64.
|
||||
|
||||
Алиас: `simpleJSONExtractFloat`.
|
||||
Синоним: `simpleJSONExtractFloat`.
|
||||
|
||||
## visitParamExtractBool(params, name) {#visitparamextractboolparams-name}
|
||||
|
||||
Пытается выделить значение true/false. Результат — UInt8.
|
||||
|
||||
Алиас: `simpleJSONExtractBool`.
|
||||
Синоним: `simpleJSONExtractBool`.
|
||||
|
||||
## visitParamExtractRaw(params, name) {#visitparamextractrawparams-name}
|
||||
|
||||
Возвращает значение поля, включая разделители.
|
||||
|
||||
Алиас: `simpleJSONExtractRaw`.
|
||||
Синоним: `simpleJSONExtractRaw`.
|
||||
|
||||
Примеры:
|
||||
|
||||
@ -61,7 +61,7 @@ visitParamExtractRaw('{"abc":{"def":[1,2,3]}}', 'abc') = '{"def":[1,2,3]}';
|
||||
|
||||
Разбирает строку в двойных кавычках. У значения убирается экранирование. Если убрать экранированные символы не удалось, то возвращается пустая строка.
|
||||
|
||||
Алиас: `simpleJSONExtractString`.
|
||||
Синоним: `simpleJSONExtractString`.
|
||||
|
||||
Примеры:
|
||||
|
||||
|
@ -14,7 +14,7 @@ separator должен быть константной строкой из ро
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
splitByChar(<separator>, <s>)
|
||||
splitByChar(separator, s)
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
@ -30,12 +30,12 @@ splitByChar(<separator>, <s>)
|
||||
- Задано несколько последовательных разделителей;
|
||||
- Исходная строка `s` пуста.
|
||||
|
||||
Type: [Array](../../sql-reference/data-types/array.md) of [String](../../sql-reference/data-types/string.md).
|
||||
Тип: [Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md)).
|
||||
|
||||
**Пример**
|
||||
|
||||
``` sql
|
||||
SELECT splitByChar(',', '1,2,3,abcde')
|
||||
SELECT splitByChar(',', '1,2,3,abcde');
|
||||
```
|
||||
|
||||
``` text
|
||||
@ -67,12 +67,12 @@ splitByString(separator, s)
|
||||
- Задано несколько последовательных разделителей;
|
||||
- Исходная строка `s` пуста.
|
||||
|
||||
Тип: [Array](../../sql-reference/data-types/array.md) of [String](../../sql-reference/data-types/string.md).
|
||||
Тип: [Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md)).
|
||||
|
||||
**Примеры**
|
||||
|
||||
``` sql
|
||||
SELECT splitByString(', ', '1, 2 3, 4,5, abcde')
|
||||
SELECT splitByString(', ', '1, 2 3, 4,5, abcde');
|
||||
```
|
||||
|
||||
``` text
|
||||
@ -82,7 +82,7 @@ SELECT splitByString(', ', '1, 2 3, 4,5, abcde')
|
||||
```
|
||||
|
||||
``` sql
|
||||
SELECT splitByString('', 'abcde')
|
||||
SELECT splitByString('', 'abcde');
|
||||
```
|
||||
|
||||
``` text
|
||||
@ -91,6 +91,60 @@ SELECT splitByString('', 'abcde')
|
||||
└────────────────────────────┘
|
||||
```
|
||||
|
||||
## splitByRegexp(regexp, s) {#splitbyregexpseparator-s}
|
||||
|
||||
Разбивает строку на подстроки, разделенные регулярным выражением. В качестве разделителя используется строка регулярного выражения `regexp`. Если `regexp` пустая, функция разделит строку `s` на массив одиночных символов. Если для регулярного выражения совпадения не найдено, строка `s` не будет разбита.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
splitByRegexp(regexp, s)
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `regexp` — регулярное выражение. Константа. [String](../data-types/string.md) или [FixedString](../data-types/fixedstring.md).
|
||||
- `s` — разбиваемая строка. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Возвращаемые значения**
|
||||
|
||||
Возвращает массив выбранных подстрок. Пустая подстрока может быть возвращена, если:
|
||||
|
||||
- Непустое совпадение с регулярным выражением происходит в начале или конце строки;
|
||||
- Имеется несколько последовательных совпадений c непустым регулярным выражением;
|
||||
- Исходная строка `s` пуста, а регулярное выражение не пустое.
|
||||
|
||||
Тип: [Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md)).
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT splitByRegexp('\\d+', 'a12bc23de345f');
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─splitByRegexp('\\d+', 'a12bc23de345f')─┐
|
||||
│ ['a','bc','de','f'] │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT splitByRegexp('', 'abcde');
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─splitByRegexp('', 'abcde')─┐
|
||||
│ ['a','b','c','d','e'] │
|
||||
└────────────────────────────┘
|
||||
```
|
||||
|
||||
## arrayStringConcat(arr\[, separator\]) {#arraystringconcatarr-separator}
|
||||
|
||||
@ -106,7 +160,7 @@ separator - необязательный параметр, константна
|
||||
**Пример:**
|
||||
|
||||
``` sql
|
||||
SELECT alphaTokens('abca1abc')
|
||||
SELECT alphaTokens('abca1abc');
|
||||
```
|
||||
|
||||
``` text
|
||||
@ -114,4 +168,3 @@ SELECT alphaTokens('abca1abc')
|
||||
│ ['abca','abc'] │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
|
@ -369,7 +369,7 @@ SELECT toFixedString('foo\0bar', 8) AS s, toStringCutToZero(s) AS s_cut;
|
||||
|
||||
## reinterpretAsUUID {#reinterpretasuuid}
|
||||
|
||||
Функция принимает шестнадцатибайтную строку и интерпретирует ее байты в network order (big-endian). Если строка имеет недостаточную длину, то функция работает так, как будто строка дополнена необходимым количетсвом нулевых байт с конца. Если строка длиннее, чем шестнадцать байт, то игнорируются лишние байты с конца.
|
||||
Функция принимает строку из 16 байт и интерпретирует ее байты в порядок от старшего к младшему. Если строка имеет недостаточную длину, то функция работает так, как будто строка дополнена необходимым количеством нулевых байтов с конца. Если строка длиннее, чем 16 байтов, то лишние байты с конца игнорируются.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
@ -425,9 +425,27 @@ SELECT uuid = uuid2;
|
||||
|
||||
## reinterpret(x, T) {#type_conversion_function-reinterpret}
|
||||
|
||||
Использует туже самую исходную последовательность байт в памяти для значения `x` и переинтерпретирует ее как конечный тип данных
|
||||
Использует ту же самую исходную последовательность байтов в памяти для значения `x` и интерпретирует ее как конечный тип данных `T`.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
reinterpret(x, type)
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `x` — любой тип данных.
|
||||
- `type` — конечный тип данных. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
- Значение конечного типа данных.
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос:
|
||||
|
||||
```sql
|
||||
SELECT reinterpret(toInt8(-1), 'UInt8') as int_to_uint,
|
||||
reinterpret(toInt8(1), 'Float32') as int_to_float,
|
||||
@ -448,7 +466,23 @@ SELECT reinterpret(toInt8(-1), 'UInt8') as int_to_uint,
|
||||
|
||||
Поддерживается также синтаксис `CAST(x AS t)`.
|
||||
|
||||
Обратите внимание, что если значение `x` не может быть преобразовано к типу `T`, возникает переполнение. Например, `CAST(-1, 'UInt8')` возвращает 255.
|
||||
!!! warning "Предупреждение"
|
||||
Если значение `x` не может быть преобразовано к типу `T`, возникает переполнение. Например, `CAST(-1, 'UInt8')` возвращает 255.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
CAST(x, T)
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `x` — любой тип данных.
|
||||
- `T` — конечный тип данных. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
- Значение конечного типа данных.
|
||||
|
||||
**Примеры**
|
||||
|
||||
@ -456,9 +490,9 @@ SELECT reinterpret(toInt8(-1), 'UInt8') as int_to_uint,
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
cast(toInt8(-1), 'UInt8') AS cast_int_to_uint,
|
||||
cast(toInt8(1), 'Float32') AS cast_int_to_float,
|
||||
cast('1', 'UInt32') AS cast_string_to_int
|
||||
CAST(toInt8(-1), 'UInt8') AS cast_int_to_uint,
|
||||
CAST(toInt8(1), 'Float32') AS cast_int_to_float,
|
||||
CAST('1', 'UInt32') AS cast_string_to_int
|
||||
```
|
||||
|
||||
Результат:
|
||||
@ -488,9 +522,9 @@ SELECT
|
||||
└─────────────────────┴─────────────────────┴────────────┴─────────────────────┴───────────────────────────┘
|
||||
```
|
||||
|
||||
Преобразование в FixedString(N) работает только для аргументов типа String или FixedString(N).
|
||||
Преобразование в FixedString(N) работает только для аргументов типа [String](../../sql-reference/data-types/string.md) или [FixedString](../../sql-reference/data-types/fixedstring.md).
|
||||
|
||||
Поддержано преобразование к типу [Nullable](../../sql-reference/functions/type-conversion-functions.md) и обратно.
|
||||
Поддерживается преобразование к типу [Nullable](../../sql-reference/functions/type-conversion-functions.md) и обратно.
|
||||
|
||||
**Примеры**
|
||||
|
||||
@ -860,7 +894,7 @@ AS parseDateTimeBestEffortUS;
|
||||
## parseDateTimeBestEffortOrZero {#parsedatetimebesteffortorzero}
|
||||
## parseDateTime32BestEffortOrZero {#parsedatetime32besteffortorzero}
|
||||
|
||||
Работает также как [parseDateTimeBestEffort](#parsedatetimebesteffort), но возвращает нулевую дату или нулевую дату и время когда получает формат даты который не может быть обработан.
|
||||
Работает аналогично функции [parseDateTimeBestEffort](#parsedatetimebesteffort), но возвращает нулевое значение, если формат даты не может быть обработан.
|
||||
|
||||
## parseDateTimeBestEffortUSOrNull {#parsedatetimebesteffortusornull}
|
||||
|
||||
@ -1036,19 +1070,23 @@ SELECT parseDateTimeBestEffortUSOrZero('02.2021') AS parseDateTimeBestEffortUSOr
|
||||
|
||||
## parseDateTime64BestEffort {#parsedatetime64besteffort}
|
||||
|
||||
Работает также как функция [parseDateTimeBestEffort](#parsedatetimebesteffort) но также понимамет милисекунды и микросекунды и возвращает `DateTime64(3)` или `DateTime64(6)` типы данных в зависимости от заданной точности.
|
||||
Работает аналогично функции [parseDateTimeBestEffort](#parsedatetimebesteffort), но также принимает миллисекунды и микросекунды. Возвращает тип данных [DateTime](../../sql-reference/functions/type-conversion-functions.md#data_type-datetime).
|
||||
|
||||
**Syntax**
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
parseDateTime64BestEffort(time_string [, precision [, time_zone]])
|
||||
```
|
||||
|
||||
**Parameters**
|
||||
**Аргументы**
|
||||
|
||||
- `time_string` — String containing a date or date with time to convert. [String](../../sql-reference/data-types/string.md).
|
||||
- `precision` — `3` for milliseconds, `6` for microseconds. Default `3`. Optional [UInt8](../../sql-reference/data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone). The function parses `time_string` according to the timezone. Optional. [String](../../sql-reference/data-types/string.md).
|
||||
- `time_string` — строка, содержащая дату или дату со временем, которые нужно преобразовать. [String](../../sql-reference/data-types/string.md).
|
||||
- `precision` — требуемая точность: `3` — для миллисекунд, `6` — для микросекунд. По умолчанию — `3`. Необязательный. [UInt8](../../sql-reference/data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone). Разбирает значение `time_string` в зависимости от часового пояса. Необязательный. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
- `time_string`, преобразованная в тип данных [DateTime](../../sql-reference/data-types/datetime.md).
|
||||
|
||||
**Примеры**
|
||||
|
||||
@ -1062,7 +1100,7 @@ UNION ALL
|
||||
SELECT parseDateTime64BestEffort('2021-01-01 01:01:00.12346',6) AS a, toTypeName(a) AS t
|
||||
UNION ALL
|
||||
SELECT parseDateTime64BestEffort('2021-01-01 01:01:00.12346',3,'Europe/Moscow') AS a, toTypeName(a) AS t
|
||||
FORMAT PrettyCompactMonoBlcok
|
||||
FORMAT PrettyCompactMonoBlock;
|
||||
```
|
||||
|
||||
Результат:
|
||||
@ -1078,12 +1116,11 @@ FORMAT PrettyCompactMonoBlcok
|
||||
|
||||
## parseDateTime64BestEffortOrNull {#parsedatetime32besteffortornull}
|
||||
|
||||
Работает также как функция [parseDateTime64BestEffort](#parsedatetime64besteffort) но возвращает `NULL` когда встречает формат даты который не может обработать.
|
||||
Работает аналогично функции [parseDateTime64BestEffort](#parsedatetime64besteffort), но возвращает `NULL`, если формат даты не может быть обработан.
|
||||
|
||||
## parseDateTime64BestEffortOrZero {#parsedatetime64besteffortorzero}
|
||||
|
||||
Работает также как функция [parseDateTime64BestEffort](#parsedatetimebesteffort) но возвращает "нулевую" дату и время когда встречает формат даты который не может обработать.
|
||||
|
||||
Работает аналогично функции [parseDateTime64BestEffort](#parsedatetimebesteffort), но возвращает нулевую дату и время, если формат даты не может быть обработан.
|
||||
|
||||
## toLowCardinality {#tolowcardinality}
|
||||
|
||||
@ -1130,11 +1167,14 @@ SELECT toLowCardinality('1');
|
||||
## toUnixTimestamp64Nano {#tounixtimestamp64nano}
|
||||
|
||||
Преобразует значение `DateTime64` в значение `Int64` с фиксированной точностью менее одной секунды.
|
||||
Входное значение округляется соответствующим образом вверх или вниз в зависимости от его точности. Обратите внимание, что возвращаемое значение - это временная метка в UTC, а не в часовом поясе `DateTime64`.
|
||||
Входное значение округляется соответствующим образом вверх или вниз в зависимости от его точности.
|
||||
|
||||
!!! info "Примечание"
|
||||
Возвращаемое значение — это временная метка в UTC, а не в часовом поясе `DateTime64`.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
toUnixTimestamp64Milli(value)
|
||||
```
|
||||
|
||||
@ -1150,7 +1190,7 @@ toUnixTimestamp64Milli(value)
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
WITH toDateTime64('2019-09-16 19:20:12.345678910', 6) AS dt64
|
||||
SELECT toUnixTimestamp64Milli(dt64);
|
||||
```
|
||||
@ -1296,4 +1336,3 @@ FROM numbers(3);
|
||||
│ 2,"good" │
|
||||
└───────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
|
@ -16,6 +16,9 @@ Prewhere — это оптимизация для более эффективн
|
||||
|
||||
Если значение параметра `optimize_move_to_prewhere` равно 0, эвристика по автоматическому перемещнию части выражений из `WHERE` к `PREWHERE` отключается.
|
||||
|
||||
!!! note "Внимание"
|
||||
Секция `PREWHERE` выполняется до `FINAL`, поэтому результаты запросов `FROM FINAL` могут исказится при использовании `PREWHERE` с полями не входящями в `ORDER BY` таблицы.
|
||||
|
||||
## Ограничения {#limitations}
|
||||
|
||||
`PREWHERE` поддерживается только табличными движками из семейства `*MergeTree`.
|
||||
|
@ -51,5 +51,5 @@ The easiest way to see the result is to use `--livereload=8888` argument of buil
|
||||
|
||||
At the moment there’s no easy way to do just that, but you can consider:
|
||||
|
||||
- To hit the “Watch” button on top of GitHub web interface to know as early as possible, even during pull request. Alternative to this is `#github-activity` channel of [public ClickHouse Slack](https://join.slack.com/t/clickhousedb/shared_invite/zt-nwwakmk4-xOJ6cdy0sJC3It8j348~IA).
|
||||
- To hit the “Watch” button on top of GitHub web interface to know as early as possible, even during pull request. Alternative to this is `#github-activity` channel of [public ClickHouse Slack](https://join.slack.com/t/clickhousedb/shared_invite/zt-qfort0u8-TWqK4wIP0YSdoDE0btKa1w).
|
||||
- Some search engines allow to subscribe on specific website changes via email and you can opt-in for that for https://clickhouse.tech.
|
||||
|
@ -62,7 +62,6 @@ def build_amp(lang, args, cfg):
|
||||
for root, _, filenames in os.walk(site_temp):
|
||||
if 'index.html' in filenames:
|
||||
paths.append(prepare_amp_html(lang, args, root, site_temp, main_site_dir))
|
||||
test.test_amp(paths, lang)
|
||||
logging.info(f'Finished building AMP version for {lang}')
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ def build_for_lang(lang, args):
|
||||
|
||||
site_names = {
|
||||
'en': 'ClickHouse Blog',
|
||||
'ru': 'Блог ClickHouse '
|
||||
'ru': 'Блог ClickHouse'
|
||||
}
|
||||
|
||||
assert len(site_names) == len(languages)
|
||||
@ -62,7 +62,7 @@ def build_for_lang(lang, args):
|
||||
strict=True,
|
||||
theme=theme_cfg,
|
||||
nav=blog_nav,
|
||||
copyright='©2016–2020 Yandex LLC',
|
||||
copyright='©2016–2021 Yandex LLC',
|
||||
use_directory_urls=True,
|
||||
repo_name='ClickHouse/ClickHouse',
|
||||
repo_url='https://github.com/ClickHouse/ClickHouse/',
|
||||
|
@ -94,7 +94,7 @@ def build_for_lang(lang, args):
|
||||
site_dir=site_dir,
|
||||
strict=True,
|
||||
theme=theme_cfg,
|
||||
copyright='©2016–2020 Yandex LLC',
|
||||
copyright='©2016–2021 Yandex LLC',
|
||||
use_directory_urls=True,
|
||||
repo_name='ClickHouse/ClickHouse',
|
||||
repo_url='https://github.com/ClickHouse/ClickHouse/',
|
||||
|
@ -31,7 +31,16 @@ def build_nav_entry(root, args):
|
||||
result_items.append((prio, title, payload))
|
||||
elif filename.endswith('.md'):
|
||||
path = os.path.join(root, filename)
|
||||
meta, content = util.read_md_file(path)
|
||||
|
||||
meta = ''
|
||||
content = ''
|
||||
|
||||
try:
|
||||
meta, content = util.read_md_file(path)
|
||||
except:
|
||||
print('Error in file: {}'.format(path))
|
||||
raise
|
||||
|
||||
path = path.split('/', 2)[-1]
|
||||
title = meta.get('toc_title', find_first_header(content))
|
||||
if title:
|
||||
|
@ -3,34 +3,9 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
import bs4
|
||||
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import bs4
|
||||
|
||||
|
||||
def test_amp(paths, lang):
|
||||
try:
|
||||
# Get latest amp validator version
|
||||
subprocess.check_call('amphtml-validator --help',
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
shell=True)
|
||||
except subprocess.CalledProcessError:
|
||||
subprocess.check_call('npm i -g amphtml-validator', stderr=subprocess.DEVNULL, shell=True)
|
||||
|
||||
paths = ' '.join(paths)
|
||||
command = f'amphtml-validator {paths}'
|
||||
try:
|
||||
subprocess.check_output(command, shell=True).decode('utf-8')
|
||||
except subprocess.CalledProcessError:
|
||||
logging.error(f'Invalid AMP for {lang}')
|
||||
raise
|
||||
|
||||
|
||||
def test_template(template_path):
|
||||
if template_path.endswith('amp.html'):
|
||||
|
@ -155,10 +155,6 @@ def build_website(args):
|
||||
os.path.join(args.src_dir, 'utils', 'list-versions', 'version_date.tsv'),
|
||||
os.path.join(args.output_dir, 'data', 'version_date.tsv'))
|
||||
|
||||
shutil.copy2(
|
||||
os.path.join(args.website_dir, 'js', 'embedd.min.js'),
|
||||
os.path.join(args.output_dir, 'js', 'embedd.min.js'))
|
||||
|
||||
for root, _, filenames in os.walk(args.output_dir):
|
||||
for filename in filenames:
|
||||
if filename == 'main.html':
|
||||
|
@ -7,11 +7,11 @@ toc_title: ODBC
|
||||
|
||||
# ODBC {#table-engine-odbc}
|
||||
|
||||
允许ClickHouse通过以下方式连接到外部数据库 [ODBC](https://en.wikipedia.org/wiki/Open_Database_Connectivity).
|
||||
允许ClickHouse通过[ODBC](https://en.wikipedia.org/wiki/Open_Database_Connectivity)方式连接到外部数据库.
|
||||
|
||||
为了安全地实现ODBC连接,ClickHouse使用单独的程序 `clickhouse-odbc-bridge`. 如果直接从ODBC驱动程序加载 `clickhouse-server`,驱动程序问题可能会导致ClickHouse服务器崩溃。 ClickHouse自动启动 `clickhouse-odbc-bridge` 当它是必需的。 ODBC桥程序是从相同的软件包作为安装 `clickhouse-server`.
|
||||
为了安全地实现ODBC连接,ClickHouse使用了一个独立程序 `clickhouse-odbc-bridge`. 如果ODBC驱动程序是直接从 `clickhouse-server`中加载的,那么驱动问题可能会导致ClickHouse服务崩溃。 当有需要时,ClickHouse会自动启动 `clickhouse-odbc-bridge`。 ODBC桥梁程序与`clickhouse-server`来自相同的安装包.
|
||||
|
||||
该引擎支持 [可为空](../../../sql-reference/data-types/nullable.md) 数据类型。
|
||||
该引擎支持 [可为空](../../../sql-reference/data-types/nullable.md) 的数据类型。
|
||||
|
||||
## 创建表 {#creating-a-table}
|
||||
|
||||
@ -25,14 +25,14 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
ENGINE = ODBC(connection_settings, external_database, external_table)
|
||||
```
|
||||
|
||||
请参阅的详细说明 [CREATE TABLE](../../../sql-reference/statements/create.md#create-table-query) 查询。
|
||||
详情请见 [CREATE TABLE](../../../sql-reference/statements/create.md#create-table-query) 查询。
|
||||
|
||||
表结构可以与源表结构不同:
|
||||
|
||||
- 列名应与源表中的列名相同,但您可以按任何顺序使用其中的一些列。
|
||||
- 列类型可能与源表中的列类型不同。 ClickHouse尝试 [投](../../../sql-reference/functions/type-conversion-functions.md#type_conversion_function-cast) ClickHouse数据类型的值。
|
||||
- 列类型可能与源表中的列类型不同。 ClickHouse尝试将数值[映射](../../../sql-reference/functions/type-conversion-functions.md#type_conversion_function-cast) 到ClickHouse的数据类型。
|
||||
|
||||
**发动机参数**
|
||||
**引擎参数**
|
||||
|
||||
- `connection_settings` — Name of the section with connection settings in the `odbc.ini` 文件
|
||||
- `external_database` — Name of a database in an external DBMS.
|
||||
@ -40,13 +40,13 @@ ENGINE = ODBC(connection_settings, external_database, external_table)
|
||||
|
||||
## 用法示例 {#usage-example}
|
||||
|
||||
**通过ODBC从本地MySQL安装中检索数据**
|
||||
**通过ODBC从本地安装的MySQL中检索数据**
|
||||
|
||||
此示例检查Ubuntu Linux18.04和MySQL服务器5.7。
|
||||
本示例针对Ubuntu Linux18.04和MySQL服务器5.7进行检查。
|
||||
|
||||
确保安装了unixODBC和MySQL连接器。
|
||||
请确保安装了unixODBC和MySQL连接器。
|
||||
|
||||
默认情况下(如果从软件包安装),ClickHouse以用户身份启动 `clickhouse`. 因此,您需要在MySQL服务器中创建和配置此用户。
|
||||
默认情况下(如果从软件包安装),ClickHouse以用户`clickhouse`的身份启动 . 因此,您需要在MySQL服务器中创建和配置此用户。
|
||||
|
||||
``` bash
|
||||
$ sudo mysql
|
||||
@ -57,7 +57,7 @@ mysql> CREATE USER 'clickhouse'@'localhost' IDENTIFIED BY 'clickhouse';
|
||||
mysql> GRANT ALL PRIVILEGES ON *.* TO 'clickhouse'@'clickhouse' WITH GRANT OPTION;
|
||||
```
|
||||
|
||||
然后配置连接 `/etc/odbc.ini`.
|
||||
然后在`/etc/odbc.ini`中配置连接 .
|
||||
|
||||
``` bash
|
||||
$ cat /etc/odbc.ini
|
||||
@ -70,7 +70,7 @@ USERNAME = clickhouse
|
||||
PASSWORD = clickhouse
|
||||
```
|
||||
|
||||
您可以使用 `isql` unixodbc安装中的实用程序。
|
||||
您可以从安装的unixodbc中使用 `isql` 实用程序来检查连接情况。
|
||||
|
||||
``` bash
|
||||
$ isql -v mysqlconn
|
||||
|
@ -7,37 +7,37 @@ toc_title: "\u6570\u636E\u5907\u4EFD"
|
||||
|
||||
# 数据备份 {#data-backup}
|
||||
|
||||
尽管[副本](../engines/table-engines/mergetree-family/replication.md) 可以预防硬件错误带来的数据丢失, 但是它不能防止人为操作的错误: 意外删除数据, 删除错误的 table 或者删除错误 cluster 上的 table, 可以导致错误数据处理错误或者数据损坏的 bugs. 这类意外可能会影响所有的副本. ClickHouse 有内建的保障措施可以预防一些错误 — 例如, 默认情况下[您不能使用类似MergeTree的引擎删除包含超过50Gb数据的表](server-configuration-parameters/settings.md#max-table-size-to-drop). 但是,这些保障措施不能涵盖所有可能的情况,并且可以规避。
|
||||
尽管 [副本] (../engines/table-engines/mergetree-family/replication.md) 可以提供针对硬件的错误防护, 但是它不能预防人为操作失误: 数据的意外删除, 错误表的删除或者错误集群上表的删除, 以及导致错误数据处理或者数据损坏的软件bug. 在很多案例中,这类意外可能会影响所有的副本. ClickHouse 有内置的保护措施可以预防一些错误 — 例如, 默认情况下 [不能人工删除使用带有MergeTree引擎且包含超过50Gb数据的表] (server-configuration-parameters/settings.md#max-table-size-to-drop). 但是,这些保护措施不能覆盖所有可能情况,并且这些措施可以被绕过。
|
||||
|
||||
为了有效地减少可能的人为错误,您应该 **提前**准备备份和还原数据的策略.
|
||||
为了有效地减少可能的人为错误,您应该 **提前** 仔细的准备备份和数据还原的策略.
|
||||
|
||||
不同公司有不同的可用资源和业务需求,因此没有适合各种情况的ClickHouse备份和恢复通用解决方案。 适用于 1GB 的数据的方案可能并不适用于几十 PB 数据的情况。 有多种可能的并有自己优缺点的方法,这将在下面讨论。 好的主意是同时结合使用多种方法而不是仅使用一种,这样可以弥补不同方法各自的缺点。
|
||||
不同公司有不同的可用资源和业务需求,因此不存在一个通用的解决方案可以应对各种情况下的ClickHouse备份和恢复。 适用于 1GB 数据的方案可能并不适用于几十 PB 数据的情况。 有多种具备各自优缺点的可能方法,将在下面对其进行讨论。最好使用几种方法而不是仅仅使用一种方法来弥补它们的各种缺点。。
|
||||
|
||||
!!! note "注"
|
||||
请记住,如果您备份了某些内容并且从未尝试过还原它,那么当您实际需要它时(或者至少需要比业务能够容忍的时间更长),恢复可能无法正常工作。 因此,无论您选择哪种备份方法,请确保自动还原过程,并定期在备用ClickHouse群集上练习。
|
||||
需要注意的是,如果您备份了某些内容并且从未尝试过还原它,那么当您实际需要它时可能无法正常恢复(或者至少需要的时间比业务能够容忍的时间更长)。 因此,无论您选择哪种备份方法,请确保自动还原过程,并定期在备用ClickHouse群集上演练。
|
||||
|
||||
## 将源数据复制到其他地方 {#duplicating-source-data-somewhere-else}
|
||||
## 将源数据复制到其它地方 {#duplicating-source-data-somewhere-else}
|
||||
|
||||
通常被聚集到ClickHouse的数据是通过某种持久队列传递的,例如 [Apache Kafka](https://kafka.apache.org). 在这种情况下,可以配置一组额外的订阅服务器,这些订阅服务器将在写入ClickHouse时读取相同的数据流,并将其存储在冷存储中。 大多数公司已经有一些默认的推荐冷存储,可能是对象存储或分布式文件系统,如 [HDFS](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html).
|
||||
通常摄入到ClickHouse的数据是通过某种持久队列传递的,例如 [Apache Kafka] (https://kafka.apache.org). 在这种情况下,可以配置一组额外的订阅服务器,这些订阅服务器将在写入ClickHouse时读取相同的数据流,并将其存储在冷存储中。 大多数公司已经有一些默认推荐的冷存储,可能是对象存储或分布式文件系统,如 [HDFS] (https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html).
|
||||
|
||||
## 文件系统快照 {#filesystem-snapshots}
|
||||
|
||||
某些本地文件系统提供快照功能(例如, [ZFS](https://en.wikipedia.org/wiki/ZFS)),但它们可能不是提供实时查询的最佳选择。 一个可能的解决方案是使用这种文件系统创建额外的副本,并将它们从 [分布](../engines/table-engines/special/distributed.md) 用于以下目的的表 `SELECT` 查询。 任何修改数据的查询都无法访问此类副本上的快照。 作为奖励,这些副本可能具有特殊的硬件配置,每个服务器附加更多的磁盘,这将是经济高效的。
|
||||
某些本地文件系统提供快照功能(例如, [ZFS] (https://en.wikipedia.org/wiki/ZFS)),但它们可能不是提供实时查询的最佳选择。 一个可能的解决方案是使用这种文件系统创建额外的副本,并将它们与用于`SELECT` 查询的 [分布式] (../engines/table-engines/special/distributed.md) 表分离。 任何修改数据的查询都无法访问此类副本上的快照。 作为回报,这些副本可能具有特殊的硬件配置,每个服务器附加更多的磁盘,这将是经济高效的。
|
||||
|
||||
## clickhouse-copier {#clickhouse-copier}
|
||||
|
||||
[clickhouse-copier](utilities/clickhouse-copier.md) 是一个多功能工具,最初创建用于重新分片pb大小的表。 因为它可以在ClickHouse表和集群之间可靠地复制数据,所以它还可用于备份和还原数据。
|
||||
[clickhouse-copier] (utilities/clickhouse-copier.md) 是一个多功能工具,最初创建它是为了用于重新切分pb大小的表。 因为它能够在ClickHouse表和集群之间可靠地复制数据,所以它也可用于备份和还原数据。
|
||||
|
||||
对于较小的数据量,一个简单的 `INSERT INTO ... SELECT ...` 到远程表也可以工作。
|
||||
|
||||
## 部件操作 {#manipulations-with-parts}
|
||||
## part操作 {#manipulations-with-parts}
|
||||
|
||||
ClickHouse允许使用 `ALTER TABLE ... FREEZE PARTITION ...` 查询以创建表分区的本地副本。 这是利用硬链接(hardlink)到 `/var/lib/clickhouse/shadow/` 文件夹中实现的,所以它通常不会占用旧数据的额外磁盘空间。 创建的文件副本不由ClickHouse服务器处理,所以你可以把它们留在那里:你将有一个简单的备份,不需要任何额外的外部系统,但它仍然会容易出现硬件问题。 出于这个原因,最好将它们远程复制到另一个位置,然后删除本地副本。 分布式文件系统和对象存储仍然是一个不错的选择,但是具有足够大容量的正常附加文件服务器也可以工作(在这种情况下,传输将通过网络文件系统 [rsync](https://en.wikipedia.org/wiki/Rsync)).
|
||||
ClickHouse允许使用 `ALTER TABLE ... FREEZE PARTITION ...` 查询以创建表分区的本地副本。 这是利用硬链接(hardlink)到 `/var/lib/clickhouse/shadow/` 文件夹中实现的,所以它通常不会因为旧数据而占用额外的磁盘空间。 创建的文件副本不由ClickHouse服务器处理,所以你可以把它们留在那里:你将有一个简单的备份,不需要任何额外的外部系统,但它仍然容易出现硬件问题。 出于这个原因,最好将它们远程复制到另一个位置,然后删除本地副本。 分布式文件系统和对象存储仍然是一个不错的选择,但是具有足够大容量的正常附加文件服务器也可以工作(在这种情况下,传输将通过网络文件系统或者也许是 [rsync] (https://en.wikipedia.org/wiki/Rsync) 来进行).
|
||||
|
||||
数据可以使用 `ALTER TABLE ... ATTACH PARTITION ...` 从备份中恢复。
|
||||
|
||||
有关与分区操作相关的查询的详细信息,请参阅 [更改文档](../sql-reference/statements/alter.md#alter_manipulations-with-partitions).
|
||||
有关与分区操作相关的查询的详细信息,请参阅 [更改文档] (../sql-reference/statements/alter.md#alter_manipulations-with-partitions).
|
||||
|
||||
第三方工具可用于自动化此方法: [clickhouse-backup](https://github.com/AlexAkulov/clickhouse-backup).
|
||||
第三方工具可用于自动化此方法: [clickhouse-backup] (https://github.com/AlexAkulov/clickhouse-backup).
|
||||
|
||||
[原始文章](https://clickhouse.tech/docs/en/operations/backup/) <!--hide-->
|
||||
[原始文章] (https://clickhouse.tech/docs/en/operations/backup/) <!--hide-->
|
||||
|
@ -5,13 +5,13 @@ machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3
|
||||
|
||||
# 系统。data_type_families {#system_tables-data_type_families}
|
||||
|
||||
包含有关受支持的信息 [数据类型](../../sql-reference/data-types/).
|
||||
包含有关受支持的[数据类型](../../sql-reference/data-types/)的信息.
|
||||
|
||||
列:
|
||||
列字段包括:
|
||||
|
||||
- `name` ([字符串](../../sql-reference/data-types/string.md)) — Data type name.
|
||||
- `case_insensitive` ([UInt8](../../sql-reference/data-types/int-uint.md)) — Property that shows whether you can use a data type name in a query in case insensitive manner or not. For example, `Date` 和 `date` 都是有效的。
|
||||
- `alias_to` ([字符串](../../sql-reference/data-types/string.md)) — Data type name for which `name` 是个化名
|
||||
- `name` ([String](../../sql-reference/data-types/string.md)) — 数据类型的名称.
|
||||
- `case_insensitive` ([UInt8](../../sql-reference/data-types/int-uint.md)) — 该属性显示是否可以在查询中以不区分大小写的方式使用数据类型名称。例如 `Date` 和 `date` 都是有效的。
|
||||
- `alias_to` ([String](../../sql-reference/data-types/string.md)) — 名称为别名的数据类型名称。
|
||||
|
||||
**示例**
|
||||
|
||||
@ -36,4 +36,4 @@ SELECT * FROM system.data_type_families WHERE alias_to = 'String'
|
||||
|
||||
**另请参阅**
|
||||
|
||||
- [语法](../../sql-reference/syntax.md) — Information about supported syntax.
|
||||
- [Syntax](../../sql-reference/syntax.md) — 关于所支持的语法信息.
|
||||
|
@ -7,33 +7,33 @@ toc_title: "\u7CFB\u7EDF\u8868"
|
||||
|
||||
# 系统表 {#system-tables}
|
||||
|
||||
## 导言 {#system-tables-introduction}
|
||||
## 引言 {#system-tables-introduction}
|
||||
|
||||
系统表提供以下信息:
|
||||
系统表提供的信息如下:
|
||||
|
||||
- 服务器状态、进程和环境。
|
||||
- 服务器的状态、进程以及环境。
|
||||
- 服务器的内部进程。
|
||||
|
||||
系统表:
|
||||
|
||||
- 坐落于 `system` 数据库。
|
||||
- 仅适用于读取数据。
|
||||
- 不能删除或更改,但可以分离。
|
||||
- 存储于 `system` 数据库。
|
||||
- 仅提供数据读取功能。
|
||||
- 不能被删除或更改,但可以对其进行分离(detach)操作。
|
||||
|
||||
大多数系统表将数据存储在RAM中。 ClickHouse服务器在开始时创建此类系统表。
|
||||
大多数系统表将其数据存储在RAM中。 一个ClickHouse服务在刚启动时便会创建此类系统表。
|
||||
|
||||
与其他系统表不同,系统日志表 [metric_log](../../operations/system-tables/metric_log.md#system_tables-metric_log), [query_log](../../operations/system-tables/query_log.md#system_tables-query_log), [query_thread_log](../../operations/system-tables/query_thread_log.md#system_tables-query_thread_log), [trace_log](../../operations/system-tables/trace_log.md#system_tables-trace_log), [part_log](../../operations/system-tables/part_log.md#system.part_log), crash_log and text_log 默认采用[MergeTree](../../engines/table-engines/mergetree-family/mergetree.md) 引擎并将其数据存储在存储文件系统中。 如果从文件系统中删除表,ClickHouse服务器会在下一次写入数据时再次创建空表。 如果系统表架构在新版本中发生更改,则ClickHouse会重命名当前表并创建一个新表。
|
||||
不同于其他系统表,系统日志表 [metric_log](../../operations/system-tables/metric_log.md#system_tables-metric_log), [query_log](../../operations/system-tables/query_log.md#system_tables-query_log), [query_thread_log](../../operations/system-tables/query_thread_log.md#system_tables-query_thread_log), [trace_log](../../operations/system-tables/trace_log.md#system_tables-trace_log), [part_log](../../operations/system-tables/part_log.md#system.part_log), crash_log and text_log 默认采用[MergeTree](../../engines/table-engines/mergetree-family/mergetree.md) 引擎并将其数据存储在文件系统中。 如果人为的从文件系统中删除表,ClickHouse服务器会在下一次进行数据写入时再次创建空表。 如果系统表结构在新版本中发生更改,那么ClickHouse会重命名当前表并创建一个新表。
|
||||
|
||||
用户可以通过在`/etc/clickhouse-server/config.d/`下创建与系统表同名的配置文件, 或者在`/etc/clickhouse-server/config.xml`中设置相应配置项,来自定义系统日志表的结构。可以自定义的配置项如下:
|
||||
用户可以通过在`/etc/clickhouse-server/config.d/`下创建与系统表同名的配置文件, 或者在`/etc/clickhouse-server/config.xml`中设置相应配置项,来自定义系统日志表的结构。可供自定义的配置项如下:
|
||||
|
||||
- `database`: 系统日志表所在的数据库。这个选项目前已经废弃。所有的系统日表都位于`system`库中。
|
||||
- `table`: 系统日志表名。
|
||||
- `database`: 系统日志表所在的数据库。这个选项目前已经不推荐使用。所有的系统日表都位于`system`库中。
|
||||
- `table`: 接收数据写入的系统日志表。
|
||||
- `partition_by`: 指定[PARTITION BY](../../engines/table-engines/mergetree-family/custom-partitioning-key.md)表达式。
|
||||
- `ttl`: 指定系统日志表TTL选项。
|
||||
- `flush_interval_milliseconds`: 指定系统日志表数据落盘时间。
|
||||
- `engine`: 指定完整的表引擎定义。(以`ENGINE = `开始)。 这个选项与`partition_by`以及`ttl`冲突。如果两者一起设置,服务启动时会抛出异常并且退出。
|
||||
- `flush_interval_milliseconds`: 指定日志表数据刷新到磁盘的时间间隔。
|
||||
- `engine`: 指定完整的表引擎定义。(以`ENGINE = `开头)。 这个选项与`partition_by`以及`ttl`冲突。如果与两者一起设置,服务启动时会抛出异常并且退出。
|
||||
|
||||
一个配置定义的例子如下:
|
||||
配置定义的示例如下:
|
||||
|
||||
```
|
||||
<yandex>
|
||||
@ -50,20 +50,20 @@ toc_title: "\u7CFB\u7EDF\u8868"
|
||||
</yandex>
|
||||
```
|
||||
|
||||
默认情况下,表增长是无限的。 要控制表的大小,可以使用 TTL 删除过期日志记录的设置。 你也可以使用分区功能 `MergeTree`-发动机表。
|
||||
默认情况下,表增长是无限的。可以通过TTL 删除过期日志记录的设置来控制表的大小。 你也可以使用分区功能 `MergeTree`-引擎表。
|
||||
|
||||
## 系统指标的来源 {#system-tables-sources-of-system-metrics}
|
||||
|
||||
用于收集ClickHouse服务器使用的系统指标:
|
||||
|
||||
- `CAP_NET_ADMIN` 能力。
|
||||
- [procfs](https://en.wikipedia.org/wiki/Procfs) (仅在Linux中)。
|
||||
- [procfs](https://en.wikipedia.org/wiki/Procfs) (仅限于Linux)。
|
||||
|
||||
**procfs**
|
||||
|
||||
如果ClickHouse服务器没有 `CAP_NET_ADMIN` 能力,它试图回落到 `ProcfsMetricsProvider`. `ProcfsMetricsProvider` 允许收集每个查询系统指标(用于CPU和I/O)。
|
||||
如果ClickHouse服务器没有 `CAP_NET_ADMIN` 能力,那么它将试图退回到 `ProcfsMetricsProvider`. `ProcfsMetricsProvider` 允许收集每个查询系统指标(包括CPU和I/O)。
|
||||
|
||||
如果系统上支持并启用procfs,ClickHouse server将收集这些指标:
|
||||
如果系统上支持并启用procfs,ClickHouse server将收集如下指标:
|
||||
|
||||
- `OSCPUVirtualTimeMicroseconds`
|
||||
- `OSCPUWaitMicroseconds`
|
||||
|
@ -5,9 +5,9 @@ toc_priority: 61
|
||||
toc_title: "\u95F4\u9694"
|
||||
---
|
||||
|
||||
# 间隔 {#data-type-interval}
|
||||
# Interval类型 {#data-type-interval}
|
||||
|
||||
表示时间和日期间隔的数据类型族。 由此产生的类型 [INTERVAL](../../../sql-reference/operators/index.md#operator-interval) 接线员
|
||||
表示时间和日期间隔的数据类型家族。 [INTERVAL](../../../sql-reference/operators/index.md#operator-interval) 运算的结果类型。
|
||||
|
||||
!!! warning "警告"
|
||||
`Interval` 数据类型值不能存储在表中。
|
||||
@ -15,7 +15,7 @@ toc_title: "\u95F4\u9694"
|
||||
结构:
|
||||
|
||||
- 时间间隔作为无符号整数值。
|
||||
- 间隔的类型。
|
||||
- 时间间隔的类型。
|
||||
|
||||
支持的时间间隔类型:
|
||||
|
||||
@ -28,7 +28,7 @@ toc_title: "\u95F4\u9694"
|
||||
- `QUARTER`
|
||||
- `YEAR`
|
||||
|
||||
对于每个间隔类型,都有一个单独的数据类型。 例如, `DAY` 间隔对应于 `IntervalDay` 数据类型:
|
||||
对于每个时间间隔类型,都有一个单独的数据类型。 例如, `DAY` 间隔对应于 `IntervalDay` 数据类型:
|
||||
|
||||
``` sql
|
||||
SELECT toTypeName(INTERVAL 4 DAY)
|
||||
@ -42,7 +42,7 @@ SELECT toTypeName(INTERVAL 4 DAY)
|
||||
|
||||
## 使用说明 {#data-type-interval-usage-remarks}
|
||||
|
||||
您可以使用 `Interval`-在算术运算类型值 [日期](../../../sql-reference/data-types/date.md) 和 [日期时间](../../../sql-reference/data-types/datetime.md)-类型值。 例如,您可以将4天添加到当前时间:
|
||||
您可以在与 [日期](../../../sql-reference/data-types/date.md) 和 [日期时间](../../../sql-reference/data-types/datetime.md) 类型值的算术运算中使用 `Interval` 类型值。 例如,您可以将4天添加到当前时间:
|
||||
|
||||
``` sql
|
||||
SELECT now() as current_date_time, current_date_time + INTERVAL 4 DAY
|
||||
@ -54,10 +54,10 @@ SELECT now() as current_date_time, current_date_time + INTERVAL 4 DAY
|
||||
└─────────────────────┴───────────────────────────────┘
|
||||
```
|
||||
|
||||
不同类型的间隔不能合并。 你不能使用间隔,如 `4 DAY 1 HOUR`. 以小于或等于间隔的最小单位的单位指定间隔,例如,间隔 `1 day and an hour` 间隔可以表示为 `25 HOUR` 或 `90000 SECOND`.
|
||||
|
||||
你不能执行算术运算 `Interval`-类型值,但你可以添加不同类型的时间间隔,因此值 `Date` 或 `DateTime` 数据类型。 例如:
|
||||
不同类型的间隔不能合并。 你不能使用诸如 `4 DAY 1 HOUR` 的时间间隔. 以小于或等于时间间隔最小单位的单位来指定间隔,例如,时间间隔 `1 day and an hour` 可以表示为 `25 HOUR` 或 `90000 SECOND`.
|
||||
|
||||
你不能对 `Interval` 类型的值执行算术运算,但你可以向 `Date` 或 `DateTime` 数据类型的值添加不同类型的时间间隔,例如:
|
||||
|
||||
``` sql
|
||||
SELECT now() AS current_date_time, current_date_time + INTERVAL 4 DAY + INTERVAL 3 HOUR
|
||||
```
|
||||
@ -81,5 +81,5 @@ Code: 43. DB::Exception: Received from localhost:9000. DB::Exception: Wrong argu
|
||||
|
||||
## 另请参阅 {#see-also}
|
||||
|
||||
- [INTERVAL](../../../sql-reference/operators/index.md#operator-interval) 接线员
|
||||
- [INTERVAL](../../../sql-reference/operators/index.md#operator-interval) 操作
|
||||
- [toInterval](../../../sql-reference/functions/type-conversion-functions.md#function-tointerval) 类型转换函数
|
||||
|
@ -8,15 +8,15 @@ toc_title: "\u5BFC\u8A00"
|
||||
|
||||
# 字典 {#dictionaries}
|
||||
|
||||
字典是一个映射 (`key -> attributes`)这是方便各种类型的参考清单。
|
||||
字典是一个映射 (`键 -> 属性`), 是方便各种类型的参考清单。
|
||||
|
||||
ClickHouse支持使用可用于查询的字典的特殊功能。 这是更容易和更有效地使用字典与功能比 `JOIN` 与参考表。
|
||||
ClickHouse支持一些特殊函数配合字典在查询中使用。 将字典与函数结合使用比将 `JOIN` 操作与引用表结合使用更简单、更有效。
|
||||
|
||||
[NULL](../../sql-reference/syntax.md#null-literal) 值不能存储在字典中。
|
||||
|
||||
ClickHouse支持:
|
||||
|
||||
- [内置字典](internal-dicts.md#internal_dicts) 具有特定的 [功能集](../../sql-reference/functions/ym-dict-functions.md).
|
||||
- [插件(外部)字典](external-dictionaries/external-dicts.md#dicts-external-dicts) 用一个 [功能集](../../sql-reference/functions/ext-dict-functions.md).
|
||||
- [内置字典](internal-dicts.md#internal_dicts) ,这些字典具有特定的 [函数集](../../sql-reference/functions/ym-dict-functions.md).
|
||||
- [插件(外部)字典](external-dictionaries/external-dicts.md#dicts-external-dicts) ,这些字典拥有一个 [函数集](../../sql-reference/functions/ext-dict-functions.md).
|
||||
|
||||
[原始文章](https://clickhouse.tech/docs/en/query_language/dicts/) <!--hide-->
|
||||
|
@ -238,7 +238,7 @@ SELECT a, b, c FROM (SELECT ...)
|
||||
|
||||
当一个`SELECT`子句包含`DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`时,请注意,这些仅会在插入数据时在每个单独的数据块上执行。例如,如果你在其中包含了`GROUP BY`,则只会在查询期间进行聚合,但聚合范围仅限于单个批的写入数据。数据不会进一步被聚合。但是当你使用一些其他数据聚合引擎时这是例外的,如:`SummingMergeTree`。
|
||||
|
||||
目前对物化视图执行`ALTER`是不支持的,因此这可能是不方便的。如果物化视图是使用的`TO [db.]name`的方式进行构建的,你可以使用`DETACH`语句现将视图剥离,然后使用`ALTER`运行在目标表上,然后使用`ATTACH`将之前剥离的表重新加载进来。
|
||||
目前对物化视图执行`ALTER`是不支持的,因此这可能是不方便的。如果物化视图是使用的`TO [db.]name`的方式进行构建的,你可以使用`DETACH`语句先将视图剥离,然后使用`ALTER`运行在目标表上,然后使用`ATTACH`将之前剥离的表重新加载进来。
|
||||
|
||||
视图看起来和普通的表相同。例如,你可以通过`SHOW TABLES`查看到它们。
|
||||
|
||||
|
@ -14,7 +14,7 @@ INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def')
|
||||
|
||||
含`INSERT INTO t VALUES` 的部分由完整SQL解析器处理,包含数据的部分 `(1, 'Hello, world'), (2, 'abc'), (3, 'def')` 交给快速流式解析器解析。通过设置参数 [input_format_values_interpret_expressions](../operations/settings/settings.md#settings-input_format_values_interpret_expressions),你也可以对数据部分开启完整SQL解析器。当 `input_format_values_interpret_expressions = 1` 时,CH优先采用快速流式解析器来解析数据。如果失败,CH再尝试用完整SQL解析器来处理,就像处理SQL [expression](#syntax-expressions) 一样。
|
||||
|
||||
数据可以采用任何格式。当CH接受到请求时,服务端先在内存中计算不超过 [max_query_size](../operations/settings/settings.md#settings-max_query_size) 字节的请求数据(默认1 mb),然后剩下部分交给快速流式解析器。
|
||||
数据可以采用任何格式。当CH接收到请求时,服务端先在内存中计算不超过 [max_query_size](../operations/settings/settings.md#settings-max_query_size) 字节的请求数据(默认1 mb),然后剩下部分交给快速流式解析器。
|
||||
|
||||
这将避免在处理大型的 `INSERT`语句时出现问题。
|
||||
|
||||
|
@ -47,6 +47,15 @@ option (ENABLE_CLICKHOUSE_LIBRARY_BRIDGE "HTTP-server working like a proxy to Li
|
||||
option (ENABLE_CLICKHOUSE_GIT_IMPORT "A tool to analyze Git repositories"
|
||||
${ENABLE_CLICKHOUSE_ALL})
|
||||
|
||||
|
||||
option (ENABLE_CLICKHOUSE_KEEPER "ClickHouse alternative to ZooKeeper" ${ENABLE_CLICKHOUSE_ALL})
|
||||
if (NOT USE_NURAFT)
|
||||
# RECONFIGURE_MESSAGE_LEVEL should not be used here,
|
||||
# since USE_NURAFT is set to OFF for FreeBSD and Darwin.
|
||||
message (STATUS "clickhouse-keeper will not be built (lack of NuRaft)")
|
||||
set(ENABLE_CLICKHOUSE_KEEPER OFF)
|
||||
endif()
|
||||
|
||||
if (CLICKHOUSE_SPLIT_BINARY)
|
||||
option(ENABLE_CLICKHOUSE_INSTALL "Install ClickHouse without .deb/.rpm/.tgz packages (having the binary only)" OFF)
|
||||
else ()
|
||||
@ -134,6 +143,12 @@ else()
|
||||
message(STATUS "ClickHouse git-import: OFF")
|
||||
endif()
|
||||
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
message(STATUS "ClickHouse keeper mode: ON")
|
||||
else()
|
||||
message(STATUS "ClickHouse keeper mode: OFF")
|
||||
endif()
|
||||
|
||||
if(NOT (MAKE_STATIC_LIBRARIES OR SPLIT_SHARED_LIBRARIES))
|
||||
set(CLICKHOUSE_ONE_SHARED ON)
|
||||
endif()
|
||||
@ -189,6 +204,54 @@ macro(clickhouse_program_add name)
|
||||
clickhouse_program_add_executable(${name})
|
||||
endmacro()
|
||||
|
||||
# Embed default config files as a resource into the binary.
|
||||
# This is needed for two purposes:
|
||||
# 1. Allow to run the binary without download of any other files.
|
||||
# 2. Allow to implement "sudo clickhouse install" tool.
|
||||
#
|
||||
# Arguments: target (server, client, keeper, etc.) and list of files
|
||||
#
|
||||
# Also dependency on TARGET_FILE is required, look at examples in programs/server and programs/keeper
|
||||
macro(clickhouse_embed_binaries)
|
||||
# TODO We actually need this on Mac, FreeBSD.
|
||||
if (OS_LINUX)
|
||||
|
||||
set(arguments_list "${ARGN}")
|
||||
list(GET arguments_list 0 target)
|
||||
|
||||
# for some reason cmake iterates loop including <stop>
|
||||
math(EXPR arguments_count "${ARGC}-1")
|
||||
|
||||
foreach(RESOURCE_POS RANGE 1 "${arguments_count}")
|
||||
list(GET arguments_list "${RESOURCE_POS}" RESOURCE_FILE)
|
||||
set(RESOURCE_OBJ ${RESOURCE_FILE}.o)
|
||||
set(RESOURCE_OBJS ${RESOURCE_OBJS} ${RESOURCE_OBJ})
|
||||
|
||||
# https://stackoverflow.com/questions/14776463/compile-and-add-an-object-file-from-a-binary-with-cmake
|
||||
# PPC64LE fails to do this with objcopy, use ld or lld instead
|
||||
if (ARCH_PPC64LE)
|
||||
add_custom_command(OUTPUT ${RESOURCE_OBJ}
|
||||
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf64lppc -r -b binary -o "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_OBJ}" ${RESOURCE_FILE})
|
||||
else()
|
||||
add_custom_command(OUTPUT ${RESOURCE_OBJ}
|
||||
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${OBJCOPY_PATH} -I binary ${OBJCOPY_ARCH_OPTIONS} ${RESOURCE_FILE} "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_OBJ}"
|
||||
COMMAND ${OBJCOPY_PATH} --rename-section .data=.rodata,alloc,load,readonly,data,contents
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_OBJ}" "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_OBJ}")
|
||||
endif()
|
||||
set_source_files_properties(${RESOURCE_OBJ} PROPERTIES EXTERNAL_OBJECT true GENERATED true)
|
||||
endforeach()
|
||||
|
||||
add_library(clickhouse_${target}_configs STATIC ${RESOURCE_OBJS})
|
||||
set_target_properties(clickhouse_${target}_configs PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
# whole-archive prevents symbols from being discarded for unknown reason
|
||||
# CMake can shuffle each of target_link_libraries arguments with other
|
||||
# libraries in linker command. To avoid this we hardcode whole-archive
|
||||
# library into single string.
|
||||
add_dependencies(clickhouse-${target}-lib clickhouse_${target}_configs)
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
|
||||
add_subdirectory (server)
|
||||
add_subdirectory (client)
|
||||
@ -203,6 +266,10 @@ add_subdirectory (install)
|
||||
add_subdirectory (git-import)
|
||||
add_subdirectory (bash-completion)
|
||||
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
add_subdirectory (keeper)
|
||||
endif()
|
||||
|
||||
if (ENABLE_CLICKHOUSE_ODBC_BRIDGE)
|
||||
add_subdirectory (odbc-bridge)
|
||||
endif ()
|
||||
@ -212,15 +279,26 @@ if (ENABLE_CLICKHOUSE_LIBRARY_BRIDGE)
|
||||
endif ()
|
||||
|
||||
if (CLICKHOUSE_ONE_SHARED)
|
||||
add_library(clickhouse-lib SHARED ${CLICKHOUSE_SERVER_SOURCES} ${CLICKHOUSE_CLIENT_SOURCES} ${CLICKHOUSE_LOCAL_SOURCES} ${CLICKHOUSE_BENCHMARK_SOURCES} ${CLICKHOUSE_COPIER_SOURCES} ${CLICKHOUSE_EXTRACT_FROM_CONFIG_SOURCES} ${CLICKHOUSE_COMPRESSOR_SOURCES} ${CLICKHOUSE_FORMAT_SOURCES} ${CLICKHOUSE_OBFUSCATOR_SOURCES} ${CLICKHOUSE_GIT_IMPORT_SOURCES} ${CLICKHOUSE_ODBC_BRIDGE_SOURCES})
|
||||
target_link_libraries(clickhouse-lib ${CLICKHOUSE_SERVER_LINK} ${CLICKHOUSE_CLIENT_LINK} ${CLICKHOUSE_LOCAL_LINK} ${CLICKHOUSE_BENCHMARK_LINK} ${CLICKHOUSE_COPIER_LINK} ${CLICKHOUSE_EXTRACT_FROM_CONFIG_LINK} ${CLICKHOUSE_COMPRESSOR_LINK} ${CLICKHOUSE_FORMAT_LINK} ${CLICKHOUSE_OBFUSCATOR_LINK} ${CLICKHOUSE_GIT_IMPORT_LINK} ${CLICKHOUSE_ODBC_BRIDGE_LINK})
|
||||
target_include_directories(clickhouse-lib ${CLICKHOUSE_SERVER_INCLUDE} ${CLICKHOUSE_CLIENT_INCLUDE} ${CLICKHOUSE_LOCAL_INCLUDE} ${CLICKHOUSE_BENCHMARK_INCLUDE} ${CLICKHOUSE_COPIER_INCLUDE} ${CLICKHOUSE_EXTRACT_FROM_CONFIG_INCLUDE} ${CLICKHOUSE_COMPRESSOR_INCLUDE} ${CLICKHOUSE_FORMAT_INCLUDE} ${CLICKHOUSE_OBFUSCATOR_INCLUDE} ${CLICKHOUSE_GIT_IMPORT_INCLUDE} ${CLICKHOUSE_ODBC_BRIDGE_INCLUDE})
|
||||
add_library(clickhouse-lib SHARED ${CLICKHOUSE_SERVER_SOURCES} ${CLICKHOUSE_CLIENT_SOURCES} ${CLICKHOUSE_LOCAL_SOURCES} ${CLICKHOUSE_BENCHMARK_SOURCES} ${CLICKHOUSE_COPIER_SOURCES} ${CLICKHOUSE_EXTRACT_FROM_CONFIG_SOURCES} ${CLICKHOUSE_COMPRESSOR_SOURCES} ${CLICKHOUSE_FORMAT_SOURCES} ${CLICKHOUSE_OBFUSCATOR_SOURCES} ${CLICKHOUSE_GIT_IMPORT_SOURCES} ${CLICKHOUSE_ODBC_BRIDGE_SOURCES} ${CLICKHOUSE_KEEPER_SOURCES})
|
||||
target_link_libraries(clickhouse-lib ${CLICKHOUSE_SERVER_LINK} ${CLICKHOUSE_CLIENT_LINK} ${CLICKHOUSE_LOCAL_LINK} ${CLICKHOUSE_BENCHMARK_LINK} ${CLICKHOUSE_COPIER_LINK} ${CLICKHOUSE_EXTRACT_FROM_CONFIG_LINK} ${CLICKHOUSE_COMPRESSOR_LINK} ${CLICKHOUSE_FORMAT_LINK} ${CLICKHOUSE_OBFUSCATOR_LINK} ${CLICKHOUSE_GIT_IMPORT_LINK} ${CLICKHOUSE_ODBC_BRIDGE_LINK} ${CLICKHOUSE_KEEPER_LINK})
|
||||
target_include_directories(clickhouse-lib ${CLICKHOUSE_SERVER_INCLUDE} ${CLICKHOUSE_CLIENT_INCLUDE} ${CLICKHOUSE_LOCAL_INCLUDE} ${CLICKHOUSE_BENCHMARK_INCLUDE} ${CLICKHOUSE_COPIER_INCLUDE} ${CLICKHOUSE_EXTRACT_FROM_CONFIG_INCLUDE} ${CLICKHOUSE_COMPRESSOR_INCLUDE} ${CLICKHOUSE_FORMAT_INCLUDE} ${CLICKHOUSE_OBFUSCATOR_INCLUDE} ${CLICKHOUSE_GIT_IMPORT_INCLUDE} ${CLICKHOUSE_ODBC_BRIDGE_INCLUDE} ${CLICKHOUSE_KEEPER_INCLUDE})
|
||||
set_target_properties(clickhouse-lib PROPERTIES SOVERSION ${VERSION_MAJOR}.${VERSION_MINOR} VERSION ${VERSION_SO} OUTPUT_NAME clickhouse DEBUG_POSTFIX "")
|
||||
install (TARGETS clickhouse-lib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT clickhouse)
|
||||
endif()
|
||||
|
||||
if (CLICKHOUSE_SPLIT_BINARY)
|
||||
set (CLICKHOUSE_ALL_TARGETS clickhouse-server clickhouse-client clickhouse-local clickhouse-benchmark clickhouse-extract-from-config clickhouse-compressor clickhouse-format clickhouse-obfuscator clickhouse-git-import clickhouse-copier)
|
||||
set (CLICKHOUSE_ALL_TARGETS
|
||||
clickhouse-server
|
||||
clickhouse-client
|
||||
clickhouse-local
|
||||
clickhouse-benchmark
|
||||
clickhouse-extract-from-config
|
||||
clickhouse-compressor
|
||||
clickhouse-format
|
||||
clickhouse-obfuscator
|
||||
clickhouse-git-import
|
||||
clickhouse-copier
|
||||
)
|
||||
|
||||
if (ENABLE_CLICKHOUSE_ODBC_BRIDGE)
|
||||
list (APPEND CLICKHOUSE_ALL_TARGETS clickhouse-odbc-bridge)
|
||||
@ -230,6 +308,10 @@ if (CLICKHOUSE_SPLIT_BINARY)
|
||||
list (APPEND CLICKHOUSE_ALL_TARGETS clickhouse-library-bridge)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
list (APPEND CLICKHOUSE_ALL_TARGETS clickhouse-keeper)
|
||||
endif ()
|
||||
|
||||
set_target_properties(${CLICKHOUSE_ALL_TARGETS} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ..)
|
||||
|
||||
add_custom_target (clickhouse-bundle ALL DEPENDS ${CLICKHOUSE_ALL_TARGETS})
|
||||
@ -277,6 +359,9 @@ else ()
|
||||
if (ENABLE_CLICKHOUSE_GIT_IMPORT)
|
||||
clickhouse_target_link_split_lib(clickhouse git-import)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
clickhouse_target_link_split_lib(clickhouse keeper)
|
||||
endif()
|
||||
if (ENABLE_CLICKHOUSE_INSTALL)
|
||||
clickhouse_target_link_split_lib(clickhouse install)
|
||||
endif ()
|
||||
@ -332,6 +417,11 @@ else ()
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-git-import" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-git-import)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
add_custom_target (clickhouse-keeper ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-keeper DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-keeper" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-keeper)
|
||||
endif ()
|
||||
|
||||
install (TARGETS clickhouse RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
|
||||
|
@ -1366,6 +1366,27 @@ private:
|
||||
{
|
||||
const auto * exception = server_exception ? server_exception.get() : client_exception.get();
|
||||
fmt::print(stderr, "Error on processing query '{}': {}\n", ast_to_process->formatForErrorMessage(), exception->message());
|
||||
|
||||
// Try to reconnect after errors, for two reasons:
|
||||
// 1. We might not have realized that the server died, e.g. if
|
||||
// it sent us a <Fatal> trace and closed connection properly.
|
||||
// 2. The connection might have gotten into a wrong state and
|
||||
// the next query will get false positive about
|
||||
// "Unknown packet from server".
|
||||
try
|
||||
{
|
||||
connection->forceConnected(connection_parameters.timeouts);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Just report it, we'll terminate below.
|
||||
fmt::print(stderr,
|
||||
"Error while reconnecting to the server: Code: {}: {}\n",
|
||||
getCurrentExceptionCode(),
|
||||
getCurrentExceptionMessage(true));
|
||||
|
||||
assert(!connection->isConnected());
|
||||
}
|
||||
}
|
||||
|
||||
if (!connection->isConnected())
|
||||
@ -1469,11 +1490,6 @@ private:
|
||||
server_exception.reset();
|
||||
client_exception.reset();
|
||||
have_error = false;
|
||||
|
||||
// We have to reinitialize connection after errors, because it
|
||||
// might have gotten into a wrong state and we'll get false
|
||||
// positives about "Unknown packet from server".
|
||||
connection->forceConnected(connection_parameters.timeouts);
|
||||
}
|
||||
else if (ast_to_process->formatForErrorMessage().size() > 500)
|
||||
{
|
||||
@ -2278,7 +2294,7 @@ private:
|
||||
size_t elapsed_ns = watch.elapsed();
|
||||
if (elapsed_ns)
|
||||
std::cout << " (" << formatReadableQuantity(progress.read_rows * 1000000000.0 / elapsed_ns) << " rows/s., "
|
||||
<< formatReadableSizeWithDecimalSuffix(progress.read_bytes * 1000000000.0 / elapsed_ns) << "/s.) ";
|
||||
<< formatReadableSizeWithDecimalSuffix(progress.read_bytes * 1000000000.0 / elapsed_ns) << "/s.)";
|
||||
else
|
||||
std::cout << ". ";
|
||||
}
|
||||
|
@ -16,3 +16,4 @@
|
||||
#cmakedefine01 ENABLE_CLICKHOUSE_INSTALL
|
||||
#cmakedefine01 ENABLE_CLICKHOUSE_ODBC_BRIDGE
|
||||
#cmakedefine01 ENABLE_CLICKHOUSE_LIBRARY_BRIDGE
|
||||
#cmakedefine01 ENABLE_CLICKHOUSE_KEEPER
|
||||
|
@ -983,7 +983,7 @@ int mainEntryClickHouseStop(int argc, char ** argv)
|
||||
desc.add_options()
|
||||
("help,h", "produce help message")
|
||||
("pid-path", po::value<std::string>()->default_value("/var/run/clickhouse-server"), "directory for pid file")
|
||||
("force", po::value<bool>()->default_value(false), "Stop with KILL signal instead of TERM")
|
||||
("force", po::bool_switch(), "Stop with KILL signal instead of TERM")
|
||||
;
|
||||
|
||||
po::variables_map options;
|
||||
|
24
programs/keeper/CMakeLists.txt
Normal file
24
programs/keeper/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
set(CLICKHOUSE_KEEPER_SOURCES
|
||||
Keeper.cpp
|
||||
)
|
||||
|
||||
if (OS_LINUX)
|
||||
set (LINK_RESOURCE_LIB INTERFACE "-Wl,${WHOLE_ARCHIVE} $<TARGET_FILE:clickhouse_keeper_configs> -Wl,${NO_WHOLE_ARCHIVE}")
|
||||
endif ()
|
||||
|
||||
set (CLICKHOUSE_KEEPER_LINK
|
||||
PRIVATE
|
||||
clickhouse_common_config
|
||||
clickhouse_common_io
|
||||
clickhouse_common_zookeeper
|
||||
daemon
|
||||
dbms
|
||||
|
||||
${LINK_RESOURCE_LIB}
|
||||
)
|
||||
|
||||
clickhouse_program_add(keeper)
|
||||
|
||||
install (FILES keeper_config.xml DESTINATION "${CLICKHOUSE_ETC_DIR}/clickhouse-keeper" COMPONENT clickhouse-keeper)
|
||||
|
||||
clickhouse_embed_binaries(keeper keeper_config.xml keeper_embedded.xml)
|
468
programs/keeper/Keeper.cpp
Normal file
468
programs/keeper/Keeper.cpp
Normal file
@ -0,0 +1,468 @@
|
||||
#include "Keeper.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <Common/ClickHouseRevision.h>
|
||||
#include <Server/ProtocolServerAdapter.h>
|
||||
#include <Common/DNSResolver.h>
|
||||
#include <Interpreters/DNSCacheUpdater.h>
|
||||
#include <Poco/Net/NetException.h>
|
||||
#include <Poco/Net/TCPServerParams.h>
|
||||
#include <Poco/Net/TCPServer.h>
|
||||
#include <common/defines.h>
|
||||
#include <common/logger_useful.h>
|
||||
#include <common/ErrorHandlers.h>
|
||||
#include <ext/scope_guard.h>
|
||||
#include <Poco/Util/HelpFormatter.h>
|
||||
#include <Poco/Version.h>
|
||||
#include <Poco/Environment.h>
|
||||
#include <Common/getMultipleKeysFromConfig.h>
|
||||
#include <filesystem>
|
||||
#include <IO/UseSSL.h>
|
||||
|
||||
#if !defined(ARCADIA_BUILD)
|
||||
# include "config_core.h"
|
||||
# include "Common/config_version.h"
|
||||
#endif
|
||||
|
||||
#if USE_SSL
|
||||
# include <Poco/Net/Context.h>
|
||||
# include <Poco/Net/SecureServerSocket.h>
|
||||
#endif
|
||||
|
||||
#include <Server/KeeperTCPHandlerFactory.h>
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
# include <unistd.h>
|
||||
# include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
|
||||
int mainEntryClickHouseKeeper(int argc, char ** argv)
|
||||
{
|
||||
DB::Keeper app;
|
||||
|
||||
try
|
||||
{
|
||||
return app.run(argc, argv);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << DB::getCurrentExceptionMessage(true) << "\n";
|
||||
auto code = DB::getCurrentExceptionCode();
|
||||
return code ? code : 1;
|
||||
}
|
||||
}
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int NO_ELEMENTS_IN_CONFIG;
|
||||
extern const int SUPPORT_IS_DISABLED;
|
||||
extern const int NETWORK_ERROR;
|
||||
extern const int MISMATCHING_USERS_FOR_PROCESS_AND_DATA;
|
||||
extern const int FAILED_TO_GETPWUID;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int waitServersToFinish(std::vector<DB::ProtocolServerAdapter> & servers, size_t seconds_to_wait)
|
||||
{
|
||||
const int sleep_max_ms = 1000 * seconds_to_wait;
|
||||
const int sleep_one_ms = 100;
|
||||
int sleep_current_ms = 0;
|
||||
int current_connections = 0;
|
||||
for (;;)
|
||||
{
|
||||
current_connections = 0;
|
||||
|
||||
for (auto & server : servers)
|
||||
{
|
||||
server.stop();
|
||||
current_connections += server.currentConnections();
|
||||
}
|
||||
|
||||
if (!current_connections)
|
||||
break;
|
||||
|
||||
sleep_current_ms += sleep_one_ms;
|
||||
if (sleep_current_ms < sleep_max_ms)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_one_ms));
|
||||
else
|
||||
break;
|
||||
}
|
||||
return current_connections;
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress makeSocketAddress(const std::string & host, UInt16 port, Poco::Logger * log)
|
||||
{
|
||||
Poco::Net::SocketAddress socket_address;
|
||||
try
|
||||
{
|
||||
socket_address = Poco::Net::SocketAddress(host, port);
|
||||
}
|
||||
catch (const Poco::Net::DNSException & e)
|
||||
{
|
||||
const auto code = e.code();
|
||||
if (code == EAI_FAMILY
|
||||
#if defined(EAI_ADDRFAMILY)
|
||||
|| code == EAI_ADDRFAMILY
|
||||
#endif
|
||||
)
|
||||
{
|
||||
LOG_ERROR(log, "Cannot resolve listen_host ({}), error {}: {}. "
|
||||
"If it is an IPv6 address and your host has disabled IPv6, then consider to "
|
||||
"specify IPv4 address to listen in <listen_host> element of configuration "
|
||||
"file. Example: <listen_host>0.0.0.0</listen_host>",
|
||||
host, e.code(), e.message());
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
return socket_address;
|
||||
}
|
||||
|
||||
[[noreturn]] void forceShutdown()
|
||||
{
|
||||
#if defined(THREAD_SANITIZER) && defined(OS_LINUX)
|
||||
/// Thread sanitizer tries to do something on exit that we don't need if we want to exit immediately,
|
||||
/// while connection handling threads are still run.
|
||||
(void)syscall(SYS_exit_group, 0);
|
||||
__builtin_unreachable();
|
||||
#else
|
||||
_exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string getUserName(uid_t user_id)
|
||||
{
|
||||
/// Try to convert user id into user name.
|
||||
auto buffer_size = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (buffer_size <= 0)
|
||||
buffer_size = 1024;
|
||||
std::string buffer;
|
||||
buffer.reserve(buffer_size);
|
||||
|
||||
struct passwd passwd_entry;
|
||||
struct passwd * result = nullptr;
|
||||
const auto error = getpwuid_r(user_id, &passwd_entry, buffer.data(), buffer_size, &result);
|
||||
|
||||
if (error)
|
||||
throwFromErrno("Failed to find user name for " + toString(user_id), ErrorCodes::FAILED_TO_GETPWUID, error);
|
||||
else if (result)
|
||||
return result->pw_name;
|
||||
return toString(user_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress Keeper::socketBindListen(Poco::Net::ServerSocket & socket, const std::string & host, UInt16 port, [[maybe_unused]] bool secure) const
|
||||
{
|
||||
auto address = makeSocketAddress(host, port, &logger());
|
||||
#if !defined(POCO_CLICKHOUSE_PATCH) || POCO_VERSION < 0x01090100
|
||||
if (secure)
|
||||
/// Bug in old (<1.9.1) poco, listen() after bind() with reusePort param will fail because have no implementation in SecureServerSocketImpl
|
||||
/// https://github.com/pocoproject/poco/pull/2257
|
||||
socket.bind(address, /* reuseAddress = */ true);
|
||||
else
|
||||
#endif
|
||||
#if POCO_VERSION < 0x01080000
|
||||
socket.bind(address, /* reuseAddress = */ true);
|
||||
#else
|
||||
socket.bind(address, /* reuseAddress = */ true, /* reusePort = */ config().getBool("listen_reuse_port", false));
|
||||
#endif
|
||||
|
||||
socket.listen(/* backlog = */ config().getUInt("listen_backlog", 64));
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
void Keeper::createServer(const std::string & listen_host, const char * port_name, bool listen_try, CreateServerFunc && func) const
|
||||
{
|
||||
/// For testing purposes, user may omit tcp_port or http_port or https_port in configuration file.
|
||||
if (!config().has(port_name))
|
||||
return;
|
||||
|
||||
auto port = config().getInt(port_name);
|
||||
try
|
||||
{
|
||||
func(port);
|
||||
}
|
||||
catch (const Poco::Exception &)
|
||||
{
|
||||
std::string message = "Listen [" + listen_host + "]:" + std::to_string(port) + " failed: " + getCurrentExceptionMessage(false);
|
||||
|
||||
if (listen_try)
|
||||
{
|
||||
LOG_WARNING(&logger(), "{}. If it is an IPv6 or IPv4 address and your host has disabled IPv6 or IPv4, then consider to "
|
||||
"specify not disabled IPv4 or IPv6 address to listen in <listen_host> element of configuration "
|
||||
"file. Example for disabled IPv6: <listen_host>0.0.0.0</listen_host> ."
|
||||
" Example for disabled IPv4: <listen_host>::</listen_host>",
|
||||
message);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception{message, ErrorCodes::NETWORK_ERROR};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Keeper::uninitialize()
|
||||
{
|
||||
logger().information("shutting down");
|
||||
BaseDaemon::uninitialize();
|
||||
}
|
||||
|
||||
int Keeper::run()
|
||||
{
|
||||
if (config().hasOption("help"))
|
||||
{
|
||||
Poco::Util::HelpFormatter help_formatter(Keeper::options());
|
||||
auto header_str = fmt::format("{} [OPTION] [-- [ARG]...]\n"
|
||||
"positional arguments can be used to rewrite config.xml properties, for example, --http_port=8010",
|
||||
commandName());
|
||||
help_formatter.setHeader(header_str);
|
||||
help_formatter.format(std::cout);
|
||||
return 0;
|
||||
}
|
||||
if (config().hasOption("version"))
|
||||
{
|
||||
std::cout << DBMS_NAME << " keeper version " << VERSION_STRING << VERSION_OFFICIAL << "." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Application::run(); // NOLINT
|
||||
}
|
||||
|
||||
void Keeper::initialize(Poco::Util::Application & self)
|
||||
{
|
||||
BaseDaemon::initialize(self);
|
||||
logger().information("starting up");
|
||||
|
||||
LOG_INFO(&logger(), "OS Name = {}, OS Version = {}, OS Architecture = {}",
|
||||
Poco::Environment::osName(),
|
||||
Poco::Environment::osVersion(),
|
||||
Poco::Environment::osArchitecture());
|
||||
}
|
||||
|
||||
std::string Keeper::getDefaultConfigFileName() const
|
||||
{
|
||||
return "keeper_config.xml";
|
||||
}
|
||||
|
||||
void Keeper::defineOptions(Poco::Util::OptionSet & options)
|
||||
{
|
||||
options.addOption(
|
||||
Poco::Util::Option("help", "h", "show help and exit")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.binding("help"));
|
||||
options.addOption(
|
||||
Poco::Util::Option("version", "V", "show version and exit")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.binding("version"));
|
||||
BaseDaemon::defineOptions(options);
|
||||
}
|
||||
|
||||
int Keeper::main(const std::vector<std::string> & /*args*/)
|
||||
{
|
||||
Poco::Logger * log = &logger();
|
||||
|
||||
UseSSL use_ssl;
|
||||
|
||||
MainThreadStatus::getInstance();
|
||||
|
||||
#if !defined(NDEBUG) || !defined(__OPTIMIZE__)
|
||||
LOG_WARNING(log, "Keeper was built in debug mode. It will work slowly.");
|
||||
#endif
|
||||
|
||||
#if defined(SANITIZER)
|
||||
LOG_WARNING(log, "Keeper was built with sanitizer. It will work slowly.");
|
||||
#endif
|
||||
|
||||
auto shared_context = Context::createShared();
|
||||
global_context = Context::createGlobal(shared_context.get());
|
||||
|
||||
global_context->makeGlobalContext();
|
||||
global_context->setApplicationType(Context::ApplicationType::KEEPER);
|
||||
|
||||
if (!config().has("keeper_server"))
|
||||
throw Exception(ErrorCodes::NO_ELEMENTS_IN_CONFIG, "Keeper configuration (<keeper_server> section) not found in config");
|
||||
|
||||
|
||||
std::string path;
|
||||
|
||||
if (config().has("keeper_server.storage_path"))
|
||||
path = config().getString("keeper_server.storage_path");
|
||||
else if (config().has("keeper_server.log_storage_path"))
|
||||
path = config().getString("keeper_server.log_storage_path");
|
||||
else if (config().has("keeper_server.snapshot_storage_path"))
|
||||
path = config().getString("keeper_server.snapshot_storage_path");
|
||||
else
|
||||
path = std::filesystem::path{KEEPER_DEFAULT_PATH};
|
||||
|
||||
|
||||
/// Check that the process user id matches the owner of the data.
|
||||
const auto effective_user_id = geteuid();
|
||||
struct stat statbuf;
|
||||
if (stat(path.c_str(), &statbuf) == 0 && effective_user_id != statbuf.st_uid)
|
||||
{
|
||||
const auto effective_user = getUserName(effective_user_id);
|
||||
const auto data_owner = getUserName(statbuf.st_uid);
|
||||
std::string message = "Effective user of the process (" + effective_user +
|
||||
") does not match the owner of the data (" + data_owner + ").";
|
||||
if (effective_user_id == 0)
|
||||
{
|
||||
message += " Run under 'sudo -u " + data_owner + "'.";
|
||||
throw Exception(message, ErrorCodes::MISMATCHING_USERS_FOR_PROCESS_AND_DATA);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING(log, message);
|
||||
}
|
||||
}
|
||||
|
||||
const Settings & settings = global_context->getSettingsRef();
|
||||
|
||||
GlobalThreadPool::initialize(config().getUInt("max_thread_pool_size", 100));
|
||||
|
||||
static ServerErrorHandler error_handler;
|
||||
Poco::ErrorHandler::set(&error_handler);
|
||||
|
||||
/// Initialize DateLUT early, to not interfere with running time of first query.
|
||||
LOG_DEBUG(log, "Initializing DateLUT.");
|
||||
DateLUT::instance();
|
||||
LOG_TRACE(log, "Initialized DateLUT with time zone '{}'.", DateLUT::instance().getTimeZone());
|
||||
|
||||
/// Don't want to use DNS cache
|
||||
DNSResolver::instance().setDisableCacheFlag();
|
||||
|
||||
Poco::ThreadPool server_pool(3, config().getUInt("max_connections", 1024));
|
||||
|
||||
std::vector<std::string> listen_hosts = DB::getMultipleValuesFromConfig(config(), "", "listen_host");
|
||||
|
||||
bool listen_try = config().getBool("listen_try", false);
|
||||
if (listen_hosts.empty())
|
||||
{
|
||||
listen_hosts.emplace_back("::1");
|
||||
listen_hosts.emplace_back("127.0.0.1");
|
||||
listen_try = true;
|
||||
}
|
||||
|
||||
auto servers = std::make_shared<std::vector<ProtocolServerAdapter>>();
|
||||
|
||||
/// Initialize test keeper RAFT. Do nothing if no nu_keeper_server in config.
|
||||
global_context->initializeKeeperStorageDispatcher();
|
||||
for (const auto & listen_host : listen_hosts)
|
||||
{
|
||||
/// TCP Keeper
|
||||
const char * port_name = "keeper_server.tcp_port";
|
||||
createServer(listen_host, port_name, listen_try, [&](UInt16 port)
|
||||
{
|
||||
Poco::Net::ServerSocket socket;
|
||||
auto address = socketBindListen(socket, listen_host, port);
|
||||
socket.setReceiveTimeout(settings.receive_timeout);
|
||||
socket.setSendTimeout(settings.send_timeout);
|
||||
servers->emplace_back(
|
||||
port_name,
|
||||
std::make_unique<Poco::Net::TCPServer>(
|
||||
new KeeperTCPHandlerFactory(*this, false), server_pool, socket, new Poco::Net::TCPServerParams));
|
||||
|
||||
LOG_INFO(log, "Listening for connections to Keeper (tcp): {}", address.toString());
|
||||
});
|
||||
|
||||
const char * secure_port_name = "keeper_server.tcp_port_secure";
|
||||
createServer(listen_host, secure_port_name, listen_try, [&](UInt16 port)
|
||||
{
|
||||
#if USE_SSL
|
||||
Poco::Net::SecureServerSocket socket;
|
||||
auto address = socketBindListen(socket, listen_host, port, /* secure = */ true);
|
||||
socket.setReceiveTimeout(settings.receive_timeout);
|
||||
socket.setSendTimeout(settings.send_timeout);
|
||||
servers->emplace_back(
|
||||
secure_port_name,
|
||||
std::make_unique<Poco::Net::TCPServer>(
|
||||
new KeeperTCPHandlerFactory(*this, true), server_pool, socket, new Poco::Net::TCPServerParams));
|
||||
LOG_INFO(log, "Listening for connections to Keeper with secure protocol (tcp_secure): {}", address.toString());
|
||||
#else
|
||||
UNUSED(port);
|
||||
throw Exception{"SSL support for TCP protocol is disabled because Poco library was built without NetSSL support.",
|
||||
ErrorCodes::SUPPORT_IS_DISABLED};
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
for (auto & server : *servers)
|
||||
server.start();
|
||||
|
||||
SCOPE_EXIT({
|
||||
LOG_INFO(log, "Shutting down.");
|
||||
|
||||
global_context->shutdown();
|
||||
|
||||
LOG_DEBUG(log, "Waiting for current connections to Keeper to finish.");
|
||||
int current_connections = 0;
|
||||
for (auto & server : *servers)
|
||||
{
|
||||
server.stop();
|
||||
current_connections += server.currentConnections();
|
||||
}
|
||||
|
||||
if (current_connections)
|
||||
LOG_INFO(log, "Closed all listening sockets. Waiting for {} outstanding connections.", current_connections);
|
||||
else
|
||||
LOG_INFO(log, "Closed all listening sockets.");
|
||||
|
||||
if (current_connections > 0)
|
||||
current_connections = waitServersToFinish(*servers, config().getInt("shutdown_wait_unfinished", 5));
|
||||
|
||||
if (current_connections)
|
||||
LOG_INFO(log, "Closed connections to Keeper. But {} remain. Probably some users cannot finish their connections after context shutdown.", current_connections);
|
||||
else
|
||||
LOG_INFO(log, "Closed connections to Keeper.");
|
||||
|
||||
global_context->shutdownKeeperStorageDispatcher();
|
||||
|
||||
/// Wait server pool to avoid use-after-free of destroyed context in the handlers
|
||||
server_pool.joinAll();
|
||||
|
||||
/** Explicitly destroy Context. It is more convenient than in destructor of Server, because logger is still available.
|
||||
* At this moment, no one could own shared part of Context.
|
||||
*/
|
||||
global_context.reset();
|
||||
shared_context.reset();
|
||||
|
||||
LOG_DEBUG(log, "Destroyed global context.");
|
||||
|
||||
if (current_connections)
|
||||
{
|
||||
LOG_INFO(log, "Will shutdown forcefully.");
|
||||
forceShutdown();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
buildLoggers(config(), logger());
|
||||
|
||||
LOG_INFO(log, "Ready for connections.");
|
||||
|
||||
waitForTerminationRequest();
|
||||
|
||||
return Application::EXIT_OK;
|
||||
}
|
||||
|
||||
|
||||
void Keeper::logRevision() const
|
||||
{
|
||||
Poco::Logger::root().information("Starting ClickHouse Keeper " + std::string{VERSION_STRING}
|
||||
+ " with revision " + std::to_string(ClickHouseRevision::getVersionRevision())
|
||||
+ ", " + build_id_info
|
||||
+ ", PID " + std::to_string(getpid()));
|
||||
}
|
||||
|
||||
|
||||
}
|
69
programs/keeper/Keeper.h
Normal file
69
programs/keeper/Keeper.h
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <Server/IServer.h>
|
||||
#include <daemon/BaseDaemon.h>
|
||||
|
||||
namespace Poco
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
class ServerSocket;
|
||||
}
|
||||
}
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// standalone clickhouse-keeper server (replacement for ZooKeeper). Uses the same
|
||||
/// config as clickhouse-server. Serves requests on TCP ports with or without
|
||||
/// SSL using ZooKeeper protocol.
|
||||
class Keeper : public BaseDaemon, public IServer
|
||||
{
|
||||
public:
|
||||
using ServerApplication::run;
|
||||
|
||||
Poco::Util::LayeredConfiguration & config() const override
|
||||
{
|
||||
return BaseDaemon::config();
|
||||
}
|
||||
|
||||
Poco::Logger & logger() const override
|
||||
{
|
||||
return BaseDaemon::logger();
|
||||
}
|
||||
|
||||
ContextPtr context() const override
|
||||
{
|
||||
return global_context;
|
||||
}
|
||||
|
||||
bool isCancelled() const override
|
||||
{
|
||||
return BaseDaemon::isCancelled();
|
||||
}
|
||||
|
||||
void defineOptions(Poco::Util::OptionSet & _options) override;
|
||||
|
||||
protected:
|
||||
void logRevision() const override;
|
||||
|
||||
int run() override;
|
||||
|
||||
void initialize(Application & self) override;
|
||||
|
||||
void uninitialize() override;
|
||||
|
||||
int main(const std::vector<std::string> & args) override;
|
||||
|
||||
std::string getDefaultConfigFileName() const override;
|
||||
|
||||
private:
|
||||
ContextPtr global_context;
|
||||
|
||||
Poco::Net::SocketAddress socketBindListen(Poco::Net::ServerSocket & socket, const std::string & host, UInt16 port, [[maybe_unused]] bool secure = false) const;
|
||||
|
||||
using CreateServerFunc = std::function<void(UInt16)>;
|
||||
void createServer(const std::string & listen_host, const char * port_name, bool listen_try, CreateServerFunc && func) const;
|
||||
};
|
||||
|
||||
}
|
6
programs/keeper/clickhouse-keeper.cpp
Normal file
6
programs/keeper/clickhouse-keeper.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
int mainEntryClickHouseKeeper(int argc, char ** argv);
|
||||
|
||||
int main(int argc_, char ** argv_)
|
||||
{
|
||||
return mainEntryClickHouseKeeper(argc_, argv_);
|
||||
}
|
81
programs/keeper/keeper_config.xml
Normal file
81
programs/keeper/keeper_config.xml
Normal file
@ -0,0 +1,81 @@
|
||||
<yandex>
|
||||
<logger>
|
||||
<!-- Possible levels [1]:
|
||||
|
||||
- none (turns off logging)
|
||||
- fatal
|
||||
- critical
|
||||
- error
|
||||
- warning
|
||||
- notice
|
||||
- information
|
||||
- debug
|
||||
- trace
|
||||
|
||||
[1]: https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/Logger.h#L105-L114
|
||||
-->
|
||||
<level>trace</level>
|
||||
<log>/var/log/clickhouse-keeper/clickhouse-keeper.log</log>
|
||||
<errorlog>/var/log/clickhouse-keeper/clickhouse-keeper.err.log</errorlog>
|
||||
<!-- Rotation policy
|
||||
See https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/FileChannel.h#L54-L85
|
||||
-->
|
||||
<size>1000M</size>
|
||||
<count>10</count>
|
||||
<!-- <console>1</console> --> <!-- Default behavior is autodetection (log to console if not daemon mode and is tty) -->
|
||||
</logger>
|
||||
|
||||
<max_connections>4096</max_connections>
|
||||
|
||||
<keeper_server>
|
||||
<tcp_port>9181</tcp_port>
|
||||
|
||||
<!-- Must be unique among all keeper serves -->
|
||||
<server_id>1</server_id>
|
||||
|
||||
<log_storage_path>/var/lib/clickhouse/coordination/logs</log_storage_path>
|
||||
<snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
|
||||
|
||||
<coordination_settings>
|
||||
<operation_timeout_ms>10000</operation_timeout_ms>
|
||||
<session_timeout_ms>30000</session_timeout_ms>
|
||||
<raft_logs_level>information</raft_logs_level>
|
||||
<!-- All settings listed in https://github.com/ClickHouse/ClickHouse/blob/master/src/Coordination/CoordinationSettings.h -->
|
||||
</coordination_settings>
|
||||
|
||||
<raft_configuration>
|
||||
<server>
|
||||
<id>1</id>
|
||||
|
||||
<!-- Internal port and hostname -->
|
||||
<hostname>localhost</hostname>
|
||||
<port>44444</port>
|
||||
</server>
|
||||
|
||||
<!-- Add more servers here -->
|
||||
|
||||
</raft_configuration>
|
||||
</keeper_server>
|
||||
|
||||
|
||||
<openSSL>
|
||||
<server>
|
||||
<!-- Used for secure tcp port -->
|
||||
<!-- openssl req -subj "/CN=localhost" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/clickhouse-server/server.key -out /etc/clickhouse-server/server.crt -->
|
||||
<certificateFile>/etc/clickhouse-keeper/server.crt</certificateFile>
|
||||
<privateKeyFile>/etc/clickhouse-keeper/server.key</privateKeyFile>
|
||||
<!-- dhparams are optional. You can delete the <dhParamsFile> element.
|
||||
To generate dhparams, use the following command:
|
||||
openssl dhparam -out /etc/clickhouse-keeper/dhparam.pem 4096
|
||||
Only file format with BEGIN DH PARAMETERS is supported.
|
||||
-->
|
||||
<dhParamsFile>/etc/clickhouse-keeper/dhparam.pem</dhParamsFile>
|
||||
<verificationMode>none</verificationMode>
|
||||
<loadDefaultCAFile>true</loadDefaultCAFile>
|
||||
<cacheSessions>true</cacheSessions>
|
||||
<disableProtocols>sslv2,sslv3</disableProtocols>
|
||||
<preferServerCiphers>true</preferServerCiphers>
|
||||
</server>
|
||||
</openSSL>
|
||||
|
||||
</yandex>
|
21
programs/keeper/keeper_embedded.xml
Normal file
21
programs/keeper/keeper_embedded.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<yandex>
|
||||
<logger>
|
||||
<level>trace</level>
|
||||
<console>true</console>
|
||||
</logger>
|
||||
|
||||
<keeper_server>
|
||||
<tcp_port>9181</tcp_port>
|
||||
<server_id>1</server_id>
|
||||
<log_storage_path>./keeper_log</log_storage_path>
|
||||
<snapshot_storage_path>./keeper_snapshot</snapshot_storage_path>
|
||||
|
||||
<raft_configuration>
|
||||
<server>
|
||||
<id>1</id>
|
||||
<hostname>localhost</hostname>
|
||||
<port>44444</port>
|
||||
</server>
|
||||
</raft_configuration>
|
||||
</keeper_server>
|
||||
</yandex>
|
@ -55,6 +55,9 @@ int mainEntryClickHouseObfuscator(int argc, char ** argv);
|
||||
#if ENABLE_CLICKHOUSE_GIT_IMPORT
|
||||
int mainEntryClickHouseGitImport(int argc, char ** argv);
|
||||
#endif
|
||||
#if ENABLE_CLICKHOUSE_KEEPER
|
||||
int mainEntryClickHouseKeeper(int argc, char ** argv);
|
||||
#endif
|
||||
#if ENABLE_CLICKHOUSE_INSTALL
|
||||
int mainEntryClickHouseInstall(int argc, char ** argv);
|
||||
int mainEntryClickHouseStart(int argc, char ** argv);
|
||||
@ -112,6 +115,9 @@ std::pair<const char *, MainFunc> clickhouse_applications[] =
|
||||
#if ENABLE_CLICKHOUSE_GIT_IMPORT
|
||||
{"git-import", mainEntryClickHouseGitImport},
|
||||
#endif
|
||||
#if ENABLE_CLICKHOUSE_KEEPER
|
||||
{"keeper", mainEntryClickHouseKeeper},
|
||||
#endif
|
||||
#if ENABLE_CLICKHOUSE_INSTALL
|
||||
{"install", mainEntryClickHouseInstall},
|
||||
{"start", mainEntryClickHouseStart},
|
||||
|
@ -31,37 +31,4 @@ clickhouse_program_add(server)
|
||||
|
||||
install(FILES config.xml users.xml DESTINATION "${CLICKHOUSE_ETC_DIR}/clickhouse-server" COMPONENT clickhouse)
|
||||
|
||||
# TODO We actually need this on Mac, FreeBSD.
|
||||
if (OS_LINUX)
|
||||
# Embed default config files as a resource into the binary.
|
||||
# This is needed for two purposes:
|
||||
# 1. Allow to run the binary without download of any other files.
|
||||
# 2. Allow to implement "sudo clickhouse install" tool.
|
||||
|
||||
foreach(RESOURCE_FILE config.xml users.xml embedded.xml play.html)
|
||||
set(RESOURCE_OBJ ${RESOURCE_FILE}.o)
|
||||
set(RESOURCE_OBJS ${RESOURCE_OBJS} ${RESOURCE_OBJ})
|
||||
|
||||
# https://stackoverflow.com/questions/14776463/compile-and-add-an-object-file-from-a-binary-with-cmake
|
||||
# PPC64LE fails to do this with objcopy, use ld or lld instead
|
||||
if (ARCH_PPC64LE)
|
||||
add_custom_command(OUTPUT ${RESOURCE_OBJ}
|
||||
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf64lppc -r -b binary -o "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_OBJ}" ${RESOURCE_FILE})
|
||||
else()
|
||||
add_custom_command(OUTPUT ${RESOURCE_OBJ}
|
||||
COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${OBJCOPY_PATH} -I binary ${OBJCOPY_ARCH_OPTIONS} ${RESOURCE_FILE} "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_OBJ}"
|
||||
COMMAND ${OBJCOPY_PATH} --rename-section .data=.rodata,alloc,load,readonly,data,contents
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_OBJ}" "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_OBJ}")
|
||||
endif()
|
||||
set_source_files_properties(${RESOURCE_OBJ} PROPERTIES EXTERNAL_OBJECT true GENERATED true)
|
||||
endforeach(RESOURCE_FILE)
|
||||
|
||||
add_library(clickhouse_server_configs STATIC ${RESOURCE_OBJS})
|
||||
set_target_properties(clickhouse_server_configs PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
# whole-archive prevents symbols from being discarded for unknown reason
|
||||
# CMake can shuffle each of target_link_libraries arguments with other
|
||||
# libraries in linker command. To avoid this we hardcode whole-archive
|
||||
# library into single string.
|
||||
add_dependencies(clickhouse-server-lib clickhouse_server_configs)
|
||||
endif ()
|
||||
clickhouse_embed_binaries(server config.xml users.xml embedded.xml play.html)
|
||||
|
@ -364,6 +364,20 @@
|
||||
bind_dn - template used to construct the DN to bind to.
|
||||
The resulting DN will be constructed by replacing all '{user_name}' substrings of the template with the actual
|
||||
user name during each authentication attempt.
|
||||
user_dn_detection - section with LDAP search parameters for detecting the actual user DN of the bound user.
|
||||
This is mainly used in search filters for further role mapping when the server is Active Directory. The
|
||||
resulting user DN will be used when replacing '{user_dn}' substrings wherever they are allowed. By default,
|
||||
user DN is set equal to bind DN, but once search is performed, it will be updated with to the actual detected
|
||||
user DN value.
|
||||
base_dn - template used to construct the base DN for the LDAP search.
|
||||
The resulting DN will be constructed by replacing all '{user_name}' and '{bind_dn}' substrings
|
||||
of the template with the actual user name and bind DN during the LDAP search.
|
||||
scope - scope of the LDAP search.
|
||||
Accepted values are: 'base', 'one_level', 'children', 'subtree' (the default).
|
||||
search_filter - template used to construct the search filter for the LDAP search.
|
||||
The resulting filter will be constructed by replacing all '{user_name}', '{bind_dn}', and '{base_dn}'
|
||||
substrings of the template with the actual user name, bind DN, and base DN during the LDAP search.
|
||||
Note, that the special characters must be escaped properly in XML.
|
||||
verification_cooldown - a period of time, in seconds, after a successful bind attempt, during which a user will be assumed
|
||||
to be successfully authenticated for all consecutive requests without contacting the LDAP server.
|
||||
Specify 0 (the default) to disable caching and force contacting the LDAP server for each authentication request.
|
||||
@ -395,6 +409,17 @@
|
||||
<tls_ca_cert_dir>/path/to/tls_ca_cert_dir</tls_ca_cert_dir>
|
||||
<tls_cipher_suite>ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384</tls_cipher_suite>
|
||||
</my_ldap_server>
|
||||
Example (typical Active Directory with configured user DN detection for further role mapping):
|
||||
<my_ad_server>
|
||||
<host>localhost</host>
|
||||
<port>389</port>
|
||||
<bind_dn>EXAMPLE\{user_name}</bind_dn>
|
||||
<user_dn_detection>
|
||||
<base_dn>CN=Users,DC=example,DC=com</base_dn>
|
||||
<search_filter>(&(objectClass=user)(sAMAccountName={user_name}))</search_filter>
|
||||
</user_dn_detection>
|
||||
<enable_tls>no</enable_tls>
|
||||
</my_ad_server>
|
||||
-->
|
||||
</ldap_servers>
|
||||
|
||||
@ -446,15 +471,16 @@
|
||||
There can be multiple 'role_mapping' sections defined inside the same 'ldap' section. All of them will be
|
||||
applied.
|
||||
base_dn - template used to construct the base DN for the LDAP search.
|
||||
The resulting DN will be constructed by replacing all '{user_name}' and '{bind_dn}' substrings
|
||||
of the template with the actual user name and bind DN during each LDAP search.
|
||||
The resulting DN will be constructed by replacing all '{user_name}', '{bind_dn}', and '{user_dn}'
|
||||
substrings of the template with the actual user name, bind DN, and user DN during each LDAP search.
|
||||
scope - scope of the LDAP search.
|
||||
Accepted values are: 'base', 'one_level', 'children', 'subtree' (the default).
|
||||
search_filter - template used to construct the search filter for the LDAP search.
|
||||
The resulting filter will be constructed by replacing all '{user_name}', '{bind_dn}', and '{base_dn}'
|
||||
substrings of the template with the actual user name, bind DN, and base DN during each LDAP search.
|
||||
The resulting filter will be constructed by replacing all '{user_name}', '{bind_dn}', '{user_dn}', and
|
||||
'{base_dn}' substrings of the template with the actual user name, bind DN, user DN, and base DN during
|
||||
each LDAP search.
|
||||
Note, that the special characters must be escaped properly in XML.
|
||||
attribute - attribute name whose values will be returned by the LDAP search.
|
||||
attribute - attribute name whose values will be returned by the LDAP search. 'cn', by default.
|
||||
prefix - prefix, that will be expected to be in front of each string in the original list of strings returned by
|
||||
the LDAP search. Prefix will be removed from the original strings and resulting strings will be treated
|
||||
as local role names. Empty, by default.
|
||||
@ -473,6 +499,17 @@
|
||||
<prefix>clickhouse_</prefix>
|
||||
</role_mapping>
|
||||
</ldap>
|
||||
Example (typical Active Directory with role mapping that relies on the detected user DN):
|
||||
<ldap>
|
||||
<server>my_ad_server</server>
|
||||
<role_mapping>
|
||||
<base_dn>CN=Users,DC=example,DC=com</base_dn>
|
||||
<attribute>CN</attribute>
|
||||
<scope>subtree</scope>
|
||||
<search_filter>(&(objectClass=group)(member={user_dn}))</search_filter>
|
||||
<prefix>clickhouse_</prefix>
|
||||
</role_mapping>
|
||||
</ldap>
|
||||
-->
|
||||
</user_directories>
|
||||
|
||||
|
950
programs/server/config.yaml.example
Normal file
950
programs/server/config.yaml.example
Normal file
@ -0,0 +1,950 @@
|
||||
# This is an example of a configuration file "config.xml" rewritten in YAML
|
||||
# You can read this documentation for detailed information about YAML configuration:
|
||||
# https://clickhouse.tech/docs/en/operations/configuration-files/
|
||||
|
||||
# NOTE: User and query level settings are set up in "users.yaml" file.
|
||||
# If you have accidentally specified user-level settings here, server won't start.
|
||||
# You can either move the settings to the right place inside "users.xml" file
|
||||
# or add skip_check_for_incorrect_settings: 1 here.
|
||||
logger:
|
||||
# Possible levels [1]:
|
||||
# - none (turns off logging)
|
||||
# - fatal
|
||||
# - critical
|
||||
# - error
|
||||
# - warning
|
||||
# - notice
|
||||
# - information
|
||||
# - debug
|
||||
# - trace
|
||||
# [1]: https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/Logger.h#L105-L114
|
||||
level: trace
|
||||
log: /var/log/clickhouse-server/clickhouse-server.log
|
||||
errorlog: /var/log/clickhouse-server/clickhouse-server.err.log
|
||||
# Rotation policy
|
||||
# See https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/FileChannel.h#L54-L85
|
||||
size: 1000M
|
||||
count: 10
|
||||
# console: 1
|
||||
# Default behavior is autodetection (log to console if not daemon mode and is tty)
|
||||
|
||||
# Per level overrides (legacy):
|
||||
# For example to suppress logging of the ConfigReloader you can use:
|
||||
# NOTE: levels.logger is reserved, see below.
|
||||
# levels:
|
||||
# ConfigReloader: none
|
||||
|
||||
# Per level overrides:
|
||||
# For example to suppress logging of the RBAC for default user you can use:
|
||||
# (But please note that the logger name maybe changed from version to version, even after minor upgrade)
|
||||
# levels:
|
||||
# - logger:
|
||||
# name: 'ContextAccess (default)'
|
||||
# level: none
|
||||
# - logger:
|
||||
# name: 'DatabaseOrdinary (test)'
|
||||
# level: none
|
||||
|
||||
# It is the name that will be shown in the clickhouse-client.
|
||||
# By default, anything with "production" will be highlighted in red in query prompt.
|
||||
# display_name: production
|
||||
|
||||
# Port for HTTP API. See also 'https_port' for secure connections.
|
||||
# This interface is also used by ODBC and JDBC drivers (DataGrip, Dbeaver, ...)
|
||||
# and by most of web interfaces (embedded UI, Grafana, Redash, ...).
|
||||
http_port: 8123
|
||||
|
||||
# Port for interaction by native protocol with:
|
||||
# - clickhouse-client and other native ClickHouse tools (clickhouse-benchmark, clickhouse-copier);
|
||||
# - clickhouse-server with other clickhouse-servers for distributed query processing;
|
||||
# - ClickHouse drivers and applications supporting native protocol
|
||||
# (this protocol is also informally called as "the TCP protocol");
|
||||
# See also 'tcp_port_secure' for secure connections.
|
||||
tcp_port: 9000
|
||||
|
||||
# Compatibility with MySQL protocol.
|
||||
# ClickHouse will pretend to be MySQL for applications connecting to this port.
|
||||
mysql_port: 9004
|
||||
|
||||
# Compatibility with PostgreSQL protocol.
|
||||
# ClickHouse will pretend to be PostgreSQL for applications connecting to this port.
|
||||
postgresql_port: 9005
|
||||
|
||||
# HTTP API with TLS (HTTPS).
|
||||
# You have to configure certificate to enable this interface.
|
||||
# See the openSSL section below.
|
||||
# https_port: 8443
|
||||
|
||||
# Native interface with TLS.
|
||||
# You have to configure certificate to enable this interface.
|
||||
# See the openSSL section below.
|
||||
# tcp_port_secure: 9440
|
||||
|
||||
# Native interface wrapped with PROXYv1 protocol
|
||||
# PROXYv1 header sent for every connection.
|
||||
# ClickHouse will extract information about proxy-forwarded client address from the header.
|
||||
# tcp_with_proxy_port: 9011
|
||||
|
||||
# Port for communication between replicas. Used for data exchange.
|
||||
# It provides low-level data access between servers.
|
||||
# This port should not be accessible from untrusted networks.
|
||||
# See also 'interserver_http_credentials'.
|
||||
# Data transferred over connections to this port should not go through untrusted networks.
|
||||
# See also 'interserver_https_port'.
|
||||
interserver_http_port: 9009
|
||||
|
||||
# Port for communication between replicas with TLS.
|
||||
# You have to configure certificate to enable this interface.
|
||||
# See the openSSL section below.
|
||||
# See also 'interserver_http_credentials'.
|
||||
# interserver_https_port: 9010
|
||||
|
||||
# Hostname that is used by other replicas to request this server.
|
||||
# If not specified, than it is determined analogous to 'hostname -f' command.
|
||||
# This setting could be used to switch replication to another network interface
|
||||
# (the server may be connected to multiple networks via multiple addresses)
|
||||
# interserver_http_host: example.yandex.ru
|
||||
|
||||
# You can specify credentials for authenthication between replicas.
|
||||
# This is required when interserver_https_port is accessible from untrusted networks,
|
||||
# and also recommended to avoid SSRF attacks from possibly compromised services in your network.
|
||||
# interserver_http_credentials:
|
||||
# user: interserver
|
||||
# password: ''
|
||||
|
||||
# Listen specified address.
|
||||
# Use :: (wildcard IPv6 address), if you want to accept connections both with IPv4 and IPv6 from everywhere.
|
||||
# Notes:
|
||||
# If you open connections from wildcard address, make sure that at least one of the following measures applied:
|
||||
# - server is protected by firewall and not accessible from untrusted networks;
|
||||
# - all users are restricted to subset of network addresses (see users.xml);
|
||||
# - all users have strong passwords, only secure (TLS) interfaces are accessible, or connections are only made via TLS interfaces.
|
||||
# - users without password have readonly access.
|
||||
# See also: https://www.shodan.io/search?query=clickhouse
|
||||
# listen_host: '::'
|
||||
|
||||
# Same for hosts without support for IPv6:
|
||||
# listen_host: 0.0.0.0
|
||||
|
||||
# Default values - try listen localhost on IPv4 and IPv6.
|
||||
# listen_host: '::1'
|
||||
# listen_host: 127.0.0.1
|
||||
|
||||
# Don't exit if IPv6 or IPv4 networks are unavailable while trying to listen.
|
||||
# listen_try: 0
|
||||
|
||||
# Allow multiple servers to listen on the same address:port. This is not recommended.
|
||||
# listen_reuse_port: 0
|
||||
|
||||
# listen_backlog: 64
|
||||
max_connections: 4096
|
||||
|
||||
# For 'Connection: keep-alive' in HTTP 1.1
|
||||
keep_alive_timeout: 3
|
||||
|
||||
# gRPC protocol (see src/Server/grpc_protos/clickhouse_grpc.proto for the API)
|
||||
# grpc_port: 9100
|
||||
grpc:
|
||||
enable_ssl: false
|
||||
|
||||
# The following two files are used only if enable_ssl=1
|
||||
ssl_cert_file: /path/to/ssl_cert_file
|
||||
ssl_key_file: /path/to/ssl_key_file
|
||||
|
||||
# Whether server will request client for a certificate
|
||||
ssl_require_client_auth: false
|
||||
|
||||
# The following file is used only if ssl_require_client_auth=1
|
||||
ssl_ca_cert_file: /path/to/ssl_ca_cert_file
|
||||
|
||||
# Default compression algorithm (applied if client doesn't specify another algorithm).
|
||||
# Supported algorithms: none, deflate, gzip, stream_gzip
|
||||
compression: deflate
|
||||
|
||||
# Default compression level (applied if client doesn't specify another level).
|
||||
# Supported levels: none, low, medium, high
|
||||
compression_level: medium
|
||||
|
||||
# Send/receive message size limits in bytes. -1 means unlimited
|
||||
max_send_message_size: -1
|
||||
max_receive_message_size: -1
|
||||
|
||||
# Enable if you want very detailed logs
|
||||
verbose_logs: false
|
||||
|
||||
# Used with https_port and tcp_port_secure. Full ssl options list: https://github.com/ClickHouse-Extras/poco/blob/master/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h#L71
|
||||
openSSL:
|
||||
server:
|
||||
# Used for https server AND secure tcp port
|
||||
# openssl req -subj "/CN=localhost" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/clickhouse-server/server.key -out /etc/clickhouse-server/server.crt
|
||||
certificateFile: /etc/clickhouse-server/server.crt
|
||||
privateKeyFile: /etc/clickhouse-server/server.key
|
||||
|
||||
# dhparams are optional. You can delete the dhParamsFile: element.
|
||||
# To generate dhparams, use the following command:
|
||||
# openssl dhparam -out /etc/clickhouse-server/dhparam.pem 4096
|
||||
# Only file format with BEGIN DH PARAMETERS is supported.
|
||||
dhParamsFile: /etc/clickhouse-server/dhparam.pem
|
||||
verificationMode: none
|
||||
loadDefaultCAFile: true
|
||||
cacheSessions: true
|
||||
disableProtocols: 'sslv2,sslv3'
|
||||
preferServerCiphers: true
|
||||
client:
|
||||
# Used for connecting to https dictionary source and secured Zookeeper communication
|
||||
loadDefaultCAFile: true
|
||||
cacheSessions: true
|
||||
disableProtocols: 'sslv2,sslv3'
|
||||
preferServerCiphers: true
|
||||
|
||||
# Use for self-signed: verificationMode: none
|
||||
invalidCertificateHandler:
|
||||
# Use for self-signed: name: AcceptCertificateHandler
|
||||
name: RejectCertificateHandler
|
||||
|
||||
# Default root page on http[s] server. For example load UI from https://tabix.io/ when opening http://localhost:8123
|
||||
# http_server_default_response: |-
|
||||
# <html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>
|
||||
|
||||
# Maximum number of concurrent queries.
|
||||
max_concurrent_queries: 100
|
||||
|
||||
# Maximum memory usage (resident set size) for server process.
|
||||
# Zero value or unset means default. Default is "max_server_memory_usage_to_ram_ratio" of available physical RAM.
|
||||
# If the value is larger than "max_server_memory_usage_to_ram_ratio" of available physical RAM, it will be cut down.
|
||||
|
||||
# The constraint is checked on query execution time.
|
||||
# If a query tries to allocate memory and the current memory usage plus allocation is greater
|
||||
# than specified threshold, exception will be thrown.
|
||||
|
||||
# It is not practical to set this constraint to small values like just a few gigabytes,
|
||||
# because memory allocator will keep this amount of memory in caches and the server will deny service of queries.
|
||||
max_server_memory_usage: 0
|
||||
|
||||
# Maximum number of threads in the Global thread pool.
|
||||
# This will default to a maximum of 10000 threads if not specified.
|
||||
# This setting will be useful in scenarios where there are a large number
|
||||
# of distributed queries that are running concurrently but are idling most
|
||||
# of the time, in which case a higher number of threads might be required.
|
||||
max_thread_pool_size: 10000
|
||||
|
||||
# On memory constrained environments you may have to set this to value larger than 1.
|
||||
max_server_memory_usage_to_ram_ratio: 0.9
|
||||
|
||||
# Simple server-wide memory profiler. Collect a stack trace at every peak allocation step (in bytes).
|
||||
# Data will be stored in system.trace_log table with query_id = empty string.
|
||||
# Zero means disabled.
|
||||
total_memory_profiler_step: 4194304
|
||||
|
||||
# Collect random allocations and deallocations and write them into system.trace_log with 'MemorySample' trace_type.
|
||||
# The probability is for every alloc/free regardless to the size of the allocation.
|
||||
# Note that sampling happens only when the amount of untracked memory exceeds the untracked memory limit,
|
||||
# which is 4 MiB by default but can be lowered if 'total_memory_profiler_step' is lowered.
|
||||
# You may want to set 'total_memory_profiler_step' to 1 for extra fine grained sampling.
|
||||
total_memory_tracker_sample_probability: 0
|
||||
|
||||
# Set limit on number of open files (default: maximum). This setting makes sense on Mac OS X because getrlimit() fails to retrieve
|
||||
# correct maximum value.
|
||||
# max_open_files: 262144
|
||||
|
||||
# Size of cache of uncompressed blocks of data, used in tables of MergeTree family.
|
||||
# In bytes. Cache is single for server. Memory is allocated only on demand.
|
||||
# Cache is used when 'use_uncompressed_cache' user setting turned on (off by default).
|
||||
# Uncompressed cache is advantageous only for very short queries and in rare cases.
|
||||
|
||||
# Note: uncompressed cache can be pointless for lz4, because memory bandwidth
|
||||
# is slower than multi-core decompression on some server configurations.
|
||||
# Enabling it can sometimes paradoxically make queries slower.
|
||||
uncompressed_cache_size: 8589934592
|
||||
|
||||
# Approximate size of mark cache, used in tables of MergeTree family.
|
||||
# In bytes. Cache is single for server. Memory is allocated only on demand.
|
||||
# You should not lower this value.
|
||||
mark_cache_size: 5368709120
|
||||
|
||||
# If you enable the `min_bytes_to_use_mmap_io` setting,
|
||||
# the data in MergeTree tables can be read with mmap to avoid copying from kernel to userspace.
|
||||
# It makes sense only for large files and helps only if data reside in page cache.
|
||||
# To avoid frequent open/mmap/munmap/close calls (which are very expensive due to consequent page faults)
|
||||
# and to reuse mappings from several threads and queries,
|
||||
# the cache of mapped files is maintained. Its size is the number of mapped regions (usually equal to the number of mapped files).
|
||||
# The amount of data in mapped files can be monitored
|
||||
# in system.metrics, system.metric_log by the MMappedFiles, MMappedFileBytes metrics
|
||||
# and in system.asynchronous_metrics, system.asynchronous_metrics_log by the MMapCacheCells metric,
|
||||
# and also in system.events, system.processes, system.query_log, system.query_thread_log by the
|
||||
# CreatedReadBufferMMap, CreatedReadBufferMMapFailed, MMappedFileCacheHits, MMappedFileCacheMisses events.
|
||||
# Note that the amount of data in mapped files does not consume memory directly and is not accounted
|
||||
# in query or server memory usage - because this memory can be discarded similar to OS page cache.
|
||||
# The cache is dropped (the files are closed) automatically on removal of old parts in MergeTree,
|
||||
# also it can be dropped manually by the SYSTEM DROP MMAP CACHE query.
|
||||
mmap_cache_size: 1000
|
||||
|
||||
# Cache size for compiled expressions.
|
||||
compiled_expression_cache_size: 1073741824
|
||||
|
||||
# Path to data directory, with trailing slash.
|
||||
path: /var/lib/clickhouse/
|
||||
|
||||
# Path to temporary data for processing hard queries.
|
||||
tmp_path: /var/lib/clickhouse/tmp/
|
||||
|
||||
# Policy from the <storage_configuration> for the temporary files.
|
||||
# If not set <tmp_path> is used, otherwise <tmp_path> is ignored.
|
||||
|
||||
# Notes:
|
||||
# - move_factor is ignored
|
||||
# - keep_free_space_bytes is ignored
|
||||
# - max_data_part_size_bytes is ignored
|
||||
# - you must have exactly one volume in that policy
|
||||
# tmp_policy: tmp
|
||||
|
||||
# Directory with user provided files that are accessible by 'file' table function.
|
||||
user_files_path: /var/lib/clickhouse/user_files/
|
||||
|
||||
# LDAP server definitions.
|
||||
ldap_servers: ''
|
||||
|
||||
# List LDAP servers with their connection parameters here to later 1) use them as authenticators for dedicated local users,
|
||||
# who have 'ldap' authentication mechanism specified instead of 'password', or to 2) use them as remote user directories.
|
||||
# Parameters:
|
||||
# host - LDAP server hostname or IP, this parameter is mandatory and cannot be empty.
|
||||
# port - LDAP server port, default is 636 if enable_tls is set to true, 389 otherwise.
|
||||
# bind_dn - template used to construct the DN to bind to.
|
||||
# The resulting DN will be constructed by replacing all '{user_name}' substrings of the template with the actual
|
||||
# user name during each authentication attempt.
|
||||
# user_dn_detection - section with LDAP search parameters for detecting the actual user DN of the bound user.
|
||||
# This is mainly used in search filters for further role mapping when the server is Active Directory. The
|
||||
# resulting user DN will be used when replacing '{user_dn}' substrings wherever they are allowed. By default,
|
||||
# user DN is set equal to bind DN, but once search is performed, it will be updated with to the actual detected
|
||||
# user DN value.
|
||||
# base_dn - template used to construct the base DN for the LDAP search.
|
||||
# The resulting DN will be constructed by replacing all '{user_name}' and '{bind_dn}' substrings
|
||||
# of the template with the actual user name and bind DN during the LDAP search.
|
||||
# scope - scope of the LDAP search.
|
||||
# Accepted values are: 'base', 'one_level', 'children', 'subtree' (the default).
|
||||
# search_filter - template used to construct the search filter for the LDAP search.
|
||||
# The resulting filter will be constructed by replacing all '{user_name}', '{bind_dn}', and '{base_dn}'
|
||||
# substrings of the template with the actual user name, bind DN, and base DN during the LDAP search.
|
||||
# Note, that the special characters must be escaped properly in XML.
|
||||
# verification_cooldown - a period of time, in seconds, after a successful bind attempt, during which a user will be assumed
|
||||
# to be successfully authenticated for all consecutive requests without contacting the LDAP server.
|
||||
# Specify 0 (the default) to disable caching and force contacting the LDAP server for each authentication request.
|
||||
# enable_tls - flag to trigger use of secure connection to the LDAP server.
|
||||
# Specify 'no' for plain text (ldap://) protocol (not recommended).
|
||||
# Specify 'yes' for LDAP over SSL/TLS (ldaps://) protocol (recommended, the default).
|
||||
# Specify 'starttls' for legacy StartTLS protocol (plain text (ldap://) protocol, upgraded to TLS).
|
||||
# tls_minimum_protocol_version - the minimum protocol version of SSL/TLS.
|
||||
# Accepted values are: 'ssl2', 'ssl3', 'tls1.0', 'tls1.1', 'tls1.2' (the default).
|
||||
# tls_require_cert - SSL/TLS peer certificate verification behavior.
|
||||
# Accepted values are: 'never', 'allow', 'try', 'demand' (the default).
|
||||
# tls_cert_file - path to certificate file.
|
||||
# tls_key_file - path to certificate key file.
|
||||
# tls_ca_cert_file - path to CA certificate file.
|
||||
# tls_ca_cert_dir - path to the directory containing CA certificates.
|
||||
# tls_cipher_suite - allowed cipher suite (in OpenSSL notation).
|
||||
# Example:
|
||||
# my_ldap_server:
|
||||
# host: localhost
|
||||
# port: 636
|
||||
# bind_dn: 'uid={user_name},ou=users,dc=example,dc=com'
|
||||
# verification_cooldown: 300
|
||||
# enable_tls: yes
|
||||
# tls_minimum_protocol_version: tls1.2
|
||||
# tls_require_cert: demand
|
||||
# tls_cert_file: /path/to/tls_cert_file
|
||||
# tls_key_file: /path/to/tls_key_file
|
||||
# tls_ca_cert_file: /path/to/tls_ca_cert_file
|
||||
# tls_ca_cert_dir: /path/to/tls_ca_cert_dir
|
||||
# tls_cipher_suite: ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384
|
||||
|
||||
# Example (typical Active Directory with configured user DN detection for further role mapping):
|
||||
# my_ad_server:
|
||||
# host: localhost
|
||||
# port: 389
|
||||
# bind_dn: 'EXAMPLE\{user_name}'
|
||||
# user_dn_detection:
|
||||
# base_dn: CN=Users,DC=example,DC=com
|
||||
# search_filter: '(&(objectClass=user)(sAMAccountName={user_name}))'
|
||||
# enable_tls: no
|
||||
|
||||
# To enable Kerberos authentication support for HTTP requests (GSS-SPNEGO), for those users who are explicitly configured
|
||||
# to authenticate via Kerberos, define a single 'kerberos' section here.
|
||||
# Parameters:
|
||||
# principal - canonical service principal name, that will be acquired and used when accepting security contexts.
|
||||
# This parameter is optional, if omitted, the default principal will be used.
|
||||
# This parameter cannot be specified together with 'realm' parameter.
|
||||
# realm - a realm, that will be used to restrict authentication to only those requests whose initiator's realm matches it.
|
||||
# This parameter is optional, if omitted, no additional filtering by realm will be applied.
|
||||
# This parameter cannot be specified together with 'principal' parameter.
|
||||
# Example:
|
||||
# kerberos: ''
|
||||
|
||||
# Example:
|
||||
# kerberos:
|
||||
# principal: HTTP/clickhouse.example.com@EXAMPLE.COM
|
||||
|
||||
# Example:
|
||||
# kerberos:
|
||||
# realm: EXAMPLE.COM
|
||||
|
||||
# Sources to read users, roles, access rights, profiles of settings, quotas.
|
||||
user_directories:
|
||||
users_xml:
|
||||
# Path to configuration file with predefined users.
|
||||
path: users.yaml
|
||||
local_directory:
|
||||
# Path to folder where users created by SQL commands are stored.
|
||||
path: /var/lib/clickhouse/access/
|
||||
|
||||
# # To add an LDAP server as a remote user directory of users that are not defined locally, define a single 'ldap' section
|
||||
# # with the following parameters:
|
||||
# # server - one of LDAP server names defined in 'ldap_servers' config section above.
|
||||
# # This parameter is mandatory and cannot be empty.
|
||||
# # roles - section with a list of locally defined roles that will be assigned to each user retrieved from the LDAP server.
|
||||
# # If no roles are specified here or assigned during role mapping (below), user will not be able to perform any
|
||||
# # actions after authentication.
|
||||
# # role_mapping - section with LDAP search parameters and mapping rules.
|
||||
# # When a user authenticates, while still bound to LDAP, an LDAP search is performed using search_filter and the
|
||||
# # name of the logged in user. For each entry found during that search, the value of the specified attribute is
|
||||
# # extracted. For each attribute value that has the specified prefix, the prefix is removed, and the rest of the
|
||||
# # value becomes the name of a local role defined in ClickHouse, which is expected to be created beforehand by
|
||||
# # CREATE ROLE command.
|
||||
# # There can be multiple 'role_mapping' sections defined inside the same 'ldap' section. All of them will be
|
||||
# # applied.
|
||||
# # base_dn - template used to construct the base DN for the LDAP search.
|
||||
# # The resulting DN will be constructed by replacing all '{user_name}', '{bind_dn}', and '{user_dn}'
|
||||
# # substrings of the template with the actual user name, bind DN, and user DN during each LDAP search.
|
||||
# # scope - scope of the LDAP search.
|
||||
# # Accepted values are: 'base', 'one_level', 'children', 'subtree' (the default).
|
||||
# # search_filter - template used to construct the search filter for the LDAP search.
|
||||
# # The resulting filter will be constructed by replacing all '{user_name}', '{bind_dn}', '{user_dn}', and
|
||||
# # '{base_dn}' substrings of the template with the actual user name, bind DN, user DN, and base DN during
|
||||
# # each LDAP search.
|
||||
# # Note, that the special characters must be escaped properly in XML.
|
||||
# # attribute - attribute name whose values will be returned by the LDAP search. 'cn', by default.
|
||||
# # prefix - prefix, that will be expected to be in front of each string in the original list of strings returned by
|
||||
# # the LDAP search. Prefix will be removed from the original strings and resulting strings will be treated
|
||||
# # as local role names. Empty, by default.
|
||||
# # Example:
|
||||
# # ldap:
|
||||
# # server: my_ldap_server
|
||||
# # roles:
|
||||
# # my_local_role1: ''
|
||||
# # my_local_role2: ''
|
||||
# # role_mapping:
|
||||
# # base_dn: 'ou=groups,dc=example,dc=com'
|
||||
# # scope: subtree
|
||||
# # search_filter: '(&(objectClass=groupOfNames)(member={bind_dn}))'
|
||||
# # attribute: cn
|
||||
# # prefix: clickhouse_
|
||||
# # Example (typical Active Directory with role mapping that relies on the detected user DN):
|
||||
# # ldap:
|
||||
# # server: my_ad_server
|
||||
# # role_mapping:
|
||||
# # base_dn: 'CN=Users,DC=example,DC=com'
|
||||
# # attribute: CN
|
||||
# # scope: subtree
|
||||
# # search_filter: '(&(objectClass=group)(member={user_dn}))'
|
||||
# # prefix: clickhouse_
|
||||
|
||||
# Default profile of settings.
|
||||
default_profile: default
|
||||
|
||||
# Comma-separated list of prefixes for user-defined settings.
|
||||
# custom_settings_prefixes: ''
|
||||
# System profile of settings. This settings are used by internal processes (Distributed DDL worker and so on).
|
||||
# system_profile: default
|
||||
|
||||
# Buffer profile of settings.
|
||||
# This settings are used by Buffer storage to flush data to the underlying table.
|
||||
# Default: used from system_profile directive.
|
||||
# buffer_profile: default
|
||||
|
||||
# Default database.
|
||||
default_database: default
|
||||
|
||||
# Server time zone could be set here.
|
||||
|
||||
# Time zone is used when converting between String and DateTime types,
|
||||
# when printing DateTime in text formats and parsing DateTime from text,
|
||||
# it is used in date and time related functions, if specific time zone was not passed as an argument.
|
||||
|
||||
# Time zone is specified as identifier from IANA time zone database, like UTC or Africa/Abidjan.
|
||||
# If not specified, system time zone at server startup is used.
|
||||
|
||||
# Please note, that server could display time zone alias instead of specified name.
|
||||
# Example: W-SU is an alias for Europe/Moscow and Zulu is an alias for UTC.
|
||||
# timezone: Europe/Moscow
|
||||
|
||||
# You can specify umask here (see "man umask"). Server will apply it on startup.
|
||||
# Number is always parsed as octal. Default umask is 027 (other users cannot read logs, data files, etc; group can only read).
|
||||
# umask: 022
|
||||
|
||||
# Perform mlockall after startup to lower first queries latency
|
||||
# and to prevent clickhouse executable from being paged out under high IO load.
|
||||
# Enabling this option is recommended but will lead to increased startup time for up to a few seconds.
|
||||
mlock_executable: true
|
||||
|
||||
# Reallocate memory for machine code ("text") using huge pages. Highly experimental.
|
||||
remap_executable: false
|
||||
|
||||
# Uncomment below in order to use JDBC table engine and function.
|
||||
# To install and run JDBC bridge in background:
|
||||
# * [Debian/Ubuntu]
|
||||
# export MVN_URL=https://repo1.maven.org/maven2/ru/yandex/clickhouse/clickhouse-jdbc-bridge
|
||||
# export PKG_VER=$(curl -sL $MVN_URL/maven-metadata.xml | grep '<release>' | sed -e 's|.*>\(.*\)<.*|\1|')
|
||||
# wget https://github.com/ClickHouse/clickhouse-jdbc-bridge/releases/download/v$PKG_VER/clickhouse-jdbc-bridge_$PKG_VER-1_all.deb
|
||||
# apt install --no-install-recommends -f ./clickhouse-jdbc-bridge_$PKG_VER-1_all.deb
|
||||
# clickhouse-jdbc-bridge &
|
||||
# * [CentOS/RHEL]
|
||||
# export MVN_URL=https://repo1.maven.org/maven2/ru/yandex/clickhouse/clickhouse-jdbc-bridge
|
||||
# export PKG_VER=$(curl -sL $MVN_URL/maven-metadata.xml | grep '<release>' | sed -e 's|.*>\(.*\)<.*|\1|')
|
||||
# wget https://github.com/ClickHouse/clickhouse-jdbc-bridge/releases/download/v$PKG_VER/clickhouse-jdbc-bridge-$PKG_VER-1.noarch.rpm
|
||||
# yum localinstall -y clickhouse-jdbc-bridge-$PKG_VER-1.noarch.rpm
|
||||
# clickhouse-jdbc-bridge &
|
||||
# Please refer to https://github.com/ClickHouse/clickhouse-jdbc-bridge#usage for more information.
|
||||
|
||||
# jdbc_bridge:
|
||||
# host: 127.0.0.1
|
||||
# port: 9019
|
||||
|
||||
# Configuration of clusters that could be used in Distributed tables.
|
||||
# https://clickhouse.tech/docs/en/operations/table_engines/distributed/
|
||||
remote_servers:
|
||||
# Test only shard config for testing distributed storage
|
||||
test_shard_localhost:
|
||||
# Inter-server per-cluster secret for Distributed queries
|
||||
# default: no secret (no authentication will be performed)
|
||||
|
||||
# If set, then Distributed queries will be validated on shards, so at least:
|
||||
# - such cluster should exist on the shard,
|
||||
# - such cluster should have the same secret.
|
||||
|
||||
# And also (and which is more important), the initial_user will
|
||||
# be used as current user for the query.
|
||||
|
||||
# Right now the protocol is pretty simple and it only takes into account:
|
||||
# - cluster name
|
||||
# - query
|
||||
|
||||
# Also it will be nice if the following will be implemented:
|
||||
# - source hostname (see interserver_http_host), but then it will depends from DNS,
|
||||
# it can use IP address instead, but then the you need to get correct on the initiator node.
|
||||
# - target hostname / ip address (same notes as for source hostname)
|
||||
# - time-based security tokens
|
||||
# secret: ''
|
||||
shard:
|
||||
# Optional. Whether to write data to just one of the replicas. Default: false (write data to all replicas).
|
||||
# internal_replication: false
|
||||
# Optional. Shard weight when writing data. Default: 1.
|
||||
# weight: 1
|
||||
replica:
|
||||
host: localhost
|
||||
port: 9000
|
||||
# Optional. Priority of the replica for load_balancing. Default: 1 (less value has more priority).
|
||||
# priority: 1
|
||||
test_cluster_two_shards_localhost:
|
||||
shard:
|
||||
- replica:
|
||||
host: localhost
|
||||
port: 9000
|
||||
- replica:
|
||||
host: localhost
|
||||
port: 9000
|
||||
test_cluster_two_shards:
|
||||
shard:
|
||||
- replica:
|
||||
host: 127.0.0.1
|
||||
port: 9000
|
||||
- replica:
|
||||
host: 127.0.0.2
|
||||
port: 9000
|
||||
test_cluster_two_shards_internal_replication:
|
||||
shard:
|
||||
- internal_replication: true
|
||||
replica:
|
||||
host: 127.0.0.1
|
||||
port: 9000
|
||||
- internal_replication: true
|
||||
replica:
|
||||
host: 127.0.0.2
|
||||
port: 9000
|
||||
test_shard_localhost_secure:
|
||||
shard:
|
||||
replica:
|
||||
host: localhost
|
||||
port: 9440
|
||||
secure: 1
|
||||
test_unavailable_shard:
|
||||
shard:
|
||||
- replica:
|
||||
host: localhost
|
||||
port: 9000
|
||||
- replica:
|
||||
host: localhost
|
||||
port: 1
|
||||
|
||||
# The list of hosts allowed to use in URL-related storage engines and table functions.
|
||||
# If this section is not present in configuration, all hosts are allowed.
|
||||
# remote_url_allow_hosts:
|
||||
|
||||
# Host should be specified exactly as in URL. The name is checked before DNS resolution.
|
||||
# Example: "yandex.ru", "yandex.ru." and "www.yandex.ru" are different hosts.
|
||||
# If port is explicitly specified in URL, the host:port is checked as a whole.
|
||||
# If host specified here without port, any port with this host allowed.
|
||||
# "yandex.ru" -> "yandex.ru:443", "yandex.ru:80" etc. is allowed, but "yandex.ru:80" -> only "yandex.ru:80" is allowed.
|
||||
# If the host is specified as IP address, it is checked as specified in URL. Example: "[2a02:6b8:a::a]".
|
||||
# If there are redirects and support for redirects is enabled, every redirect (the Location field) is checked.
|
||||
|
||||
# Regular expression can be specified. RE2 engine is used for regexps.
|
||||
# Regexps are not aligned: don't forget to add ^ and $. Also don't forget to escape dot (.) metacharacter
|
||||
# (forgetting to do so is a common source of error).
|
||||
|
||||
# If element has 'incl' attribute, then for it's value will be used corresponding substitution from another file.
|
||||
# By default, path to file with substitutions is /etc/metrika.xml. It could be changed in config in 'include_from' element.
|
||||
# Values for substitutions are specified in /yandex/name_of_substitution elements in that file.
|
||||
|
||||
# ZooKeeper is used to store metadata about replicas, when using Replicated tables.
|
||||
# Optional. If you don't use replicated tables, you could omit that.
|
||||
# See https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/replication/
|
||||
|
||||
# zookeeper:
|
||||
# - node:
|
||||
# host: example1
|
||||
# port: 2181
|
||||
# - node:
|
||||
# host: example2
|
||||
# port: 2181
|
||||
# - node:
|
||||
# host: example3
|
||||
# port: 2181
|
||||
|
||||
# Substitutions for parameters of replicated tables.
|
||||
# Optional. If you don't use replicated tables, you could omit that.
|
||||
# See https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/replication/#creating-replicated-tables
|
||||
# macros:
|
||||
# shard: 01
|
||||
# replica: example01-01-1
|
||||
|
||||
# Reloading interval for embedded dictionaries, in seconds. Default: 3600.
|
||||
builtin_dictionaries_reload_interval: 3600
|
||||
|
||||
# Maximum session timeout, in seconds. Default: 3600.
|
||||
max_session_timeout: 3600
|
||||
|
||||
# Default session timeout, in seconds. Default: 60.
|
||||
default_session_timeout: 60
|
||||
|
||||
# Sending data to Graphite for monitoring. Several sections can be defined.
|
||||
# interval - send every X second
|
||||
# root_path - prefix for keys
|
||||
# hostname_in_path - append hostname to root_path (default = true)
|
||||
# metrics - send data from table system.metrics
|
||||
# events - send data from table system.events
|
||||
# asynchronous_metrics - send data from table system.asynchronous_metrics
|
||||
|
||||
# graphite:
|
||||
# host: localhost
|
||||
# port: 42000
|
||||
# timeout: 0.1
|
||||
# interval: 60
|
||||
# root_path: one_min
|
||||
# hostname_in_path: true
|
||||
|
||||
# metrics: true
|
||||
# events: true
|
||||
# events_cumulative: false
|
||||
# asynchronous_metrics: true
|
||||
|
||||
# graphite:
|
||||
# host: localhost
|
||||
# port: 42000
|
||||
# timeout: 0.1
|
||||
# interval: 1
|
||||
# root_path: one_sec
|
||||
|
||||
# metrics: true
|
||||
# events: true
|
||||
# events_cumulative: false
|
||||
# asynchronous_metrics: false
|
||||
|
||||
# Serve endpoint for Prometheus monitoring.
|
||||
# endpoint - mertics path (relative to root, statring with "/")
|
||||
# port - port to setup server. If not defined or 0 than http_port used
|
||||
# metrics - send data from table system.metrics
|
||||
# events - send data from table system.events
|
||||
# asynchronous_metrics - send data from table system.asynchronous_metrics
|
||||
# status_info - send data from different component from CH, ex: Dictionaries status
|
||||
|
||||
# prometheus:
|
||||
# endpoint: /metrics
|
||||
# port: 9363
|
||||
|
||||
# metrics: true
|
||||
# events: true
|
||||
# asynchronous_metrics: true
|
||||
# status_info: true
|
||||
|
||||
# Query log. Used only for queries with setting log_queries = 1.
|
||||
query_log:
|
||||
# What table to insert data. If table is not exist, it will be created.
|
||||
# When query log structure is changed after system update,
|
||||
# then old table will be renamed and new table will be created automatically.
|
||||
database: system
|
||||
table: query_log
|
||||
|
||||
# PARTITION BY expr: https://clickhouse.yandex/docs/en/table_engines/mergetree-family/custom_partitioning_key/
|
||||
# Example:
|
||||
# event_date
|
||||
# toMonday(event_date)
|
||||
# toYYYYMM(event_date)
|
||||
# toStartOfHour(event_time)
|
||||
partition_by: toYYYYMM(event_date)
|
||||
|
||||
# Table TTL specification: https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/mergetree/#mergetree-table-ttl
|
||||
# Example:
|
||||
# event_date + INTERVAL 1 WEEK
|
||||
# event_date + INTERVAL 7 DAY DELETE
|
||||
# event_date + INTERVAL 2 WEEK TO DISK 'bbb'
|
||||
|
||||
# ttl: 'event_date + INTERVAL 30 DAY DELETE'
|
||||
|
||||
# Instead of partition_by, you can provide full engine expression (starting with ENGINE = ) with parameters,
|
||||
# Example: engine: 'ENGINE = MergeTree PARTITION BY toYYYYMM(event_date) ORDER BY (event_date, event_time) SETTINGS index_granularity = 1024'
|
||||
|
||||
# Interval of flushing data.
|
||||
flush_interval_milliseconds: 7500
|
||||
|
||||
# Trace log. Stores stack traces collected by query profilers.
|
||||
# See query_profiler_real_time_period_ns and query_profiler_cpu_time_period_ns settings.
|
||||
trace_log:
|
||||
database: system
|
||||
table: trace_log
|
||||
partition_by: toYYYYMM(event_date)
|
||||
flush_interval_milliseconds: 7500
|
||||
|
||||
# Query thread log. Has information about all threads participated in query execution.
|
||||
# Used only for queries with setting log_query_threads = 1.
|
||||
query_thread_log:
|
||||
database: system
|
||||
table: query_thread_log
|
||||
partition_by: toYYYYMM(event_date)
|
||||
flush_interval_milliseconds: 7500
|
||||
|
||||
# Uncomment if use part log.
|
||||
# Part log contains information about all actions with parts in MergeTree tables (creation, deletion, merges, downloads).
|
||||
# part_log:
|
||||
# database: system
|
||||
# table: part_log
|
||||
# flush_interval_milliseconds: 7500
|
||||
|
||||
# Uncomment to write text log into table.
|
||||
# Text log contains all information from usual server log but stores it in structured and efficient way.
|
||||
# The level of the messages that goes to the table can be limited (<level>), if not specified all messages will go to the table.
|
||||
# text_log:
|
||||
# database: system
|
||||
# table: text_log
|
||||
# flush_interval_milliseconds: 7500
|
||||
# level: ''
|
||||
|
||||
# Metric log contains rows with current values of ProfileEvents, CurrentMetrics collected with "collect_interval_milliseconds" interval.
|
||||
metric_log:
|
||||
database: system
|
||||
table: metric_log
|
||||
flush_interval_milliseconds: 7500
|
||||
collect_interval_milliseconds: 1000
|
||||
|
||||
# Asynchronous metric log contains values of metrics from
|
||||
# system.asynchronous_metrics.
|
||||
asynchronous_metric_log:
|
||||
database: system
|
||||
table: asynchronous_metric_log
|
||||
|
||||
# Asynchronous metrics are updated once a minute, so there is
|
||||
# no need to flush more often.
|
||||
flush_interval_milliseconds: 60000
|
||||
|
||||
# OpenTelemetry log contains OpenTelemetry trace spans.
|
||||
opentelemetry_span_log:
|
||||
|
||||
# The default table creation code is insufficient, this <engine> spec
|
||||
# is a workaround. There is no 'event_time' for this log, but two times,
|
||||
# start and finish. It is sorted by finish time, to avoid inserting
|
||||
# data too far away in the past (probably we can sometimes insert a span
|
||||
# that is seconds earlier than the last span in the table, due to a race
|
||||
# between several spans inserted in parallel). This gives the spans a
|
||||
# global order that we can use to e.g. retry insertion into some external
|
||||
# system.
|
||||
engine: |-
|
||||
engine MergeTree
|
||||
partition by toYYYYMM(finish_date)
|
||||
order by (finish_date, finish_time_us, trace_id)
|
||||
database: system
|
||||
table: opentelemetry_span_log
|
||||
flush_interval_milliseconds: 7500
|
||||
|
||||
# Crash log. Stores stack traces for fatal errors.
|
||||
# This table is normally empty.
|
||||
crash_log:
|
||||
database: system
|
||||
table: crash_log
|
||||
partition_by: ''
|
||||
flush_interval_milliseconds: 1000
|
||||
|
||||
# Parameters for embedded dictionaries, used in Yandex.Metrica.
|
||||
# See https://clickhouse.yandex/docs/en/dicts/internal_dicts/
|
||||
|
||||
# Path to file with region hierarchy.
|
||||
# path_to_regions_hierarchy_file: /opt/geo/regions_hierarchy.txt
|
||||
|
||||
# Path to directory with files containing names of regions
|
||||
# path_to_regions_names_files: /opt/geo/
|
||||
|
||||
|
||||
# top_level_domains_path: /var/lib/clickhouse/top_level_domains/
|
||||
# Custom TLD lists.
|
||||
# Format: name: /path/to/file
|
||||
|
||||
# Changes will not be applied w/o server restart.
|
||||
# Path to the list is under top_level_domains_path (see above).
|
||||
top_level_domains_lists: ''
|
||||
|
||||
# public_suffix_list: /path/to/public_suffix_list.dat
|
||||
|
||||
# Configuration of external dictionaries. See:
|
||||
# https://clickhouse.tech/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts
|
||||
dictionaries_config: '*_dictionary.xml'
|
||||
|
||||
# Uncomment if you want data to be compressed 30-100% better.
|
||||
# Don't do that if you just started using ClickHouse.
|
||||
|
||||
# compression:
|
||||
# # Set of variants. Checked in order. Last matching case wins. If nothing matches, lz4 will be used.
|
||||
# case:
|
||||
# Conditions. All must be satisfied. Some conditions may be omitted.
|
||||
# # min_part_size: 10000000000 # Min part size in bytes.
|
||||
# # min_part_size_ratio: 0.01 # Min size of part relative to whole table size.
|
||||
# # What compression method to use.
|
||||
# method: zstd
|
||||
|
||||
# Allow to execute distributed DDL queries (CREATE, DROP, ALTER, RENAME) on cluster.
|
||||
# Works only if ZooKeeper is enabled. Comment it if such functionality isn't required.
|
||||
distributed_ddl:
|
||||
# Path in ZooKeeper to queue with DDL queries
|
||||
path: /clickhouse/task_queue/ddl
|
||||
|
||||
# Settings from this profile will be used to execute DDL queries
|
||||
# profile: default
|
||||
|
||||
# Controls how much ON CLUSTER queries can be run simultaneously.
|
||||
# pool_size: 1
|
||||
|
||||
# Cleanup settings (active tasks will not be removed)
|
||||
|
||||
# Controls task TTL (default 1 week)
|
||||
# task_max_lifetime: 604800
|
||||
|
||||
# Controls how often cleanup should be performed (in seconds)
|
||||
# cleanup_delay_period: 60
|
||||
|
||||
# Controls how many tasks could be in the queue
|
||||
# max_tasks_in_queue: 1000
|
||||
|
||||
# Settings to fine tune MergeTree tables. See documentation in source code, in MergeTreeSettings.h
|
||||
# merge_tree:
|
||||
# max_suspicious_broken_parts: 5
|
||||
|
||||
# Protection from accidental DROP.
|
||||
# If size of a MergeTree table is greater than max_table_size_to_drop (in bytes) than table could not be dropped with any DROP query.
|
||||
# If you want do delete one table and don't want to change clickhouse-server config, you could create special file <clickhouse-path>/flags/force_drop_table and make DROP once.
|
||||
# By default max_table_size_to_drop is 50GB; max_table_size_to_drop=0 allows to DROP any tables.
|
||||
# The same for max_partition_size_to_drop.
|
||||
# Uncomment to disable protection.
|
||||
|
||||
# max_table_size_to_drop: 0
|
||||
# max_partition_size_to_drop: 0
|
||||
|
||||
# Example of parameters for GraphiteMergeTree table engine
|
||||
graphite_rollup_example:
|
||||
pattern:
|
||||
regexp: click_cost
|
||||
function: any
|
||||
retention:
|
||||
- age: 0
|
||||
precision: 3600
|
||||
- age: 86400
|
||||
precision: 60
|
||||
default:
|
||||
function: max
|
||||
retention:
|
||||
- age: 0
|
||||
precision: 60
|
||||
- age: 3600
|
||||
precision: 300
|
||||
- age: 86400
|
||||
precision: 3600
|
||||
|
||||
# Directory in <clickhouse-path> containing schema files for various input formats.
|
||||
# The directory will be created if it doesn't exist.
|
||||
format_schema_path: /var/lib/clickhouse/format_schemas/
|
||||
|
||||
# Default query masking rules, matching lines would be replaced with something else in the logs
|
||||
# (both text logs and system.query_log).
|
||||
# name - name for the rule (optional)
|
||||
# regexp - RE2 compatible regular expression (mandatory)
|
||||
# replace - substitution string for sensitive data (optional, by default - six asterisks)
|
||||
query_masking_rules:
|
||||
rule:
|
||||
name: hide encrypt/decrypt arguments
|
||||
regexp: '((?:aes_)?(?:encrypt|decrypt)(?:_mysql)?)\s*\(\s*(?:''(?:\\''|.)+''|.*?)\s*\)'
|
||||
# or more secure, but also more invasive:
|
||||
# (aes_\w+)\s*\(.*\)
|
||||
replace: \1(???)
|
||||
|
||||
# Uncomment to use custom http handlers.
|
||||
# rules are checked from top to bottom, first match runs the handler
|
||||
# url - to match request URL, you can use 'regex:' prefix to use regex match(optional)
|
||||
# methods - to match request method, you can use commas to separate multiple method matches(optional)
|
||||
# headers - to match request headers, match each child element(child element name is header name), you can use 'regex:' prefix to use regex match(optional)
|
||||
# handler is request handler
|
||||
# type - supported types: static, dynamic_query_handler, predefined_query_handler
|
||||
# query - use with predefined_query_handler type, executes query when the handler is called
|
||||
# query_param_name - use with dynamic_query_handler type, extracts and executes the value corresponding to the <query_param_name> value in HTTP request params
|
||||
# status - use with static type, response status code
|
||||
# content_type - use with static type, response content-type
|
||||
# response_content - use with static type, Response content sent to client, when using the prefix 'file://' or 'config://', find the content from the file or configuration send to client.
|
||||
|
||||
# http_handlers:
|
||||
# - rule:
|
||||
# url: /
|
||||
# methods: POST,GET
|
||||
# headers:
|
||||
# pragma: no-cache
|
||||
# handler:
|
||||
# type: dynamic_query_handler
|
||||
# query_param_name: query
|
||||
# - rule:
|
||||
# url: /predefined_query
|
||||
# methods: POST,GET
|
||||
# handler:
|
||||
# type: predefined_query_handler
|
||||
# query: 'SELECT * FROM system.settings'
|
||||
# - rule:
|
||||
# handler:
|
||||
# type: static
|
||||
# status: 200
|
||||
# content_type: 'text/plain; charset=UTF-8'
|
||||
# response_content: config://http_server_default_response
|
||||
|
||||
send_crash_reports:
|
||||
# Changing <enabled> to true allows sending crash reports to
|
||||
# the ClickHouse core developers team via Sentry https://sentry.io
|
||||
# Doing so at least in pre-production environments is highly appreciated
|
||||
enabled: false
|
||||
# Change <anonymize> to true if you don't feel comfortable attaching the server hostname to the crash report
|
||||
anonymize: false
|
||||
# Default endpoint should be changed to different Sentry DSN only if you have
|
||||
# some in-house engineers or hired consultants who're going to debug ClickHouse issues for you
|
||||
endpoint: 'https://6f33034cfe684dd7a3ab9875e57b1c8d@o388870.ingest.sentry.io/5226277'
|
||||
# Uncomment to disable ClickHouse internal DNS caching.
|
||||
# disable_internal_dns_cache: 1
|
107
programs/server/users.yaml.example
Normal file
107
programs/server/users.yaml.example
Normal file
@ -0,0 +1,107 @@
|
||||
# Profiles of settings.
|
||||
profiles:
|
||||
# Default settings.
|
||||
default:
|
||||
# Maximum memory usage for processing single query, in bytes.
|
||||
max_memory_usage: 10000000000
|
||||
|
||||
# How to choose between replicas during distributed query processing.
|
||||
# random - choose random replica from set of replicas with minimum number of errors
|
||||
# nearest_hostname - from set of replicas with minimum number of errors, choose replica
|
||||
# with minimum number of different symbols between replica's hostname and local hostname (Hamming distance).
|
||||
# in_order - first live replica is chosen in specified order.
|
||||
# first_or_random - if first replica one has higher number of errors, pick a random one from replicas with minimum number of errors.
|
||||
load_balancing: random
|
||||
|
||||
# Profile that allows only read queries.
|
||||
readonly:
|
||||
readonly: 1
|
||||
|
||||
# Users and ACL.
|
||||
users:
|
||||
# If user name was not specified, 'default' user is used.
|
||||
default:
|
||||
# Password could be specified in plaintext or in SHA256 (in hex format).
|
||||
#
|
||||
# If you want to specify password in plaintext (not recommended), place it in 'password' element.
|
||||
# Example: password: qwerty
|
||||
# Password could be empty.
|
||||
#
|
||||
# If you want to specify SHA256, place it in 'password_sha256_hex' element.
|
||||
# Example: password_sha256_hex: 65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5
|
||||
# Restrictions of SHA256: impossibility to connect to ClickHouse using MySQL JS client (as of July 2019).
|
||||
#
|
||||
# If you want to specify double SHA1, place it in 'password_double_sha1_hex' element.
|
||||
# Example: password_double_sha1_hex: e395796d6546b1b65db9d665cd43f0e858dd4303
|
||||
#
|
||||
# If you want to specify a previously defined LDAP server (see 'ldap_servers' in the main config) for authentication,
|
||||
# place its name in 'server' element inside 'ldap' element.
|
||||
# Example: ldap:
|
||||
# server: my_ldap_server
|
||||
#
|
||||
# If you want to authenticate the user via Kerberos (assuming Kerberos is enabled, see 'kerberos' in the main config),
|
||||
# place 'kerberos' element instead of 'password' (and similar) elements.
|
||||
# The name part of the canonical principal name of the initiator must match the user name for authentication to succeed.
|
||||
# You can also place 'realm' element inside 'kerberos' element to further restrict authentication to only those requests
|
||||
# whose initiator's realm matches it.
|
||||
# Example: kerberos: ''
|
||||
# Example: kerberos:
|
||||
# realm: EXAMPLE.COM
|
||||
#
|
||||
# How to generate decent password:
|
||||
# Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
|
||||
# In first line will be password and in second - corresponding SHA256.
|
||||
#
|
||||
# How to generate double SHA1:
|
||||
# Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha1sum | tr -d '-' | xxd -r -p | sha1sum | tr -d '-'
|
||||
# In first line will be password and in second - corresponding double SHA1.
|
||||
|
||||
password: ''
|
||||
|
||||
# List of networks with open access.
|
||||
#
|
||||
# To open access from everywhere, specify:
|
||||
# - ip: '::/0'
|
||||
#
|
||||
# To open access only from localhost, specify:
|
||||
# - ip: '::1'
|
||||
# - ip: 127.0.0.1
|
||||
#
|
||||
# Each element of list has one of the following forms:
|
||||
# ip: IP-address or network mask. Examples: 213.180.204.3 or 10.0.0.1/8 or 10.0.0.1/255.255.255.0
|
||||
# 2a02:6b8::3 or 2a02:6b8::3/64 or 2a02:6b8::3/ffff:ffff:ffff:ffff::.
|
||||
# host: Hostname. Example: server01.yandex.ru.
|
||||
# To check access, DNS query is performed, and all received addresses compared to peer address.
|
||||
# host_regexp: Regular expression for host names. Example, ^server\d\d-\d\d-\d\.yandex\.ru$
|
||||
# To check access, DNS PTR query is performed for peer address and then regexp is applied.
|
||||
# Then, for result of PTR query, another DNS query is performed and all received addresses compared to peer address.
|
||||
# Strongly recommended that regexp is ends with $ and take all expression in ''
|
||||
# All results of DNS requests are cached till server restart.
|
||||
|
||||
networks:
|
||||
ip: '::/0'
|
||||
|
||||
# Settings profile for user.
|
||||
profile: default
|
||||
|
||||
# Quota for user.
|
||||
quota: default
|
||||
|
||||
# User can create other users and grant rights to them.
|
||||
# access_management: 1
|
||||
|
||||
# Quotas.
|
||||
quotas:
|
||||
# Name of quota.
|
||||
default:
|
||||
# Limits for time interval. You could specify many intervals with different limits.
|
||||
interval:
|
||||
# Length of interval.
|
||||
duration: 3600
|
||||
|
||||
# No limits. Just calculate resource usage for time interval.
|
||||
queries: 0
|
||||
errors: 0
|
||||
result_rows: 0
|
||||
read_rows: 0
|
||||
execution_time: 0
|
@ -143,11 +143,13 @@ ContextAccess::ContextAccess(const AccessControlManager & manager_, const Params
|
||||
: manager(&manager_)
|
||||
, params(params_)
|
||||
{
|
||||
std::lock_guard lock{mutex};
|
||||
|
||||
subscription_for_user_change = manager->subscribeForChanges(
|
||||
*params.user_id, [this](const UUID &, const AccessEntityPtr & entity)
|
||||
{
|
||||
UserPtr changed_user = entity ? typeid_cast<UserPtr>(entity) : nullptr;
|
||||
std::lock_guard lock{mutex};
|
||||
std::lock_guard lock2{mutex};
|
||||
setUser(changed_user);
|
||||
});
|
||||
|
||||
@ -189,7 +191,7 @@ void ContextAccess::setUser(const UserPtr & user_) const
|
||||
current_roles_with_admin_option = user->granted_roles.findGrantedWithAdminOption(params.current_roles);
|
||||
}
|
||||
|
||||
subscription_for_roles_changes = {};
|
||||
subscription_for_roles_changes.reset();
|
||||
enabled_roles = manager->getEnabledRoles(current_roles, current_roles_with_admin_option);
|
||||
subscription_for_roles_changes = enabled_roles->subscribeForChanges([this](const std::shared_ptr<const EnabledRolesInfo> & roles_info_)
|
||||
{
|
||||
|
@ -20,13 +20,42 @@ namespace ErrorCodes
|
||||
namespace
|
||||
{
|
||||
|
||||
auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const String & name)
|
||||
void parseLDAPSearchParams(LDAPClient::SearchParams & params, const Poco::Util::AbstractConfiguration & config, const String & prefix)
|
||||
{
|
||||
const bool has_base_dn = config.has(prefix + ".base_dn");
|
||||
const bool has_search_filter = config.has(prefix + ".search_filter");
|
||||
const bool has_attribute = config.has(prefix + ".attribute");
|
||||
const bool has_scope = config.has(prefix + ".scope");
|
||||
|
||||
if (has_base_dn)
|
||||
params.base_dn = config.getString(prefix + ".base_dn");
|
||||
|
||||
if (has_search_filter)
|
||||
params.search_filter = config.getString(prefix + ".search_filter");
|
||||
|
||||
if (has_attribute)
|
||||
params.attribute = config.getString(prefix + ".attribute");
|
||||
|
||||
if (has_scope)
|
||||
{
|
||||
auto scope = config.getString(prefix + ".scope");
|
||||
boost::algorithm::to_lower(scope);
|
||||
|
||||
if (scope == "base") params.scope = LDAPClient::SearchParams::Scope::BASE;
|
||||
else if (scope == "one_level") params.scope = LDAPClient::SearchParams::Scope::ONE_LEVEL;
|
||||
else if (scope == "subtree") params.scope = LDAPClient::SearchParams::Scope::SUBTREE;
|
||||
else if (scope == "children") params.scope = LDAPClient::SearchParams::Scope::CHILDREN;
|
||||
else
|
||||
throw Exception("Invalid value for 'scope' field of LDAP search parameters in '" + prefix +
|
||||
"' section, must be one of 'base', 'one_level', 'subtree', or 'children'", ErrorCodes::BAD_ARGUMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
void parseLDAPServer(LDAPClient::Params & params, const Poco::Util::AbstractConfiguration & config, const String & name)
|
||||
{
|
||||
if (name.empty())
|
||||
throw Exception("LDAP server name cannot be empty", ErrorCodes::BAD_ARGUMENTS);
|
||||
|
||||
LDAPClient::Params params;
|
||||
|
||||
const String ldap_server_config = "ldap_servers." + name;
|
||||
|
||||
const bool has_host = config.has(ldap_server_config + ".host");
|
||||
@ -34,6 +63,7 @@ auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const Str
|
||||
const bool has_bind_dn = config.has(ldap_server_config + ".bind_dn");
|
||||
const bool has_auth_dn_prefix = config.has(ldap_server_config + ".auth_dn_prefix");
|
||||
const bool has_auth_dn_suffix = config.has(ldap_server_config + ".auth_dn_suffix");
|
||||
const bool has_user_dn_detection = config.has(ldap_server_config + ".user_dn_detection");
|
||||
const bool has_verification_cooldown = config.has(ldap_server_config + ".verification_cooldown");
|
||||
const bool has_enable_tls = config.has(ldap_server_config + ".enable_tls");
|
||||
const bool has_tls_minimum_protocol_version = config.has(ldap_server_config + ".tls_minimum_protocol_version");
|
||||
@ -66,6 +96,17 @@ auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const Str
|
||||
params.bind_dn = auth_dn_prefix + "{user_name}" + auth_dn_suffix;
|
||||
}
|
||||
|
||||
if (has_user_dn_detection)
|
||||
{
|
||||
if (!params.user_dn_detection)
|
||||
{
|
||||
params.user_dn_detection.emplace();
|
||||
params.user_dn_detection->attribute = "dn";
|
||||
}
|
||||
|
||||
parseLDAPSearchParams(*params.user_dn_detection, config, ldap_server_config + ".user_dn_detection");
|
||||
}
|
||||
|
||||
if (has_verification_cooldown)
|
||||
params.verification_cooldown = std::chrono::seconds{config.getUInt64(ldap_server_config + ".verification_cooldown")};
|
||||
|
||||
@ -143,14 +184,10 @@ auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const Str
|
||||
}
|
||||
else
|
||||
params.port = (params.enable_tls == LDAPClient::Params::TLSEnable::YES ? 636 : 389);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
auto parseKerberosParams(const Poco::Util::AbstractConfiguration & config)
|
||||
void parseKerberosParams(GSSAcceptorContext::Params & params, const Poco::Util::AbstractConfiguration & config)
|
||||
{
|
||||
GSSAcceptorContext::Params params;
|
||||
|
||||
Poco::Util::AbstractConfiguration::Keys keys;
|
||||
config.keys("kerberos", keys);
|
||||
|
||||
@ -180,12 +217,20 @@ auto parseKerberosParams(const Poco::Util::AbstractConfiguration & config)
|
||||
|
||||
params.realm = config.getString("kerberos.realm", "");
|
||||
params.principal = config.getString("kerberos.principal", "");
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void parseLDAPRoleSearchParams(LDAPClient::RoleSearchParams & params, const Poco::Util::AbstractConfiguration & config, const String & prefix)
|
||||
{
|
||||
parseLDAPSearchParams(params, config, prefix);
|
||||
|
||||
const bool has_prefix = config.has(prefix + ".prefix");
|
||||
|
||||
if (has_prefix)
|
||||
params.prefix = config.getString(prefix + ".prefix");
|
||||
}
|
||||
|
||||
void ExternalAuthenticators::reset()
|
||||
{
|
||||
std::scoped_lock lock(mutex);
|
||||
@ -229,7 +274,8 @@ void ExternalAuthenticators::setConfiguration(const Poco::Util::AbstractConfigur
|
||||
{
|
||||
try
|
||||
{
|
||||
ldap_client_params_blueprint.insert_or_assign(ldap_server_name, parseLDAPServer(config, ldap_server_name));
|
||||
ldap_client_params_blueprint.erase(ldap_server_name);
|
||||
parseLDAPServer(ldap_client_params_blueprint.emplace(ldap_server_name, LDAPClient::Params{}).first->second, config, ldap_server_name);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -240,7 +286,7 @@ void ExternalAuthenticators::setConfiguration(const Poco::Util::AbstractConfigur
|
||||
try
|
||||
{
|
||||
if (kerberos_keys_count > 0)
|
||||
kerberos_params = parseKerberosParams(config);
|
||||
parseKerberosParams(kerberos_params.emplace(), config);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -249,7 +295,7 @@ void ExternalAuthenticators::setConfiguration(const Poco::Util::AbstractConfigur
|
||||
}
|
||||
|
||||
bool ExternalAuthenticators::checkLDAPCredentials(const String & server, const BasicCredentials & credentials,
|
||||
const LDAPClient::SearchParamsList * search_params, LDAPClient::SearchResultsList * search_results) const
|
||||
const LDAPClient::RoleSearchParamsList * role_search_params, LDAPClient::SearchResultsList * role_search_results) const
|
||||
{
|
||||
std::optional<LDAPClient::Params> params;
|
||||
std::size_t params_hash = 0;
|
||||
@ -267,9 +313,9 @@ bool ExternalAuthenticators::checkLDAPCredentials(const String & server, const B
|
||||
params->password = credentials.getPassword();
|
||||
|
||||
params->combineCoreHash(params_hash);
|
||||
if (search_params)
|
||||
if (role_search_params)
|
||||
{
|
||||
for (const auto & params_instance : *search_params)
|
||||
for (const auto & params_instance : *role_search_params)
|
||||
{
|
||||
params_instance.combineHash(params_hash);
|
||||
}
|
||||
@ -301,14 +347,14 @@ bool ExternalAuthenticators::checkLDAPCredentials(const String & server, const B
|
||||
|
||||
// Ensure that search_params are compatible.
|
||||
(
|
||||
search_params == nullptr ?
|
||||
entry.last_successful_search_results.empty() :
|
||||
search_params->size() == entry.last_successful_search_results.size()
|
||||
role_search_params == nullptr ?
|
||||
entry.last_successful_role_search_results.empty() :
|
||||
role_search_params->size() == entry.last_successful_role_search_results.size()
|
||||
)
|
||||
)
|
||||
{
|
||||
if (search_results)
|
||||
*search_results = entry.last_successful_search_results;
|
||||
if (role_search_results)
|
||||
*role_search_results = entry.last_successful_role_search_results;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -326,7 +372,7 @@ bool ExternalAuthenticators::checkLDAPCredentials(const String & server, const B
|
||||
}
|
||||
|
||||
LDAPSimpleAuthClient client(params.value());
|
||||
const auto result = client.authenticate(search_params, search_results);
|
||||
const auto result = client.authenticate(role_search_params, role_search_results);
|
||||
const auto current_check_timestamp = std::chrono::steady_clock::now();
|
||||
|
||||
// Update the cache, but only if this is the latest check and the server is still configured in a compatible way.
|
||||
@ -345,9 +391,9 @@ bool ExternalAuthenticators::checkLDAPCredentials(const String & server, const B
|
||||
|
||||
std::size_t new_params_hash = 0;
|
||||
new_params.combineCoreHash(new_params_hash);
|
||||
if (search_params)
|
||||
if (role_search_params)
|
||||
{
|
||||
for (const auto & params_instance : *search_params)
|
||||
for (const auto & params_instance : *role_search_params)
|
||||
{
|
||||
params_instance.combineHash(new_params_hash);
|
||||
}
|
||||
@ -363,17 +409,17 @@ bool ExternalAuthenticators::checkLDAPCredentials(const String & server, const B
|
||||
entry.last_successful_params_hash = params_hash;
|
||||
entry.last_successful_authentication_timestamp = current_check_timestamp;
|
||||
|
||||
if (search_results)
|
||||
entry.last_successful_search_results = *search_results;
|
||||
if (role_search_results)
|
||||
entry.last_successful_role_search_results = *role_search_results;
|
||||
else
|
||||
entry.last_successful_search_results.clear();
|
||||
entry.last_successful_role_search_results.clear();
|
||||
}
|
||||
else if (
|
||||
entry.last_successful_params_hash != params_hash ||
|
||||
(
|
||||
search_params == nullptr ?
|
||||
!entry.last_successful_search_results.empty() :
|
||||
search_params->size() != entry.last_successful_search_results.size()
|
||||
role_search_params == nullptr ?
|
||||
!entry.last_successful_role_search_results.empty() :
|
||||
role_search_params->size() != entry.last_successful_role_search_results.size()
|
||||
)
|
||||
)
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
|
||||
// The name and readiness of the credentials must be verified before calling these.
|
||||
bool checkLDAPCredentials(const String & server, const BasicCredentials & credentials,
|
||||
const LDAPClient::SearchParamsList * search_params = nullptr, LDAPClient::SearchResultsList * search_results = nullptr) const;
|
||||
const LDAPClient::RoleSearchParamsList * role_search_params = nullptr, LDAPClient::SearchResultsList * role_search_results = nullptr) const;
|
||||
bool checkKerberosCredentials(const String & realm, const GSSAcceptorContext & credentials) const;
|
||||
|
||||
GSSAcceptorContext::Params getKerberosParams() const;
|
||||
@ -44,7 +44,7 @@ private:
|
||||
{
|
||||
std::size_t last_successful_params_hash = 0;
|
||||
std::chrono::steady_clock::time_point last_successful_authentication_timestamp;
|
||||
LDAPClient::SearchResultsList last_successful_search_results;
|
||||
LDAPClient::SearchResultsList last_successful_role_search_results;
|
||||
};
|
||||
|
||||
using LDAPCache = std::unordered_map<String, LDAPCacheEntry>; // user name -> cache entry
|
||||
@ -58,4 +58,6 @@ private:
|
||||
std::optional<GSSAcceptorContext::Params> kerberos_params;
|
||||
};
|
||||
|
||||
void parseLDAPRoleSearchParams(LDAPClient::RoleSearchParams & params, const Poco::Util::AbstractConfiguration & config, const String & prefix);
|
||||
|
||||
}
|
||||
|
@ -68,34 +68,15 @@ void LDAPAccessStorage::setConfiguration(AccessControlManager * access_control_m
|
||||
common_roles_cfg.insert(role_names.begin(), role_names.end());
|
||||
}
|
||||
|
||||
LDAPClient::SearchParamsList role_search_params_cfg;
|
||||
LDAPClient::RoleSearchParamsList role_search_params_cfg;
|
||||
if (has_role_mapping)
|
||||
{
|
||||
Poco::Util::AbstractConfiguration::Keys all_keys;
|
||||
config.keys(prefix, all_keys);
|
||||
for (const auto & key : all_keys)
|
||||
{
|
||||
if (key != "role_mapping" && key.find("role_mapping[") != 0)
|
||||
continue;
|
||||
|
||||
const String rm_prefix = prefix_str + key;
|
||||
const String rm_prefix_str = rm_prefix + '.';
|
||||
role_search_params_cfg.emplace_back();
|
||||
auto & rm_params = role_search_params_cfg.back();
|
||||
|
||||
rm_params.base_dn = config.getString(rm_prefix_str + "base_dn", "");
|
||||
rm_params.search_filter = config.getString(rm_prefix_str + "search_filter", "");
|
||||
rm_params.attribute = config.getString(rm_prefix_str + "attribute", "cn");
|
||||
rm_params.prefix = config.getString(rm_prefix_str + "prefix", "");
|
||||
|
||||
auto scope = config.getString(rm_prefix_str + "scope", "subtree");
|
||||
boost::algorithm::to_lower(scope);
|
||||
if (scope == "base") rm_params.scope = LDAPClient::SearchParams::Scope::BASE;
|
||||
else if (scope == "one_level") rm_params.scope = LDAPClient::SearchParams::Scope::ONE_LEVEL;
|
||||
else if (scope == "subtree") rm_params.scope = LDAPClient::SearchParams::Scope::SUBTREE;
|
||||
else if (scope == "children") rm_params.scope = LDAPClient::SearchParams::Scope::CHILDREN;
|
||||
else
|
||||
throw Exception("Invalid value of 'scope' field in '" + key + "' section of LDAP user directory, must be one of 'base', 'one_level', 'subtree', or 'children'", ErrorCodes::BAD_ARGUMENTS);
|
||||
if (key == "role_mapping" || key.find("role_mapping[") == 0)
|
||||
parseLDAPRoleSearchParams(role_search_params_cfg.emplace_back(), config, prefix_str + key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,7 +345,7 @@ std::set<String> LDAPAccessStorage::mapExternalRolesNoLock(const LDAPClient::Sea
|
||||
|
||||
|
||||
bool LDAPAccessStorage::areLDAPCredentialsValidNoLock(const User & user, const Credentials & credentials,
|
||||
const ExternalAuthenticators & external_authenticators, LDAPClient::SearchResultsList & search_results) const
|
||||
const ExternalAuthenticators & external_authenticators, LDAPClient::SearchResultsList & role_search_results) const
|
||||
{
|
||||
if (!credentials.isReady())
|
||||
return false;
|
||||
@ -373,7 +354,7 @@ bool LDAPAccessStorage::areLDAPCredentialsValidNoLock(const User & user, const C
|
||||
return false;
|
||||
|
||||
if (const auto * basic_credentials = dynamic_cast<const BasicCredentials *>(&credentials))
|
||||
return external_authenticators.checkLDAPCredentials(ldap_server_name, *basic_credentials, &role_search_params, &search_results);
|
||||
return external_authenticators.checkLDAPCredentials(ldap_server_name, *basic_credentials, &role_search_params, &role_search_results);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user