mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 10:02:01 +00:00
Merge branch 'master' into vcol
This commit is contained in:
commit
5aa9dae09b
@ -731,7 +731,13 @@ The names given to the described entities can be found in the system tables, [sy
|
|||||||
|
|
||||||
### Configuration {#table_engine-mergetree-multiple-volumes_configure}
|
### Configuration {#table_engine-mergetree-multiple-volumes_configure}
|
||||||
|
|
||||||
Disks, volumes and storage policies should be declared inside the `<storage_configuration>` tag either in the main file `config.xml` or in a distinct file in the `config.d` directory.
|
Disks, volumes and storage policies should be declared inside the `<storage_configuration>` tag either in a file in the `config.d` directory.
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
Disks can also be declared in the `SETTINGS` section of a query. This is useful
|
||||||
|
for adhoc analysis to temporarily attach a disk that is, for example, hosted at a URL.
|
||||||
|
See [dynamic storage](#dynamic-storage) for more details.
|
||||||
|
:::
|
||||||
|
|
||||||
Configuration structure:
|
Configuration structure:
|
||||||
|
|
||||||
@ -876,6 +882,87 @@ You could change storage policy after table creation with [ALTER TABLE ... MODIF
|
|||||||
|
|
||||||
The number of threads performing background moves of data parts can be changed by [background_move_pool_size](/docs/en/operations/server-configuration-parameters/settings.md/#background_move_pool_size) setting.
|
The number of threads performing background moves of data parts can be changed by [background_move_pool_size](/docs/en/operations/server-configuration-parameters/settings.md/#background_move_pool_size) setting.
|
||||||
|
|
||||||
|
### Dynamic Storage
|
||||||
|
|
||||||
|
This example query shows how to attach a table stored at a URL and configure the
|
||||||
|
remote storage within the query. The web storage is not configured in the ClickHouse
|
||||||
|
configuration files; all the settings are in the CREATE/ATTACH query.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
The example uses `type=web`, but any disk type can be configured as dynamic, even Local disk. Local disks require a path argument to be inside the server config parameter `custom_local_disks_base_directory`, which has no default, so set that also when using local disk.
|
||||||
|
:::
|
||||||
|
|
||||||
|
```sql
|
||||||
|
ATTACH TABLE uk_price_paid UUID 'cf712b4f-2ca8-435c-ac23-c4393efe52f7'
|
||||||
|
(
|
||||||
|
price UInt32,
|
||||||
|
date Date,
|
||||||
|
postcode1 LowCardinality(String),
|
||||||
|
postcode2 LowCardinality(String),
|
||||||
|
type Enum8('other' = 0, 'terraced' = 1, 'semi-detached' = 2, 'detached' = 3, 'flat' = 4),
|
||||||
|
is_new UInt8,
|
||||||
|
duration Enum8('unknown' = 0, 'freehold' = 1, 'leasehold' = 2),
|
||||||
|
addr1 String,
|
||||||
|
addr2 String,
|
||||||
|
street LowCardinality(String),
|
||||||
|
locality LowCardinality(String),
|
||||||
|
town LowCardinality(String),
|
||||||
|
district LowCardinality(String),
|
||||||
|
county LowCardinality(String)
|
||||||
|
)
|
||||||
|
ENGINE = MergeTree
|
||||||
|
ORDER BY (postcode1, postcode2, addr1, addr2)
|
||||||
|
# highlight-start
|
||||||
|
SETTINGS disk = disk(
|
||||||
|
type=web,
|
||||||
|
endpoint='https://raw.githubusercontent.com/ClickHouse/web-tables-demo/main/web/'
|
||||||
|
);
|
||||||
|
# highlight-end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nested Dynamic Storage
|
||||||
|
|
||||||
|
This example query builds on the above dynamic disk configuration and shows how to
|
||||||
|
use a local disk to cache data from a table stored at a URL. Neither the cache disk
|
||||||
|
nor the web storage is configured in the ClickHouse configuration files; both are
|
||||||
|
configured in the CREATE/ATTACH query settings.
|
||||||
|
|
||||||
|
In the settings highlighted below notice that the disk of `type=web` is nested within
|
||||||
|
the disk of `type=cache`.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
ATTACH TABLE uk_price_paid UUID 'cf712b4f-2ca8-435c-ac23-c4393efe52f7'
|
||||||
|
(
|
||||||
|
price UInt32,
|
||||||
|
date Date,
|
||||||
|
postcode1 LowCardinality(String),
|
||||||
|
postcode2 LowCardinality(String),
|
||||||
|
type Enum8('other' = 0, 'terraced' = 1, 'semi-detached' = 2, 'detached' = 3, 'flat' = 4),
|
||||||
|
is_new UInt8,
|
||||||
|
duration Enum8('unknown' = 0, 'freehold' = 1, 'leasehold' = 2),
|
||||||
|
addr1 String,
|
||||||
|
addr2 String,
|
||||||
|
street LowCardinality(String),
|
||||||
|
locality LowCardinality(String),
|
||||||
|
town LowCardinality(String),
|
||||||
|
district LowCardinality(String),
|
||||||
|
county LowCardinality(String)
|
||||||
|
)
|
||||||
|
ENGINE = MergeTree
|
||||||
|
ORDER BY (postcode1, postcode2, addr1, addr2)
|
||||||
|
# highlight-start
|
||||||
|
SETTINGS disk = disk(
|
||||||
|
type=cache,
|
||||||
|
max_size='1Gi',
|
||||||
|
path='/var/lib/clickhouse/custom_disk_cache/',
|
||||||
|
disk=disk(
|
||||||
|
type=web,
|
||||||
|
endpoint='https://raw.githubusercontent.com/ClickHouse/web-tables-demo/main/web/'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
# highlight-end
|
||||||
|
```
|
||||||
|
|
||||||
### Details {#details}
|
### Details {#details}
|
||||||
|
|
||||||
In the case of `MergeTree` tables, data is getting to disk in different ways:
|
In the case of `MergeTree` tables, data is getting to disk in different ways:
|
||||||
|
@ -49,6 +49,8 @@ class IColumn;
|
|||||||
M(MaxThreads, max_download_threads, 4, "The maximum number of threads to download data (e.g. for URL engine).", 0) \
|
M(MaxThreads, max_download_threads, 4, "The maximum number of threads to download data (e.g. for URL engine).", 0) \
|
||||||
M(UInt64, max_download_buffer_size, 10*1024*1024, "The maximal size of buffer for parallel downloading (e.g. for URL engine) per each thread.", 0) \
|
M(UInt64, max_download_buffer_size, 10*1024*1024, "The maximal size of buffer for parallel downloading (e.g. for URL engine) per each thread.", 0) \
|
||||||
M(UInt64, max_read_buffer_size, DBMS_DEFAULT_BUFFER_SIZE, "The maximum size of the buffer to read from the filesystem.", 0) \
|
M(UInt64, max_read_buffer_size, DBMS_DEFAULT_BUFFER_SIZE, "The maximum size of the buffer to read from the filesystem.", 0) \
|
||||||
|
M(UInt64, max_read_buffer_size_local_fs, 128*1024, "The maximum size of the buffer to read from local filesystem. If set to 0 then max_read_buffer_size will be used.", 0) \
|
||||||
|
M(UInt64, max_read_buffer_size_remote_fs, 0, "The maximum size of the buffer to read from remote filesystem. If set to 0 then max_read_buffer_size will be used.", 0) \
|
||||||
M(UInt64, max_distributed_connections, 1024, "The maximum number of connections for distributed processing of one query (should be greater than max_threads).", 0) \
|
M(UInt64, max_distributed_connections, 1024, "The maximum number of connections for distributed processing of one query (should be greater than max_threads).", 0) \
|
||||||
M(UInt64, max_query_size, DBMS_DEFAULT_MAX_QUERY_SIZE, "The maximum number of bytes of a query string parsed by the SQL parser. Data in the VALUES clause of INSERT queries is processed by a separate stream parser (that consumes O(1) RAM) and not affected by this restriction.", 0) \
|
M(UInt64, max_query_size, DBMS_DEFAULT_MAX_QUERY_SIZE, "The maximum number of bytes of a query string parsed by the SQL parser. Data in the VALUES clause of INSERT queries is processed by a separate stream parser (that consumes O(1) RAM) and not affected by this restriction.", 0) \
|
||||||
M(UInt64, interactive_delay, 100000, "The interval in microseconds to check if the request is cancelled, and to send progress info.", 0) \
|
M(UInt64, interactive_delay, 100000, "The interval in microseconds to check if the request is cancelled, and to send progress info.", 0) \
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#if USE_BROTLI
|
#if USE_BROTLI
|
||||||
# include <brotli/decode.h>
|
# include <brotli/decode.h>
|
||||||
# include "BrotliReadBuffer.h"
|
# include "BrotliReadBuffer.h"
|
||||||
|
# include <IO/WithFileName.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -60,7 +61,10 @@ bool BrotliReadBuffer::nextImpl()
|
|||||||
|
|
||||||
if (brotli->result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT && (!in_available || in->eof()))
|
if (brotli->result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT && (!in_available || in->eof()))
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::BROTLI_READ_FAILED, "brotli decode error");
|
throw Exception(
|
||||||
|
ErrorCodes::BROTLI_READ_FAILED,
|
||||||
|
"brotli decode error{}",
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
|
|
||||||
out_capacity = internal_buffer.size();
|
out_capacity = internal_buffer.size();
|
||||||
@ -83,13 +87,19 @@ bool BrotliReadBuffer::nextImpl()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::BROTLI_READ_FAILED, "brotli decode error");
|
throw Exception(
|
||||||
|
ErrorCodes::BROTLI_READ_FAILED,
|
||||||
|
"brotli decode error{}",
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (brotli->result == BROTLI_DECODER_RESULT_ERROR)
|
if (brotli->result == BROTLI_DECODER_RESULT_ERROR)
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::BROTLI_READ_FAILED, "brotli decode error");
|
throw Exception(
|
||||||
|
ErrorCodes::BROTLI_READ_FAILED,
|
||||||
|
"brotli decode error{}",
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#if USE_BZIP2
|
#if USE_BZIP2
|
||||||
# include <IO/Bzip2ReadBuffer.h>
|
# include <IO/Bzip2ReadBuffer.h>
|
||||||
# include <bzlib.h>
|
# include <bzlib.h>
|
||||||
|
# include <IO/WithFileName.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -118,13 +119,17 @@ bool Bzip2ReadBuffer::nextImpl()
|
|||||||
if (ret != BZ_OK)
|
if (ret != BZ_OK)
|
||||||
throw Exception(
|
throw Exception(
|
||||||
ErrorCodes::BZIP2_STREAM_DECODER_FAILED,
|
ErrorCodes::BZIP2_STREAM_DECODER_FAILED,
|
||||||
"bzip2 stream decoder failed: error code: {}",
|
"bzip2 stream decoder failed: error code: {}{}",
|
||||||
ret);
|
ret,
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
|
|
||||||
if (in->eof())
|
if (in->eof())
|
||||||
{
|
{
|
||||||
eof_flag = true;
|
eof_flag = true;
|
||||||
throw Exception(ErrorCodes::UNEXPECTED_END_OF_FILE, "Unexpected end of bzip2 archive");
|
throw Exception(
|
||||||
|
ErrorCodes::UNEXPECTED_END_OF_FILE,
|
||||||
|
"Unexpected end of bzip2 archive{}",
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "HadoopSnappyReadBuffer.h"
|
#include "HadoopSnappyReadBuffer.h"
|
||||||
|
|
||||||
|
#include <IO/WithFileName.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
@ -89,9 +91,8 @@ inline HadoopSnappyDecoder::Status HadoopSnappyDecoder::readCompressedLength(siz
|
|||||||
{
|
{
|
||||||
auto status = readLength(avail_in, next_in, &compressed_length);
|
auto status = readLength(avail_in, next_in, &compressed_length);
|
||||||
if (unlikely(compressed_length > 0 && static_cast<size_t>(compressed_length) > sizeof(buffer)))
|
if (unlikely(compressed_length > 0 && static_cast<size_t>(compressed_length) > sizeof(buffer)))
|
||||||
throw Exception(ErrorCodes::SNAPPY_UNCOMPRESS_FAILED,
|
return Status::TOO_LARGE_COMPRESSED_BLOCK;
|
||||||
"Too large snappy compressed block. buffer size: {}, compressed block size: {}",
|
|
||||||
sizeof(buffer), compressed_length);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
@ -196,7 +197,11 @@ bool HadoopSnappyReadBuffer::nextImpl()
|
|||||||
|
|
||||||
if (decoder->result == Status::NEEDS_MORE_INPUT && (!in_available || in->eof()))
|
if (decoder->result == Status::NEEDS_MORE_INPUT && (!in_available || in->eof()))
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::SNAPPY_UNCOMPRESS_FAILED, "hadoop snappy decode error: {}", statusToString(decoder->result));
|
throw Exception(
|
||||||
|
ErrorCodes::SNAPPY_UNCOMPRESS_FAILED,
|
||||||
|
"hadoop snappy decode error: {}{}",
|
||||||
|
statusToString(decoder->result),
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
|
|
||||||
out_capacity = internal_buffer.size();
|
out_capacity = internal_buffer.size();
|
||||||
@ -219,9 +224,13 @@ bool HadoopSnappyReadBuffer::nextImpl()
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (decoder->result == Status::INVALID_INPUT || decoder->result == Status::BUFFER_TOO_SMALL)
|
else if (decoder->result != Status::NEEDS_MORE_INPUT)
|
||||||
{
|
{
|
||||||
throw Exception(ErrorCodes::SNAPPY_UNCOMPRESS_FAILED, "hadoop snappy decode error: {}", statusToString(decoder->result));
|
throw Exception(
|
||||||
|
ErrorCodes::SNAPPY_UNCOMPRESS_FAILED,
|
||||||
|
"hadoop snappy decode error: {}{}",
|
||||||
|
statusToString(decoder->result),
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ public:
|
|||||||
INVALID_INPUT = 1,
|
INVALID_INPUT = 1,
|
||||||
BUFFER_TOO_SMALL = 2,
|
BUFFER_TOO_SMALL = 2,
|
||||||
NEEDS_MORE_INPUT = 3,
|
NEEDS_MORE_INPUT = 3,
|
||||||
|
TOO_LARGE_COMPRESSED_BLOCK = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
HadoopSnappyDecoder() = default;
|
HadoopSnappyDecoder() = default;
|
||||||
@ -84,6 +85,8 @@ public:
|
|||||||
return "BUFFER_TOO_SMALL";
|
return "BUFFER_TOO_SMALL";
|
||||||
case Status::NEEDS_MORE_INPUT:
|
case Status::NEEDS_MORE_INPUT:
|
||||||
return "NEEDS_MORE_INPUT";
|
return "NEEDS_MORE_INPUT";
|
||||||
|
case Status::TOO_LARGE_COMPRESSED_BLOCK:
|
||||||
|
return "TOO_LARGE_COMPRESSED_BLOCK";
|
||||||
}
|
}
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <IO/LZMAInflatingReadBuffer.h>
|
#include <IO/LZMAInflatingReadBuffer.h>
|
||||||
|
#include <IO/WithFileName.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -78,18 +79,20 @@ bool LZMAInflatingReadBuffer::nextImpl()
|
|||||||
{
|
{
|
||||||
throw Exception(
|
throw Exception(
|
||||||
ErrorCodes::LZMA_STREAM_DECODER_FAILED,
|
ErrorCodes::LZMA_STREAM_DECODER_FAILED,
|
||||||
"lzma decoder finished, but input stream has not exceeded: error code: {}; lzma version: {}",
|
"lzma decoder finished, but input stream has not exceeded: error code: {}; lzma version: {}{}",
|
||||||
ret,
|
ret,
|
||||||
LZMA_VERSION_STRING);
|
LZMA_VERSION_STRING,
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != LZMA_OK)
|
if (ret != LZMA_OK)
|
||||||
throw Exception(
|
throw Exception(
|
||||||
ErrorCodes::LZMA_STREAM_DECODER_FAILED,
|
ErrorCodes::LZMA_STREAM_DECODER_FAILED,
|
||||||
"lzma_stream_decoder failed: error code: error codeL {}; lzma version: {}",
|
"lzma_stream_decoder failed: error code: error code {}; lzma version: {}{}",
|
||||||
ret,
|
ret,
|
||||||
LZMA_VERSION_STRING);
|
LZMA_VERSION_STRING,
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <IO/Lz4InflatingReadBuffer.h>
|
#include <IO/Lz4InflatingReadBuffer.h>
|
||||||
|
#include <IO/WithFileName.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -72,9 +73,10 @@ bool Lz4InflatingReadBuffer::nextImpl()
|
|||||||
if (LZ4F_isError(ret))
|
if (LZ4F_isError(ret))
|
||||||
throw Exception(
|
throw Exception(
|
||||||
ErrorCodes::LZ4_DECODER_FAILED,
|
ErrorCodes::LZ4_DECODER_FAILED,
|
||||||
"LZ4 decompression failed. LZ4F version: {}. Error: {}",
|
"LZ4 decompression failed. LZ4F version: {}. Error: {}{}",
|
||||||
LZ4F_VERSION,
|
LZ4F_VERSION,
|
||||||
LZ4F_getErrorName(ret));
|
LZ4F_getErrorName(ret),
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
|
|
||||||
if (in->eof())
|
if (in->eof())
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,9 @@ struct ReadSettings
|
|||||||
/// Method to use reading from remote filesystem.
|
/// Method to use reading from remote filesystem.
|
||||||
RemoteFSReadMethod remote_fs_method = RemoteFSReadMethod::threadpool;
|
RemoteFSReadMethod remote_fs_method = RemoteFSReadMethod::threadpool;
|
||||||
|
|
||||||
size_t local_fs_buffer_size = DBMS_DEFAULT_BUFFER_SIZE;
|
/// https://eklitzke.org/efficient-file-copying-on-linux
|
||||||
|
size_t local_fs_buffer_size = 128 * 1024;
|
||||||
|
|
||||||
size_t remote_fs_buffer_size = DBMS_DEFAULT_BUFFER_SIZE;
|
size_t remote_fs_buffer_size = DBMS_DEFAULT_BUFFER_SIZE;
|
||||||
size_t prefetch_buffer_size = DBMS_DEFAULT_BUFFER_SIZE;
|
size_t prefetch_buffer_size = DBMS_DEFAULT_BUFFER_SIZE;
|
||||||
|
|
||||||
|
@ -26,4 +26,14 @@ String getFileNameFromReadBuffer(const ReadBuffer & in)
|
|||||||
return getFileName(in);
|
return getFileName(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getExceptionEntryWithFileName(const ReadBuffer & in)
|
||||||
|
{
|
||||||
|
auto filename = getFileNameFromReadBuffer(in);
|
||||||
|
|
||||||
|
if (filename.empty())
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return fmt::format("; While reading from: {}", filename);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,5 +14,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
String getFileNameFromReadBuffer(const ReadBuffer & in);
|
String getFileNameFromReadBuffer(const ReadBuffer & in);
|
||||||
|
String getExceptionEntryWithFileName(const ReadBuffer & in);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <IO/ZlibInflatingReadBuffer.h>
|
#include <IO/ZlibInflatingReadBuffer.h>
|
||||||
|
#include <IO/WithFileName.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -99,14 +99,22 @@ bool ZlibInflatingReadBuffer::nextImpl()
|
|||||||
{
|
{
|
||||||
rc = inflateReset(&zstr);
|
rc = inflateReset(&zstr);
|
||||||
if (rc != Z_OK)
|
if (rc != Z_OK)
|
||||||
throw Exception(ErrorCodes::ZLIB_INFLATE_FAILED, "inflateReset failed: {}", zError(rc));
|
throw Exception(
|
||||||
|
ErrorCodes::ZLIB_INFLATE_FAILED,
|
||||||
|
"inflateReset failed: {}{}",
|
||||||
|
zError(rc),
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If it is not end and not OK, something went wrong, throw exception
|
/// If it is not end and not OK, something went wrong, throw exception
|
||||||
if (rc != Z_OK)
|
if (rc != Z_OK)
|
||||||
throw Exception(ErrorCodes::ZLIB_INFLATE_FAILED, "inflate failed: {}", zError(rc));
|
throw Exception(
|
||||||
|
ErrorCodes::ZLIB_INFLATE_FAILED,
|
||||||
|
"inflate failed: {}{}",
|
||||||
|
zError(rc),
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
while (working_buffer.empty());
|
while (working_buffer.empty());
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <IO/ZstdInflatingReadBuffer.h>
|
#include <IO/ZstdInflatingReadBuffer.h>
|
||||||
|
#include <IO/WithFileName.h>
|
||||||
#include <zstd_errors.h>
|
#include <zstd_errors.h>
|
||||||
|
|
||||||
|
|
||||||
@ -61,12 +62,13 @@ bool ZstdInflatingReadBuffer::nextImpl()
|
|||||||
{
|
{
|
||||||
throw Exception(
|
throw Exception(
|
||||||
ErrorCodes::ZSTD_DECODER_FAILED,
|
ErrorCodes::ZSTD_DECODER_FAILED,
|
||||||
"ZSTD stream decoding failed: error '{}'{}; ZSTD version: {}",
|
"ZSTD stream decoding failed: error '{}'{}; ZSTD version: {}{}",
|
||||||
ZSTD_getErrorName(ret),
|
ZSTD_getErrorName(ret),
|
||||||
ZSTD_error_frameParameter_windowTooLarge == ret
|
ZSTD_error_frameParameter_windowTooLarge == ret
|
||||||
? ". You can increase the maximum window size with the 'zstd_window_log_max' setting in ClickHouse. Example: 'SET zstd_window_log_max = 31'"
|
? ". You can increase the maximum window size with the 'zstd_window_log_max' setting in ClickHouse. Example: 'SET zstd_window_log_max = 31'"
|
||||||
: "",
|
: "",
|
||||||
ZSTD_VERSION_STRING);
|
ZSTD_VERSION_STRING,
|
||||||
|
getExceptionEntryWithFileName(*in));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that something has changed after decompress (input or output position)
|
/// Check that something has changed after decompress (input or output position)
|
||||||
|
@ -4288,8 +4288,10 @@ ReadSettings Context::getReadSettings() const
|
|||||||
"Invalid value '{}' for max_read_buffer_size", settings.max_read_buffer_size);
|
"Invalid value '{}' for max_read_buffer_size", settings.max_read_buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.local_fs_buffer_size = settings.max_read_buffer_size;
|
res.local_fs_buffer_size
|
||||||
res.remote_fs_buffer_size = settings.max_read_buffer_size;
|
= settings.max_read_buffer_size_local_fs ? settings.max_read_buffer_size_local_fs : settings.max_read_buffer_size;
|
||||||
|
res.remote_fs_buffer_size
|
||||||
|
= settings.max_read_buffer_size_remote_fs ? settings.max_read_buffer_size_remote_fs : settings.max_read_buffer_size;
|
||||||
res.prefetch_buffer_size = settings.prefetch_buffer_size;
|
res.prefetch_buffer_size = settings.prefetch_buffer_size;
|
||||||
res.direct_io_threshold = settings.min_bytes_to_use_direct_io;
|
res.direct_io_threshold = settings.min_bytes_to_use_direct_io;
|
||||||
res.mmap_threshold = settings.min_bytes_to_use_mmap_io;
|
res.mmap_threshold = settings.min_bytes_to_use_mmap_io;
|
||||||
|
@ -1066,13 +1066,6 @@ static std::shared_ptr<IJoin> chooseJoinAlgorithm(
|
|||||||
{
|
{
|
||||||
const auto & settings = context->getSettings();
|
const auto & settings = context->getSettings();
|
||||||
|
|
||||||
Block left_sample_block(left_sample_columns);
|
|
||||||
for (auto & column : left_sample_block)
|
|
||||||
{
|
|
||||||
if (!column.column)
|
|
||||||
column.column = column.type->createColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
Block right_sample_block = joined_plan->getCurrentDataStream().header;
|
Block right_sample_block = joined_plan->getCurrentDataStream().header;
|
||||||
|
|
||||||
std::vector<String> tried_algorithms;
|
std::vector<String> tried_algorithms;
|
||||||
@ -1118,7 +1111,10 @@ static std::shared_ptr<IJoin> chooseJoinAlgorithm(
|
|||||||
if (analyzed_join->isEnabledAlgorithm(JoinAlgorithm::GRACE_HASH))
|
if (analyzed_join->isEnabledAlgorithm(JoinAlgorithm::GRACE_HASH))
|
||||||
{
|
{
|
||||||
tried_algorithms.push_back(toString(JoinAlgorithm::GRACE_HASH));
|
tried_algorithms.push_back(toString(JoinAlgorithm::GRACE_HASH));
|
||||||
if (GraceHashJoin::isSupported(analyzed_join))
|
|
||||||
|
// Grace hash join requires that columns exist in left_sample_block.
|
||||||
|
Block left_sample_block(left_sample_columns);
|
||||||
|
if (sanitizeBlock(left_sample_block, false) && GraceHashJoin::isSupported(analyzed_join))
|
||||||
return std::make_shared<GraceHashJoin>(context, analyzed_join, left_sample_block, right_sample_block, context->getTempDataOnDisk());
|
return std::make_shared<GraceHashJoin>(context, analyzed_join, left_sample_block, right_sample_block, context->getTempDataOnDisk());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <Backups/BackupEntryFromSmallFile.h>
|
#include <Backups/BackupEntryFromSmallFile.h>
|
||||||
#include <Backups/BackupEntryFromImmutableFile.h>
|
#include <Backups/BackupEntryFromImmutableFile.h>
|
||||||
#include <Disks/SingleDiskVolume.h>
|
#include <Disks/SingleDiskVolume.h>
|
||||||
|
#include <Storages/MergeTree/IMergeTreeDataPart.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -415,6 +416,7 @@ MutableDataPartStoragePtr DataPartStorageOnDiskBase::freeze(
|
|||||||
|
|
||||||
disk->removeFileIfExists(fs::path(to) / dir_path / "delete-on-destroy.txt");
|
disk->removeFileIfExists(fs::path(to) / dir_path / "delete-on-destroy.txt");
|
||||||
disk->removeFileIfExists(fs::path(to) / dir_path / "txn_version.txt");
|
disk->removeFileIfExists(fs::path(to) / dir_path / "txn_version.txt");
|
||||||
|
disk->removeFileIfExists(fs::path(to) / dir_path / IMergeTreeDataPart::METADATA_VERSION_FILE_NAME);
|
||||||
|
|
||||||
auto single_disk_volume = std::make_shared<SingleDiskVolume>(disk->getName(), disk, 0);
|
auto single_disk_volume = std::make_shared<SingleDiskVolume>(disk->getName(), disk, 0);
|
||||||
|
|
||||||
|
@ -1357,14 +1357,6 @@ void IMergeTreeDataPart::loadColumns(bool require)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
loaded_metadata_version = metadata_snapshot->getMetadataVersion();
|
loaded_metadata_version = metadata_snapshot->getMetadataVersion();
|
||||||
|
|
||||||
if (!is_readonly_storage)
|
|
||||||
{
|
|
||||||
writeMetadata(METADATA_VERSION_FILE_NAME, {}, [loaded_metadata_version](auto & buffer)
|
|
||||||
{
|
|
||||||
writeIntText(loaded_metadata_version, buffer);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setColumns(loaded_columns, infos, loaded_metadata_version);
|
setColumns(loaded_columns, infos, loaded_metadata_version);
|
||||||
|
@ -470,7 +470,7 @@ CHECK_DESCRIPTIONS = [
|
|||||||
),
|
),
|
||||||
CheckDescription(
|
CheckDescription(
|
||||||
"Flaky tests",
|
"Flaky tests",
|
||||||
"Runs a flaky tests from master multiple times to identify if they are stable.",
|
"Checks if new added or modified tests are flaky by running them repeatedly, in parallel, with more randomization. Functional tests are run 100 times with address sanitizer, and additional randomization of thread scheduling. Integrational tests are run up to 10 times. If at least once a new test has failed, or was too long, this check will be red. We don't allow flaky tests, read https://clickhouse.com/blog/decorating-a-christmas-tree-with-the-help-of-flaky-tests/",
|
||||||
lambda x: "tests flaky check" in x,
|
lambda x: "tests flaky check" in x,
|
||||||
),
|
),
|
||||||
CheckDescription(
|
CheckDescription(
|
||||||
|
@ -224,14 +224,22 @@ def test_attach_detach_partition(cluster):
|
|||||||
wait_for_delete_empty_parts(node, "hdfs_test")
|
wait_for_delete_empty_parts(node, "hdfs_test")
|
||||||
wait_for_delete_inactive_parts(node, "hdfs_test")
|
wait_for_delete_inactive_parts(node, "hdfs_test")
|
||||||
wait_for_delete_hdfs_objects(
|
wait_for_delete_hdfs_objects(
|
||||||
cluster, FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 2
|
cluster,
|
||||||
|
FILES_OVERHEAD
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 2
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION,
|
||||||
)
|
)
|
||||||
|
|
||||||
node.query("ALTER TABLE hdfs_test ATTACH PARTITION '2020-01-03'")
|
node.query("ALTER TABLE hdfs_test ATTACH PARTITION '2020-01-03'")
|
||||||
assert node.query("SELECT count(*) FROM hdfs_test FORMAT Values") == "(8192)"
|
assert node.query("SELECT count(*) FROM hdfs_test FORMAT Values") == "(8192)"
|
||||||
|
|
||||||
hdfs_objects = fs.listdir("/clickhouse")
|
hdfs_objects = fs.listdir("/clickhouse")
|
||||||
assert len(hdfs_objects) == FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 2
|
assert (
|
||||||
|
len(hdfs_objects)
|
||||||
|
== FILES_OVERHEAD
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 2
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION
|
||||||
|
)
|
||||||
|
|
||||||
node.query("ALTER TABLE hdfs_test DROP PARTITION '2020-01-03'")
|
node.query("ALTER TABLE hdfs_test DROP PARTITION '2020-01-03'")
|
||||||
assert node.query("SELECT count(*) FROM hdfs_test FORMAT Values") == "(4096)"
|
assert node.query("SELECT count(*) FROM hdfs_test FORMAT Values") == "(4096)"
|
||||||
@ -355,7 +363,14 @@ def test_move_replace_partition_to_another_table(cluster):
|
|||||||
|
|
||||||
# Number of objects in HDFS should be unchanged.
|
# Number of objects in HDFS should be unchanged.
|
||||||
hdfs_objects = fs.listdir("/clickhouse")
|
hdfs_objects = fs.listdir("/clickhouse")
|
||||||
assert len(hdfs_objects) == FILES_OVERHEAD * 2 + FILES_OVERHEAD_PER_PART_WIDE * 4
|
for obj in hdfs_objects:
|
||||||
|
print("Object in HDFS after move", obj)
|
||||||
|
wait_for_delete_hdfs_objects(
|
||||||
|
cluster,
|
||||||
|
FILES_OVERHEAD * 2
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 4
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
|
)
|
||||||
|
|
||||||
# Add new partitions to source table, but with different values and replace them from copied table.
|
# Add new partitions to source table, but with different values and replace them from copied table.
|
||||||
node.query(
|
node.query(
|
||||||
@ -370,7 +385,15 @@ def test_move_replace_partition_to_another_table(cluster):
|
|||||||
assert node.query("SELECT count(*) FROM hdfs_test FORMAT Values") == "(16384)"
|
assert node.query("SELECT count(*) FROM hdfs_test FORMAT Values") == "(16384)"
|
||||||
|
|
||||||
hdfs_objects = fs.listdir("/clickhouse")
|
hdfs_objects = fs.listdir("/clickhouse")
|
||||||
assert len(hdfs_objects) == FILES_OVERHEAD * 2 + FILES_OVERHEAD_PER_PART_WIDE * 6
|
for obj in hdfs_objects:
|
||||||
|
print("Object in HDFS after insert", obj)
|
||||||
|
|
||||||
|
wait_for_delete_hdfs_objects(
|
||||||
|
cluster,
|
||||||
|
FILES_OVERHEAD * 2
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 6
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
|
)
|
||||||
|
|
||||||
node.query("ALTER TABLE hdfs_test REPLACE PARTITION '2020-01-03' FROM hdfs_clone")
|
node.query("ALTER TABLE hdfs_test REPLACE PARTITION '2020-01-03' FROM hdfs_clone")
|
||||||
node.query("ALTER TABLE hdfs_test REPLACE PARTITION '2020-01-05' FROM hdfs_clone")
|
node.query("ALTER TABLE hdfs_test REPLACE PARTITION '2020-01-05' FROM hdfs_clone")
|
||||||
@ -381,7 +404,10 @@ def test_move_replace_partition_to_another_table(cluster):
|
|||||||
|
|
||||||
# Wait for outdated partitions deletion.
|
# Wait for outdated partitions deletion.
|
||||||
wait_for_delete_hdfs_objects(
|
wait_for_delete_hdfs_objects(
|
||||||
cluster, FILES_OVERHEAD * 2 + FILES_OVERHEAD_PER_PART_WIDE * 4
|
cluster,
|
||||||
|
FILES_OVERHEAD * 2
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 4
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
)
|
)
|
||||||
|
|
||||||
node.query("DROP TABLE hdfs_clone NO DELAY")
|
node.query("DROP TABLE hdfs_clone NO DELAY")
|
||||||
@ -390,4 +416,13 @@ def test_move_replace_partition_to_another_table(cluster):
|
|||||||
|
|
||||||
# Data should remain in hdfs
|
# Data should remain in hdfs
|
||||||
hdfs_objects = fs.listdir("/clickhouse")
|
hdfs_objects = fs.listdir("/clickhouse")
|
||||||
assert len(hdfs_objects) == FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 4
|
|
||||||
|
for obj in hdfs_objects:
|
||||||
|
print("Object in HDFS after drop", obj)
|
||||||
|
|
||||||
|
wait_for_delete_hdfs_objects(
|
||||||
|
cluster,
|
||||||
|
FILES_OVERHEAD
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 4
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
|
)
|
||||||
|
@ -312,14 +312,18 @@ def test_attach_detach_partition(cluster, node_name):
|
|||||||
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(4096)"
|
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(4096)"
|
||||||
assert (
|
assert (
|
||||||
len(list_objects(cluster, "data/"))
|
len(list_objects(cluster, "data/"))
|
||||||
== FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 2
|
== FILES_OVERHEAD
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 2
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION
|
||||||
)
|
)
|
||||||
|
|
||||||
node.query("ALTER TABLE s3_test ATTACH PARTITION '2020-01-03'")
|
node.query("ALTER TABLE s3_test ATTACH PARTITION '2020-01-03'")
|
||||||
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(8192)"
|
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(8192)"
|
||||||
assert (
|
assert (
|
||||||
len(list_objects(cluster, "data/"))
|
len(list_objects(cluster, "data/"))
|
||||||
== FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 2
|
== FILES_OVERHEAD
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 2
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION
|
||||||
)
|
)
|
||||||
|
|
||||||
node.query("ALTER TABLE s3_test DROP PARTITION '2020-01-03'")
|
node.query("ALTER TABLE s3_test DROP PARTITION '2020-01-03'")
|
||||||
@ -337,7 +341,9 @@ def test_attach_detach_partition(cluster, node_name):
|
|||||||
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(0)"
|
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(0)"
|
||||||
assert (
|
assert (
|
||||||
len(list_objects(cluster, "data/"))
|
len(list_objects(cluster, "data/"))
|
||||||
== FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 1
|
== FILES_OVERHEAD
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 1
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION
|
||||||
)
|
)
|
||||||
node.query(
|
node.query(
|
||||||
"ALTER TABLE s3_test DROP DETACHED PARTITION '2020-01-04'",
|
"ALTER TABLE s3_test DROP DETACHED PARTITION '2020-01-04'",
|
||||||
@ -444,10 +450,12 @@ def test_move_replace_partition_to_another_table(cluster, node_name):
|
|||||||
)
|
)
|
||||||
assert node.query("SELECT sum(id) FROM s3_test FORMAT Values") == "(0)"
|
assert node.query("SELECT sum(id) FROM s3_test FORMAT Values") == "(0)"
|
||||||
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(16384)"
|
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(16384)"
|
||||||
assert (
|
|
||||||
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
s3_objects = list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True))
|
||||||
== FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 4
|
for obj in s3_objects:
|
||||||
)
|
print("Object at start", obj.object_name)
|
||||||
|
|
||||||
|
assert len(s3_objects) == FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 4
|
||||||
|
|
||||||
create_table(node, "s3_clone")
|
create_table(node, "s3_clone")
|
||||||
|
|
||||||
@ -457,10 +465,16 @@ def test_move_replace_partition_to_another_table(cluster, node_name):
|
|||||||
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(8192)"
|
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(8192)"
|
||||||
assert node.query("SELECT sum(id) FROM s3_clone FORMAT Values") == "(0)"
|
assert node.query("SELECT sum(id) FROM s3_clone FORMAT Values") == "(0)"
|
||||||
assert node.query("SELECT count(*) FROM s3_clone FORMAT Values") == "(8192)"
|
assert node.query("SELECT count(*) FROM s3_clone FORMAT Values") == "(8192)"
|
||||||
|
s3_objects = list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True))
|
||||||
|
for obj in s3_objects:
|
||||||
|
print("Object after move partition", obj.object_name)
|
||||||
|
|
||||||
# Number of objects in S3 should be unchanged.
|
# Number of objects in S3 should be unchanged.
|
||||||
assert (
|
wait_for_delete_s3_objects(
|
||||||
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
cluster,
|
||||||
== FILES_OVERHEAD * 2 + FILES_OVERHEAD_PER_PART_WIDE * 4
|
FILES_OVERHEAD * 2
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 4
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add new partitions to source table, but with different values and replace them from copied table.
|
# Add new partitions to source table, but with different values and replace them from copied table.
|
||||||
@ -472,9 +486,15 @@ def test_move_replace_partition_to_another_table(cluster, node_name):
|
|||||||
)
|
)
|
||||||
assert node.query("SELECT sum(id) FROM s3_test FORMAT Values") == "(0)"
|
assert node.query("SELECT sum(id) FROM s3_test FORMAT Values") == "(0)"
|
||||||
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(16384)"
|
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(16384)"
|
||||||
assert (
|
s3_objects = list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True))
|
||||||
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
for obj in s3_objects:
|
||||||
== FILES_OVERHEAD * 2 + FILES_OVERHEAD_PER_PART_WIDE * 6
|
print("Object after insert", obj.object_name)
|
||||||
|
|
||||||
|
wait_for_delete_s3_objects(
|
||||||
|
cluster,
|
||||||
|
FILES_OVERHEAD * 2
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 6
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
)
|
)
|
||||||
|
|
||||||
node.query("ALTER TABLE s3_test REPLACE PARTITION '2020-01-03' FROM s3_clone")
|
node.query("ALTER TABLE s3_test REPLACE PARTITION '2020-01-03' FROM s3_clone")
|
||||||
@ -486,29 +506,47 @@ def test_move_replace_partition_to_another_table(cluster, node_name):
|
|||||||
|
|
||||||
# Wait for outdated partitions deletion.
|
# Wait for outdated partitions deletion.
|
||||||
wait_for_delete_s3_objects(
|
wait_for_delete_s3_objects(
|
||||||
cluster, FILES_OVERHEAD * 2 + FILES_OVERHEAD_PER_PART_WIDE * 4
|
cluster,
|
||||||
|
FILES_OVERHEAD * 2
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 4
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
)
|
)
|
||||||
|
|
||||||
node.query("DROP TABLE s3_clone NO DELAY")
|
node.query("DROP TABLE s3_clone NO DELAY")
|
||||||
assert node.query("SELECT sum(id) FROM s3_test FORMAT Values") == "(0)"
|
assert node.query("SELECT sum(id) FROM s3_test FORMAT Values") == "(0)"
|
||||||
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(16384)"
|
assert node.query("SELECT count(*) FROM s3_test FORMAT Values") == "(16384)"
|
||||||
|
s3_objects = list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True))
|
||||||
|
for obj in s3_objects:
|
||||||
|
print("Object after drop", obj.object_name)
|
||||||
|
|
||||||
# Data should remain in S3
|
# Data should remain in S3
|
||||||
assert (
|
|
||||||
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
wait_for_delete_s3_objects(
|
||||||
== FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 4
|
cluster,
|
||||||
|
FILES_OVERHEAD
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 4
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
)
|
)
|
||||||
|
|
||||||
node.query("ALTER TABLE s3_test FREEZE")
|
node.query("ALTER TABLE s3_test FREEZE")
|
||||||
# Number S3 objects should be unchanged.
|
# Number S3 objects should be unchanged.
|
||||||
assert (
|
s3_objects = list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True))
|
||||||
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
for obj in s3_objects:
|
||||||
== FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 4
|
print("Object after freeze", obj.object_name)
|
||||||
|
|
||||||
|
wait_for_delete_s3_objects(
|
||||||
|
cluster,
|
||||||
|
FILES_OVERHEAD
|
||||||
|
+ FILES_OVERHEAD_PER_PART_WIDE * 4
|
||||||
|
- FILES_OVERHEAD_METADATA_VERSION * 2,
|
||||||
)
|
)
|
||||||
|
|
||||||
node.query("DROP TABLE s3_test NO DELAY")
|
node.query("DROP TABLE s3_test NO DELAY")
|
||||||
# Backup data should remain in S3.
|
# Backup data should remain in S3.
|
||||||
|
|
||||||
wait_for_delete_s3_objects(cluster, FILES_OVERHEAD_PER_PART_WIDE * 4)
|
wait_for_delete_s3_objects(
|
||||||
|
cluster, FILES_OVERHEAD_PER_PART_WIDE * 4 - FILES_OVERHEAD_METADATA_VERSION * 4
|
||||||
|
)
|
||||||
|
|
||||||
for obj in list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)):
|
for obj in list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)):
|
||||||
minio.remove_object(cluster.minio_bucket, obj.object_name)
|
minio.remove_object(cluster.minio_bucket, obj.object_name)
|
||||||
@ -534,7 +572,8 @@ def test_freeze_unfreeze(cluster, node_name):
|
|||||||
wait_for_delete_inactive_parts(node, "s3_test")
|
wait_for_delete_inactive_parts(node, "s3_test")
|
||||||
assert (
|
assert (
|
||||||
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
||||||
== FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 2
|
== FILES_OVERHEAD
|
||||||
|
+ (FILES_OVERHEAD_PER_PART_WIDE - FILES_OVERHEAD_METADATA_VERSION) * 2
|
||||||
)
|
)
|
||||||
|
|
||||||
# Unfreeze single partition from backup1.
|
# Unfreeze single partition from backup1.
|
||||||
@ -575,7 +614,8 @@ def test_freeze_system_unfreeze(cluster, node_name):
|
|||||||
node.query("DROP TABLE s3_test_removed NO DELAY")
|
node.query("DROP TABLE s3_test_removed NO DELAY")
|
||||||
assert (
|
assert (
|
||||||
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
len(list(minio.list_objects(cluster.minio_bucket, "data/", recursive=True)))
|
||||||
== FILES_OVERHEAD + FILES_OVERHEAD_PER_PART_WIDE * 2
|
== FILES_OVERHEAD
|
||||||
|
+ (FILES_OVERHEAD_PER_PART_WIDE - FILES_OVERHEAD_METADATA_VERSION) * 2
|
||||||
)
|
)
|
||||||
|
|
||||||
# Unfreeze all data from backup3.
|
# Unfreeze all data from backup3.
|
||||||
|
@ -70,7 +70,7 @@ def partition_complex_assert_columns_txt():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def partition_complex_assert_checksums():
|
def partition_complex_assert_checksums(after_detach=False):
|
||||||
# Do not check increment.txt - it can be changed by other tests with FREEZE
|
# Do not check increment.txt - it can be changed by other tests with FREEZE
|
||||||
cmd = [
|
cmd = [
|
||||||
"bash",
|
"bash",
|
||||||
@ -80,36 +80,67 @@ def partition_complex_assert_checksums():
|
|||||||
" | sed 's shadow/[0-9]*/data/[a-z0-9_-]*/ shadow/1/data/test/ g' | sort | uniq",
|
" | sed 's shadow/[0-9]*/data/[a-z0-9_-]*/ shadow/1/data/test/ g' | sort | uniq",
|
||||||
]
|
]
|
||||||
|
|
||||||
checksums = (
|
# no metadata version
|
||||||
"082814b5aa5109160d5c0c5aff10d4df\tshadow/1/data/test/partition_complex/19700102_2_2_0/k.bin\n"
|
if after_detach:
|
||||||
"082814b5aa5109160d5c0c5aff10d4df\tshadow/1/data/test/partition_complex/19700201_1_1_0/v1.bin\n"
|
checksums = (
|
||||||
"13cae8e658e0ca4f75c56b1fc424e150\tshadow/1/data/test/partition_complex/19700102_2_2_0/minmax_p.idx\n"
|
"082814b5aa5109160d5c0c5aff10d4df\tshadow/1/data/test/partition_complex/19700102_2_2_0/k.bin\n"
|
||||||
"25daad3d9e60b45043a70c4ab7d3b1c6\tshadow/1/data/test/partition_complex/19700102_2_2_0/partition.dat\n"
|
"082814b5aa5109160d5c0c5aff10d4df\tshadow/1/data/test/partition_complex/19700201_1_1_0/v1.bin\n"
|
||||||
"3726312af62aec86b64a7708d5751787\tshadow/1/data/test/partition_complex/19700201_1_1_0/partition.dat\n"
|
"13cae8e658e0ca4f75c56b1fc424e150\tshadow/1/data/test/partition_complex/19700102_2_2_0/minmax_p.idx\n"
|
||||||
"37855b06a39b79a67ea4e86e4a3299aa\tshadow/1/data/test/partition_complex/19700102_2_2_0/checksums.txt\n"
|
"25daad3d9e60b45043a70c4ab7d3b1c6\tshadow/1/data/test/partition_complex/19700102_2_2_0/partition.dat\n"
|
||||||
"38e62ff37e1e5064e9a3f605dfe09d13\tshadow/1/data/test/partition_complex/19700102_2_2_0/v1.bin\n"
|
"3726312af62aec86b64a7708d5751787\tshadow/1/data/test/partition_complex/19700201_1_1_0/partition.dat\n"
|
||||||
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/k.mrk\n"
|
"37855b06a39b79a67ea4e86e4a3299aa\tshadow/1/data/test/partition_complex/19700102_2_2_0/checksums.txt\n"
|
||||||
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/p.mrk\n"
|
"38e62ff37e1e5064e9a3f605dfe09d13\tshadow/1/data/test/partition_complex/19700102_2_2_0/v1.bin\n"
|
||||||
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/v1.mrk\n"
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/k.mrk\n"
|
||||||
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/k.mrk\n"
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/p.mrk\n"
|
||||||
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/p.mrk\n"
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/v1.mrk\n"
|
||||||
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/v1.mrk\n"
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/k.mrk\n"
|
||||||
"55a54008ad1ba589aa210d2629c1df41\tshadow/1/data/test/partition_complex/19700201_1_1_0/primary.idx\n"
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/p.mrk\n"
|
||||||
"5f087cb3e7071bf9407e095821e2af8f\tshadow/1/data/test/partition_complex/19700201_1_1_0/checksums.txt\n"
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/v1.mrk\n"
|
||||||
"77d5af402ada101574f4da114f242e02\tshadow/1/data/test/partition_complex/19700102_2_2_0/columns.txt\n"
|
"55a54008ad1ba589aa210d2629c1df41\tshadow/1/data/test/partition_complex/19700201_1_1_0/primary.idx\n"
|
||||||
"77d5af402ada101574f4da114f242e02\tshadow/1/data/test/partition_complex/19700201_1_1_0/columns.txt\n"
|
"5f087cb3e7071bf9407e095821e2af8f\tshadow/1/data/test/partition_complex/19700201_1_1_0/checksums.txt\n"
|
||||||
"88cdc31ded355e7572d68d8cde525d3a\tshadow/1/data/test/partition_complex/19700201_1_1_0/p.bin\n"
|
"77d5af402ada101574f4da114f242e02\tshadow/1/data/test/partition_complex/19700102_2_2_0/columns.txt\n"
|
||||||
"9e688c58a5487b8eaf69c9e1005ad0bf\tshadow/1/data/test/partition_complex/19700102_2_2_0/primary.idx\n"
|
"77d5af402ada101574f4da114f242e02\tshadow/1/data/test/partition_complex/19700201_1_1_0/columns.txt\n"
|
||||||
"c0904274faa8f3f06f35666cc9c5bd2f\tshadow/1/data/test/partition_complex/19700102_2_2_0/default_compression_codec.txt\n"
|
"88cdc31ded355e7572d68d8cde525d3a\tshadow/1/data/test/partition_complex/19700201_1_1_0/p.bin\n"
|
||||||
"c0904274faa8f3f06f35666cc9c5bd2f\tshadow/1/data/test/partition_complex/19700201_1_1_0/default_compression_codec.txt\n"
|
"9e688c58a5487b8eaf69c9e1005ad0bf\tshadow/1/data/test/partition_complex/19700102_2_2_0/primary.idx\n"
|
||||||
"c4ca4238a0b923820dcc509a6f75849b\tshadow/1/data/test/partition_complex/19700102_2_2_0/count.txt\n"
|
"c0904274faa8f3f06f35666cc9c5bd2f\tshadow/1/data/test/partition_complex/19700102_2_2_0/default_compression_codec.txt\n"
|
||||||
"c4ca4238a0b923820dcc509a6f75849b\tshadow/1/data/test/partition_complex/19700201_1_1_0/count.txt\n"
|
"c0904274faa8f3f06f35666cc9c5bd2f\tshadow/1/data/test/partition_complex/19700201_1_1_0/default_compression_codec.txt\n"
|
||||||
"cfcb770c3ecd0990dcceb1bde129e6c6\tshadow/1/data/test/partition_complex/19700102_2_2_0/p.bin\n"
|
"c4ca4238a0b923820dcc509a6f75849b\tshadow/1/data/test/partition_complex/19700102_2_2_0/count.txt\n"
|
||||||
"cfcd208495d565ef66e7dff9f98764da\tshadow/1/data/test/partition_complex/19700102_2_2_0/metadata_version.txt\n"
|
"c4ca4238a0b923820dcc509a6f75849b\tshadow/1/data/test/partition_complex/19700201_1_1_0/count.txt\n"
|
||||||
"cfcd208495d565ef66e7dff9f98764da\tshadow/1/data/test/partition_complex/19700201_1_1_0/metadata_version.txt\n"
|
"cfcb770c3ecd0990dcceb1bde129e6c6\tshadow/1/data/test/partition_complex/19700102_2_2_0/p.bin\n"
|
||||||
"e2af3bef1fd129aea73a890ede1e7a30\tshadow/1/data/test/partition_complex/19700201_1_1_0/k.bin\n"
|
"e2af3bef1fd129aea73a890ede1e7a30\tshadow/1/data/test/partition_complex/19700201_1_1_0/k.bin\n"
|
||||||
"f2312862cc01adf34a93151377be2ddf\tshadow/1/data/test/partition_complex/19700201_1_1_0/minmax_p.idx\n"
|
"f2312862cc01adf34a93151377be2ddf\tshadow/1/data/test/partition_complex/19700201_1_1_0/minmax_p.idx\n"
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
checksums = (
|
||||||
|
"082814b5aa5109160d5c0c5aff10d4df\tshadow/1/data/test/partition_complex/19700102_2_2_0/k.bin\n"
|
||||||
|
"082814b5aa5109160d5c0c5aff10d4df\tshadow/1/data/test/partition_complex/19700201_1_1_0/v1.bin\n"
|
||||||
|
"13cae8e658e0ca4f75c56b1fc424e150\tshadow/1/data/test/partition_complex/19700102_2_2_0/minmax_p.idx\n"
|
||||||
|
"25daad3d9e60b45043a70c4ab7d3b1c6\tshadow/1/data/test/partition_complex/19700102_2_2_0/partition.dat\n"
|
||||||
|
"3726312af62aec86b64a7708d5751787\tshadow/1/data/test/partition_complex/19700201_1_1_0/partition.dat\n"
|
||||||
|
"37855b06a39b79a67ea4e86e4a3299aa\tshadow/1/data/test/partition_complex/19700102_2_2_0/checksums.txt\n"
|
||||||
|
"38e62ff37e1e5064e9a3f605dfe09d13\tshadow/1/data/test/partition_complex/19700102_2_2_0/v1.bin\n"
|
||||||
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/k.mrk\n"
|
||||||
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/p.mrk\n"
|
||||||
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700102_2_2_0/v1.mrk\n"
|
||||||
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/k.mrk\n"
|
||||||
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/p.mrk\n"
|
||||||
|
"4ae71336e44bf9bf79d2752e234818a5\tshadow/1/data/test/partition_complex/19700201_1_1_0/v1.mrk\n"
|
||||||
|
"55a54008ad1ba589aa210d2629c1df41\tshadow/1/data/test/partition_complex/19700201_1_1_0/primary.idx\n"
|
||||||
|
"5f087cb3e7071bf9407e095821e2af8f\tshadow/1/data/test/partition_complex/19700201_1_1_0/checksums.txt\n"
|
||||||
|
"77d5af402ada101574f4da114f242e02\tshadow/1/data/test/partition_complex/19700102_2_2_0/columns.txt\n"
|
||||||
|
"77d5af402ada101574f4da114f242e02\tshadow/1/data/test/partition_complex/19700201_1_1_0/columns.txt\n"
|
||||||
|
"88cdc31ded355e7572d68d8cde525d3a\tshadow/1/data/test/partition_complex/19700201_1_1_0/p.bin\n"
|
||||||
|
"9e688c58a5487b8eaf69c9e1005ad0bf\tshadow/1/data/test/partition_complex/19700102_2_2_0/primary.idx\n"
|
||||||
|
"c0904274faa8f3f06f35666cc9c5bd2f\tshadow/1/data/test/partition_complex/19700102_2_2_0/default_compression_codec.txt\n"
|
||||||
|
"c0904274faa8f3f06f35666cc9c5bd2f\tshadow/1/data/test/partition_complex/19700201_1_1_0/default_compression_codec.txt\n"
|
||||||
|
"c4ca4238a0b923820dcc509a6f75849b\tshadow/1/data/test/partition_complex/19700102_2_2_0/count.txt\n"
|
||||||
|
"c4ca4238a0b923820dcc509a6f75849b\tshadow/1/data/test/partition_complex/19700201_1_1_0/count.txt\n"
|
||||||
|
"cfcb770c3ecd0990dcceb1bde129e6c6\tshadow/1/data/test/partition_complex/19700102_2_2_0/p.bin\n"
|
||||||
|
"cfcd208495d565ef66e7dff9f98764da\tshadow/1/data/test/partition_complex/19700102_2_2_0/metadata_version.txt\n"
|
||||||
|
"cfcd208495d565ef66e7dff9f98764da\tshadow/1/data/test/partition_complex/19700201_1_1_0/metadata_version.txt\n"
|
||||||
|
"e2af3bef1fd129aea73a890ede1e7a30\tshadow/1/data/test/partition_complex/19700201_1_1_0/k.bin\n"
|
||||||
|
"f2312862cc01adf34a93151377be2ddf\tshadow/1/data/test/partition_complex/19700201_1_1_0/minmax_p.idx\n"
|
||||||
|
)
|
||||||
|
|
||||||
assert TSV(instance.exec_in_container(cmd).replace(" ", "\t")) == TSV(checksums)
|
assert TSV(instance.exec_in_container(cmd).replace(" ", "\t")) == TSV(checksums)
|
||||||
|
|
||||||
@ -134,7 +165,7 @@ def test_partition_complex(partition_table_complex):
|
|||||||
|
|
||||||
q("ALTER TABLE test.partition_complex FREEZE")
|
q("ALTER TABLE test.partition_complex FREEZE")
|
||||||
|
|
||||||
partition_complex_assert_checksums()
|
partition_complex_assert_checksums(True)
|
||||||
|
|
||||||
q("ALTER TABLE test.partition_complex DETACH PARTITION 197001")
|
q("ALTER TABLE test.partition_complex DETACH PARTITION 197001")
|
||||||
q("ALTER TABLE test.partition_complex ATTACH PARTITION 197001")
|
q("ALTER TABLE test.partition_complex ATTACH PARTITION 197001")
|
||||||
@ -144,7 +175,7 @@ def test_partition_complex(partition_table_complex):
|
|||||||
q("ALTER TABLE test.partition_complex MODIFY COLUMN v1 Int8")
|
q("ALTER TABLE test.partition_complex MODIFY COLUMN v1 Int8")
|
||||||
|
|
||||||
# Check the backup hasn't changed
|
# Check the backup hasn't changed
|
||||||
partition_complex_assert_checksums()
|
partition_complex_assert_checksums(True)
|
||||||
|
|
||||||
q("OPTIMIZE TABLE test.partition_complex")
|
q("OPTIMIZE TABLE test.partition_complex")
|
||||||
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
Ok
|
||||||
|
Ok
|
||||||
|
Ok
|
||||||
|
Ok
|
||||||
|
Ok
|
||||||
|
Ok
|
||||||
|
Ok
|
||||||
|
Ok
|
22
tests/queries/0_stateless/02724_decompress_filename_exception.sh
Executable file
22
tests/queries/0_stateless/02724_decompress_filename_exception.sh
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Tags: no-fasttest, no-parallel
|
||||||
|
|
||||||
|
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
# shellcheck source=../shell_config.sh
|
||||||
|
. "$CURDIR"/../shell_config.sh
|
||||||
|
|
||||||
|
USER_FILES_PATH=$(clickhouse-client --query "select _path,_file from file('nonexist.txt', 'CSV', 'val1 char')" 2>&1 | grep Exception | awk '{gsub("/nonexist.txt","",$9); print $9}')
|
||||||
|
FILENAME="${USER_FILES_PATH}/corrupted_file.tsv.xx"
|
||||||
|
|
||||||
|
echo 'corrupted file' > $FILENAME;
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT --query "SELECT * FROM file('${FILENAME}', 'TSV', 'c UInt32', 'gzip')" 2>&1 | grep -q "While reading from: $FILENAME" && echo 'Ok' || echo 'Fail';
|
||||||
|
$CLICKHOUSE_CLIENT --query "SELECT * FROM file('${FILENAME}', 'TSV', 'c UInt32', 'deflate')" 2>&1 | grep -q "While reading from: $FILENAME" && echo 'Ok' || echo 'Fail';
|
||||||
|
$CLICKHOUSE_CLIENT --query "SELECT * FROM file('${FILENAME}', 'TSV', 'c UInt32', 'br')" 2>&1 | grep -q "While reading from: $FILENAME" && echo 'Ok' || echo 'Fail';
|
||||||
|
$CLICKHOUSE_CLIENT --query "SELECT * FROM file('${FILENAME}', 'TSV', 'c UInt32', 'xz')" 2>&1 | grep -q "While reading from: $FILENAME" && echo 'Ok' || echo 'Fail';
|
||||||
|
$CLICKHOUSE_CLIENT --query "SELECT * FROM file('${FILENAME}', 'TSV', 'c UInt32', 'zstd')" 2>&1 | grep -q "While reading from: $FILENAME" && echo 'Ok' || echo 'Fail';
|
||||||
|
$CLICKHOUSE_CLIENT --query "SELECT * FROM file('${FILENAME}', 'TSV', 'c UInt32', 'lz4')" 2>&1 | grep -q "While reading from: $FILENAME" && echo 'Ok' || echo 'Fail';
|
||||||
|
$CLICKHOUSE_CLIENT --query "SELECT * FROM file('${FILENAME}', 'TSV', 'c UInt32', 'bz2')" 2>&1 | grep -q "While reading from: $FILENAME" && echo 'Ok' || echo 'Fail';
|
||||||
|
$CLICKHOUSE_CLIENT --query "SELECT * FROM file('${FILENAME}', 'TSV', 'c UInt32', 'snappy')" 2>&1 | grep -q "While reading from: $FILENAME" && echo 'Ok' || echo 'Fail';
|
||||||
|
|
||||||
|
rm $FILENAME;
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1,8 @@
|
|||||||
|
select count(*)
|
||||||
|
from (
|
||||||
|
select 1 as id, [1, 2, 3] as arr
|
||||||
|
) as sessions
|
||||||
|
ASOF LEFT JOIN (
|
||||||
|
select 1 as session_id, 4 as id
|
||||||
|
) as visitors
|
||||||
|
ON visitors.session_id <= sessions.id AND arrayFirst(a -> a, arrayMap((a) -> a, sessions.arr)) = visitors.id
|
Loading…
Reference in New Issue
Block a user