translate comments

This commit is contained in:
f1yegor 2017-04-16 17:00:33 +02:00 committed by alexey-milovidov
parent 41e97787e3
commit 0b243a8b01
70 changed files with 705 additions and 706 deletions

View File

@ -248,7 +248,7 @@ public:
return summary.back().mean; return summary.back().mean;
} }
/** Get multiple quantiles (`size` pieces). /** Get multiple quantiles (`size` parts).
* levels - an array of levels of the desired quantiles. They are in a random order. * levels - an array of levels of the desired quantiles. They are in a random order.
* levels_permutation - array-permutation levels. The i-th position will be the index of the i-th ascending level in the `levels` array. * levels_permutation - array-permutation levels. The i-th position will be the index of the i-th ascending level in the `levels` array.
* result - the array where the results are added, in order of `levels`, * result - the array where the results are added, in order of `levels`,

View File

@ -6,7 +6,7 @@
namespace DB namespace DB
{ {
/// Операция из запроса ALTER (кроме манипуляции с PART/PARTITION). Добавление столбцов типа Nested не развернуто в добавление отдельных столбцов. /// Operation from the ALTER query (except for manipulation with PART/PARTITION). Adding Nested columns is not expanded to add individual columns.
struct AlterCommand struct AlterCommand
{ {
enum Type enum Type
@ -24,19 +24,19 @@ struct AlterCommand
/// For DROP COLUMN ... FROM PARTITION /// For DROP COLUMN ... FROM PARTITION
String partition_name; String partition_name;
/// Для ADD и MODIFY - новый тип столбца. /// For ADD and MODIFY, a new column type.
DataTypePtr data_type; DataTypePtr data_type;
ColumnDefaultType default_type{}; ColumnDefaultType default_type{};
ASTPtr default_expression{}; ASTPtr default_expression{};
/// Для ADD - после какого столбца добавить новый. Если пустая строка, добавить в конец. Добавить в начало сейчас нельзя. /// For ADD - after which column to add a new one. If an empty string, add to the end. To add to the beginning now it is impossible.
String after_column; String after_column;
/// Для MODIFY_PRIMARY_KEY /// For MODIFY_PRIMARY_KEY
ASTPtr primary_key; ASTPtr primary_key;
/// одинаковыми считаются имена, если они совпадают целиком или name_without_dot совпадает с частью имени до точки /// the names are the same if they match the whole name or name_without_dot matches the part of the name up to the dot
static bool namesEqual(const String & name_without_dot, const DB::NameAndTypePair & name_type) static bool namesEqual(const String & name_without_dot, const DB::NameAndTypePair & name_type)
{ {
String name_with_dot = name_without_dot + "."; String name_with_dot = name_without_dot + ".";

View File

@ -15,19 +15,19 @@ namespace ErrorCodes
} }
/** Позволяет выбрать метод сжатия по указанным в конфигурационном файле условиям. /** Allows you to select the compression method for the conditions specified in the configuration file.
* Конфиг выглядит примерно так: * The config looks like this
<compression> <compression>
<!-- Набор вариантов. Варианты проверяются подряд. Побеждает последний сработавший вариант. Если ни один не сработал, то используется lz4. --> <!-- Set of options. Options are checked in a row. The last worked option wins. If none has worked, then lz4 is used. -->
<case> <case>
<!-- Условия. Должны сработать одновременно все. Часть условий могут быть не указаны. --> <!-- Conditions. All must be satisfied simultaneously. Some conditions may not be specified. -->
<min_part_size>10000000000</min_part_size> <!-- Минимальный размер куска в байтах. --> <min_part_size>10000000000</min_part_size> <!-- The minimum size of a part in bytes. -->
<min_part_size_ratio>0.01</min_part_size_ratio> <!-- Минимальный размер куска относительно всех данных таблицы. --> <min_part_size_ratio>0.01</min_part_size_ratio> <!-- The minimum size of the part relative to all the data in the table. -->
<!-- Какой метод сжатия выбрать. --> <! - Which compression method to choose. ->
<method>zstd</method> <method>zstd</method>
</case> </case>
@ -73,7 +73,7 @@ private:
std::vector<Element> elements; std::vector<Element> elements;
public: public:
CompressionMethodSelector() {} /// Всегда возвращает метод по-умолчанию. CompressionMethodSelector() {} /// Always returns the default method.
CompressionMethodSelector(Poco::Util::AbstractConfiguration & config, const std::string & config_prefix) CompressionMethodSelector(Poco::Util::AbstractConfiguration & config, const std::string & config_prefix)
{ {

View File

@ -10,14 +10,14 @@ namespace DB
class StorageDistributed; class StorageDistributed;
/** Запись асинхронная - данные сначала записываются на локальную файловую систему, а потом отправляются на удалённые серверы. /** The write is asynchronous - the data is first written to the local file system, and then sent to the remote servers.
* Если Distributed таблица использует более одного шарда, то для того, чтобы поддерживалась запись, * If the Distributed table uses more than one shard, then in order to support the write,
* при создании таблицы должен быть указан дополнительный параметр у ENGINE - ключ шардирования. * when creating the table, an additional parameter must be specified for ENGINE - the sharding key.
* Ключ шардирования - произвольное выражение от столбцов. Например, rand() или UserID. * Sharding key is an arbitrary expression from the columns. For example, rand() or UserID.
* При записи блок данных разбивается по остатку от деления ключа шардирования на суммарный вес шардов, * When writing, the data block is splitted by the remainder of the division of the sharding key by the total weight of the shards,
* и полученные блоки пишутся в сжатом Native формате в отдельные директории для отправки. * and the resulting blocks are written in a compressed Native format in separate directories for sending.
* Для каждого адреса назначения (каждой директории с данными для отправки), в StorageDistributed создаётся отдельный поток, * For each destination address (each directory with data to send), a separate thread is created in StorageDistributed,
* который следит за директорией и отправляет данные. */ * which monitors the directory and sends data. */
class DistributedBlockOutputStream : public IBlockOutputStream class DistributedBlockOutputStream : public IBlockOutputStream
{ {
public: public:

View File

@ -44,11 +44,11 @@ using WeightedZooKeeperPaths = std::vector<WeightedZooKeeperPath>;
/** Не дает изменять описание таблицы (в том числе переименовывать и удалять таблицу). /** Does not allow changing the table description (including rename and delete the table).
* Если в течение какой-то операции структура таблицы должна оставаться неизменной, нужно держать такой лок на все ее время. * If during any operation the table structure should remain unchanged, you need to hold such a lock for all of its time.
* Например, нужно держать такой лок на время всего запроса SELECT или INSERT и на все время слияния набора кусков * For example, you need to hold such a lock for the duration of the entire SELECT or INSERT query and for the whole time the merge of the set of parts
* (но между выбором кусков для слияния и их слиянием структура таблицы может измениться). * (but between the selection of parts for the merge and their merging, the table structure can change).
* NOTE: Это лок на "чтение" описания таблицы. Чтобы изменить описание таблицы, нужно взять TableStructureWriteLock. * NOTE: This is a lock to "read" the table's description. To change the table description, you need to take the TableStructureWriteLock.
*/ */
class TableStructureReadLock class TableStructureReadLock
{ {
@ -56,7 +56,7 @@ private:
friend class IStorage; friend class IStorage;
StoragePtr storage; StoragePtr storage;
/// Порядок важен. /// Order is important.
std::experimental::optional<Poco::ScopedReadRWLock> data_lock; std::experimental::optional<Poco::ScopedReadRWLock> data_lock;
std::experimental::optional<Poco::ScopedReadRWLock> structure_lock; std::experimental::optional<Poco::ScopedReadRWLock> structure_lock;
@ -72,39 +72,39 @@ using TableDataWriteLockPtr = std::unique_ptr<Poco::ScopedWriteRWLock>;
using TableFullWriteLockPtr = std::pair<TableDataWriteLockPtr, TableStructureWriteLockPtr>; using TableFullWriteLockPtr = std::pair<TableDataWriteLockPtr, TableStructureWriteLockPtr>;
/** Хранилище. Отвечает за: /** Storage. Responsible for
* - хранение данных таблицы; * - storage of the table data;
* - определение, в каком файле (или не файле) хранятся данные; * - the definition in which file (or not the file) the data is stored;
* - поиск данных и обновление данных; * - search for data and update data;
* - структура хранения данных (сжатие, etc.) * - data storage structure (compression, etc.)
* - конкуррентный доступ к данным (блокировки, etc.) * - concurrent access to data (locks, etc.)
*/ */
class IStorage : public std::enable_shared_from_this<IStorage>, private boost::noncopyable, public ITableDeclaration class IStorage : public std::enable_shared_from_this<IStorage>, private boost::noncopyable, public ITableDeclaration
{ {
public: public:
/// Основное имя типа таблицы (например, StorageMergeTree). /// The main name of the table type (for example, StorageMergeTree).
virtual std::string getName() const = 0; virtual std::string getName() const = 0;
/** Возвращает true, если хранилище получает данные с удалённого сервера или серверов. */ /** Returns true if the store receives data from a remote server or servers. */
virtual bool isRemote() const { return false; } virtual bool isRemote() const { return false; }
/** Возвращает true, если хранилище поддерживает запросы с секцией SAMPLE. */ /** Returns true if the storage supports queries with the SAMPLE section. */
virtual bool supportsSampling() const { return false; } virtual bool supportsSampling() const { return false; }
/** Возвращает true, если хранилище поддерживает запросы с секцией FINAL. */ /** Returns true if the storage supports queries with the FINAL section. */
virtual bool supportsFinal() const { return false; } virtual bool supportsFinal() const { return false; }
/** Возвращает true, если хранилище поддерживает запросы с секцией PREWHERE. */ /** Returns true if the storage supports queries with the PREWHERE section. */
virtual bool supportsPrewhere() const { return false; } virtual bool supportsPrewhere() const { return false; }
/** Возвращает true, если хранилище поддерживает несколько реплик. */ /** Returns true if the storage supports multiple replicas. */
virtual bool supportsParallelReplicas() const { return false; } virtual bool supportsParallelReplicas() const { return false; }
/** Не дает изменять структуру или имя таблицы. /** Does not allow you to change the structure or name of the table.
* Если в рамках этого лока будут изменены данные в таблице, нужно указать will_modify_data=true. * If you change the data in the table, you will need to specify will_modify_data = true.
* Это возьмет дополнительный лок, не позволяющий начать ALTER MODIFY. * This will take an extra lock that does not allow starting ALTER MODIFY.
* *
* WARNING: Вызывать методы из ITableDeclaration нужно под такой блокировкой. Без нее они не thread safe. * WARNING: You need to call methods from ITableDeclaration under such a lock. Without it, they are not thread safe.
* WARNING: To avoid deadlocks, this method must not be called under lock of Context. * WARNING: To avoid deadlocks, this method must not be called under lock of Context.
*/ */
TableStructureReadLockPtr lockStructure(bool will_modify_data) TableStructureReadLockPtr lockStructure(bool will_modify_data)
@ -115,20 +115,20 @@ public:
return res; return res;
} }
/** Не дает читать структуру таблицы. Берется для ALTER, RENAME и DROP. /** Does not allow reading the table structure. It is taken for ALTER, RENAME and DROP.
*/ */
TableFullWriteLockPtr lockForAlter() TableFullWriteLockPtr lockForAlter()
{ {
/// Порядок вычисления важен. /// The calculation order is important.
auto data_lock = lockDataForAlter(); auto data_lock = lockDataForAlter();
auto structure_lock = lockStructureForAlter(); auto structure_lock = lockStructureForAlter();
return {std::move(data_lock), std::move(structure_lock)}; return {std::move(data_lock), std::move(structure_lock)};
} }
/** Не дает изменять данные в таблице. (Более того, не дает посмотреть на структуру таблицы с намерением изменить данные). /** Does not allow changing the data in the table. (Moreover, does not give a look at the structure of the table with the intention to change the data).
* Берется на время записи временных данных в ALTER MODIFY. * It is taken during write temporary data in ALTER MODIFY.
* Под этим локом можно брать lockStructureForAlter(), чтобы изменить структуру таблицы. * Under this lock, you can take lockStructureForAlter() to change the structure of the table.
*/ */
TableDataWriteLockPtr lockDataForAlter() TableDataWriteLockPtr lockDataForAlter()
{ {
@ -147,24 +147,24 @@ public:
} }
/** Читать набор столбцов из таблицы. /** Read a set of columns from the table.
* Принимает список столбцов, которых нужно прочитать, а также описание запроса, * Accepts a list of columns to read, as well as a description of the query,
* из которого может быть извлечена информация о том, каким способом извлекать данные * from which information can be extracted about how to retrieve data
* (индексы, блокировки и т. п.) * (indexes, locks, etc.)
* Возвращает поток с помощью которого можно последовательно читать данные * Returns a stream with which you can read data sequentially
* или несколько потоков для параллельного чтения данных. * or multiple streams for parallel data reading.
* Также в processed_stage записывается, до какой стадии запрос был обработан. * The into `processed_stage` info is also written to what stage the request was processed.
* (Обычно функция только читает столбцы из списка, но в других случаях, * (Normally, the function only reads the columns from the list, but in other cases,
* например, запрос может быть частично обработан на удалённом сервере.) * for example, the request can be partially processed on a remote server.)
* *
* settings - настройки на один запрос. * settings - settings for one query.
* Обычно Storage не заботится об этих настройках, так как они применяются в интерпретаторе. * Usually Storage does not care about these settings, since they are used in the interpreter.
* Но, например, при распределённой обработке запроса, настройки передаются на удалённый сервер. * But, for example, for distributed query processing, the settings are passed to the remote server.
* *
* threads - рекомендация, сколько потоков возвращать, * threads - a recommendation, how many threads to return,
* если хранилище может возвращать разное количество потоков. * if the storage can return a different number of threads.
* *
* Гарантируется, что структура таблицы не изменится за время жизни возвращенных потоков (то есть не будет ALTER, RENAME и DROP). * It is guaranteed that the structure of the table will not change over the lifetime of the returned streams (that is, there will not be ALTER, RENAME and DROP).
*/ */
virtual BlockInputStreams read( virtual BlockInputStreams read(
const Names & column_names, const Names & column_names,
@ -178,11 +178,11 @@ public:
throw Exception("Method read is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method read is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Пишет данные в таблицу. /** Writes the data to a table.
* Принимает описание запроса, в котором может содержаться информация о методе записи данных. * Receives a description of the query, which can contain information about the data write method.
* Возвращает объект, с помощью которого можно последовательно писать данные. * Returns an object by which you can write data sequentially.
* *
* Гарантируется, что структура таблицы не изменится за время жизни возвращенных потоков (то есть не будет ALTER, RENAME и DROP). * It is guaranteed that the table structure will not change over the lifetime of the returned streams (that is, there will not be ALTER, RENAME and DROP).
*/ */
virtual BlockOutputStreamPtr write( virtual BlockOutputStreamPtr write(
ASTPtr query, ASTPtr query,
@ -191,24 +191,24 @@ public:
throw Exception("Method write is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method write is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Удалить данные таблицы. Вызывается перед удалением директории с данными. /** Delete the table data. Called before deleting the directory with the data.
* Если не требуется никаких действий, кроме удаления директории с данными, этот метод можно оставить пустым. * If you do not need any action other than deleting the directory with data, you can leave this method blank.
*/ */
virtual void drop() {} virtual void drop() {}
/** Переименовать таблицу. /** Rename the table.
* Переименование имени в файле с метаданными, имени в списке таблиц в оперативке, осуществляется отдельно. * Renaming a name in a file with metadata, the name in the list of tables in the RAM, is done separately.
* В этой функции нужно переименовать директорию с данными, если она есть. * In this function, you need to rename the directory with the data, if any.
* Вызывается при заблокированной на запись структуре таблицы. * Called when the table structure is locked for write.
*/ */
virtual void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) virtual void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name)
{ {
throw Exception("Method rename is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method rename is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** ALTER таблицы в виде изменения столбцов, не затрагивающий изменение Storage или его параметров. /** ALTER tables in the form of column changes that do not affect the change to Storage or its parameters.
* Этот метод должен полностью выполнить запрос ALTER, самостоятельно заботясь о блокировках. * This method must fully execute the ALTER query, taking care of the locks itself.
* Для обновления метаданных таблицы на диске этот метод должен вызвать InterpreterAlterQuery::updateMetadata. * To update the table metadata on disk, this method should call InterpreterAlterQuery::updateMetadata.
*/ */
virtual void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context) virtual void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context)
{ {
@ -221,35 +221,35 @@ public:
throw Exception("Method dropColumnFromPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method dropColumnFromPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Выполнить запрос (DROP|DETACH) PARTITION. /** Run the query (DROP|DETACH) PARTITION.
*/ */
virtual void dropPartition(ASTPtr query, const Field & partition, bool detach, bool unreplicated, const Settings & settings) virtual void dropPartition(ASTPtr query, const Field & partition, bool detach, bool unreplicated, const Settings & settings)
{ {
throw Exception("Method dropPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method dropPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Выполнить запрос ATTACH [UNREPLICATED] (PART|PARTITION). /** Run the ATTACH request [UNREPLICATED] (PART|PARTITION).
*/ */
virtual void attachPartition(ASTPtr query, const Field & partition, bool unreplicated, bool part, const Settings & settings) virtual void attachPartition(ASTPtr query, const Field & partition, bool unreplicated, bool part, const Settings & settings)
{ {
throw Exception("Method attachPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method attachPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Выполнить запрос FETCH PARTITION. /** Run the FETCH PARTITION query.
*/ */
virtual void fetchPartition(const Field & partition, const String & from, const Settings & settings) virtual void fetchPartition(const Field & partition, const String & from, const Settings & settings)
{ {
throw Exception("Method fetchPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method fetchPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Выполнить запрос FREEZE PARTITION. То есть, создать локальный бэкап (снэпшот) данных с помощью функции localBackup (см. localBackup.h) /** Run the FREEZE PARTITION request. That is, create a local backup (snapshot) of data using the `localBackup` function (see localBackup.h)
*/ */
virtual void freezePartition(const Field & partition, const String & with_name, const Settings & settings) virtual void freezePartition(const Field & partition, const String & with_name, const Settings & settings)
{ {
throw Exception("Method freezePartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method freezePartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Выполнить запрос RESHARD PARTITION. /** Run the RESHARD PARTITION query.
*/ */
virtual void reshardPartitions(ASTPtr query, const String & database_name, virtual void reshardPartitions(ASTPtr query, const String & database_name,
const Field & first_partition, const Field & last_partition, const Field & first_partition, const Field & last_partition,
@ -260,18 +260,18 @@ public:
throw Exception("Method reshardPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method reshardPartition is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Выполнить какую-либо фоновую работу. Например, объединение кусков в таблице типа MergeTree. /** Perform any background work. For example, combining parts in a MergeTree type table.
* Возвращает - была ли выполнена какая-либо работа. * Returns whether any work has been done.
*/ */
virtual bool optimize(const String & partition, bool final, const Settings & settings) virtual bool optimize(const String & partition, bool final, const Settings & settings)
{ {
throw Exception("Method optimize is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED); throw Exception("Method optimize is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
} }
/** Если при уничтожении объекта надо сделать какую-то сложную работу - сделать её заранее. /** If you have to do some complicated work when destroying an object - do it in advance.
* Например, если таблица содержит какие-нибудь потоки для фоновой работы - попросить их завершиться и дождаться завершения. * For example, if the table contains any threads for background work - ask them to complete and wait for completion.
* По-умолчанию - ничего не делать. * By default, do nothing.
* Может вызываться одновременно из разных потоков, даже после вызова drop(). * Can be called simultaneously from different threads, even after a call to drop().
*/ */
virtual void shutdown() {} virtual void shutdown() {}
@ -295,25 +295,25 @@ protected:
private: private:
friend class TableStructureReadLock; friend class TableStructureReadLock;
/// Брать следующие два лока всегда нужно в этом порядке. /// You always need to take the next two locks in this order.
/** Берется на чтение на все время запроса INSERT и на все время слияния кусков (для MergeTree). /** It is taken for read for the entire INSERT query and the entire merge of the parts (for MergeTree).
* Берется на запись на все время ALTER MODIFY. * It is taken for write for the entire time ALTER MODIFY.
* *
* Формально: * Formally:
* Ввзятие на запись гарантирует, что: * Taking a write lock ensures that:
* 1) данные в таблице не изменится, пока лок жив, * 1) the data in the table will not change while the lock is alive,
* 2) все изменения данных после отпускания лока будут основаны на структуре таблицы на момент после отпускания лока. * 2) all changes to the data after releasing the lock will be based on the structure of the table at the time after the lock was released.
* Нужно брать на чтение на все время операции, изменяющей данные. * You need to take for read for the entire time of the operation that changes the data.
*/ */
mutable Poco::RWLock data_lock; mutable Poco::RWLock data_lock;
/** Лок для множества столбцов и пути к таблице. Берется на запись в RENAME, ALTER (для ALTER MODIFY ненадолго) и DROP. /** Lock for multiple columns and path to table. It is taken for write at RENAME, ALTER (for ALTER MODIFY for a while) and DROP.
* Берется на чтение на все время SELECT, INSERT и слияния кусков (для MergeTree). * It is taken for read for the whole time of SELECT, INSERT and merge parts (for MergeTree).
* *
* Взятие этого лока на запись - строго более "сильная" операция, чем взятие parts_writing_lock на запись. * Taking this lock for writing is a strictly "stronger" operation than taking parts_writing_lock for write record.
* То есть, если этот лок взят на запись, о parts_writing_lock можно не заботиться. * That is, if this lock is taken for write, you should not worry about `parts_writing_lock`.
* parts_writing_lock нужен только для случаев, когда не хочется брать table_structure_lock надолго (ALTER MODIFY). * parts_writing_lock is only needed for cases when you do not want to take `table_structure_lock` for long operations (ALTER MODIFY).
*/ */
mutable Poco::RWLock structure_lock; mutable Poco::RWLock structure_lock;
}; };
@ -321,7 +321,7 @@ private:
using StorageVector = std::vector<StoragePtr>; using StorageVector = std::vector<StoragePtr>;
using StorageList = std::list<StoragePtr>; using StorageList = std::list<StoragePtr>;
/// имя таблицы -> таблица /// table name -> table
using Tables = std::map<String, StoragePtr>; using Tables = std::map<String, StoragePtr>;
} }

View File

@ -15,67 +15,67 @@ namespace DB
class Context; class Context;
/** Описание таблицы. /** Description of the table.
* Не thread safe. См. IStorage::lockStructure(). * Do not thread safe. See IStorage::lockStructure ().
*/ */
class ITableDeclaration class ITableDeclaration
{ {
public: public:
/** Имя таблицы. /** The name of the table.
*/ */
virtual std::string getTableName() const = 0; virtual std::string getTableName() const = 0;
/** Получить список имён и типов столбцов таблицы, только невиртуальные. /** Get a list of names and table column types, only non-virtual.
*/ */
NamesAndTypesList getColumnsList() const; NamesAndTypesList getColumnsList() const;
const NamesAndTypesList & getColumnsListNonMaterialized() const { return getColumnsListImpl(); } const NamesAndTypesList & getColumnsListNonMaterialized() const { return getColumnsListImpl(); }
/** Получить список имён столбцов таблицы, только невиртуальные. /** Get a list of column table names, only non-virtual.
*/ */
virtual Names getColumnNamesList() const; virtual Names getColumnNamesList() const;
/** Получить описание реального (невиртуального) столбца по его имени. /** Get a description of the real (non-virtual) column by its name.
*/ */
virtual NameAndTypePair getRealColumn(const String & column_name) const; virtual NameAndTypePair getRealColumn(const String & column_name) const;
/** Присутствует ли реальный (невиртуальный) столбец с таким именем. /** Is there a real (non-virtual) column with that name.
*/ */
virtual bool hasRealColumn(const String & column_name) const; virtual bool hasRealColumn(const String & column_name) const;
NameAndTypePair getMaterializedColumn(const String & column_name) const; NameAndTypePair getMaterializedColumn(const String & column_name) const;
bool hasMaterializedColumn(const String & column_name) const; bool hasMaterializedColumn(const String & column_name) const;
/** Получить описание любого столбца по его имени. /** Get a description of any column by its name.
*/ */
virtual NameAndTypePair getColumn(const String & column_name) const; virtual NameAndTypePair getColumn(const String & column_name) const;
/** Присутствует ли столбец с таким именем. /** Is there a column with that name.
*/ */
virtual bool hasColumn(const String & column_name) const; virtual bool hasColumn(const String & column_name) const;
const DataTypePtr getDataTypeByName(const String & column_name) const; const DataTypePtr getDataTypeByName(const String & column_name) const;
/** То же самое, но в виде блока-образца. /** The same, but in the form of a block-sample.
*/ */
Block getSampleBlock() const; Block getSampleBlock() const;
Block getSampleBlockNonMaterialized() const; Block getSampleBlockNonMaterialized() const;
/** Проверить, что все запрошенные имена есть в таблице и заданы корректно. /** Verify that all the requested names are in the table and are set correctly.
* (список имён не пустой и имена не повторяются) * (the list of names is not empty and the names do not repeat)
*/ */
void check(const Names & column_names) const; void check(const Names & column_names) const;
/** Проверить, что все запрошенные имена есть в таблице и имеют правильные типы. /** Check that all the requested names are in the table and have the correct types.
*/ */
void check(const NamesAndTypesList & columns) const; void check(const NamesAndTypesList & columns) const;
/** Проверить, что все имена из пересечения names и columns есть в таблице и имеют одинаковые типы. /** Check that all names from the intersection of `names` and `columns` are in the table and have the same types.
*/ */
void check(const NamesAndTypesList & columns, const Names & column_names) const; void check(const NamesAndTypesList & columns, const Names & column_names) const;
/** Проверить, что блок с данными для записи содержит все столбцы таблицы с правильными типами, /** Check that the data block for the record contains all the columns of the table with the correct types,
* содержит только столбцы таблицы, и все столбцы различны. * contains only the columns of the table, and all the columns are different.
* Если need_all, еще проверяет, что все столбцы таблицы есть в блоке. * If need_all, still checks that all the columns of the table are in the block.
*/ */
void check(const Block & block, bool need_all = false) const; void check(const Block & block, bool need_all = false) const;

View File

@ -13,11 +13,11 @@ namespace ErrorCodes
extern const int LOGICAL_ERROR; extern const int LOGICAL_ERROR;
} }
/** Примитив синхронизации. Работает следующим образом: /** The synchronization is primitive. Works as follows:
* При создании создает неэфемерную инкрементную ноду и помечает ее как заблокированную (LOCKED). * Creates a non-ephemeral incremental node and marks it as locked (LOCKED).
* unlock() разблокирует ее (UNLOCKED). * `unlock()` unlocks it (UNLOCKED).
* При вызове деструктора или завершении сессии в ZooKeeper, переходит в состояние ABANDONED. * When the destructor is called or the session ends in ZooKeeper, it goes into the ABANDONED state.
* (В том числе при падении программы). * (Including when the program is halted).
*/ */
class AbandonableLockInZooKeeper : private boost::noncopyable class AbandonableLockInZooKeeper : private boost::noncopyable
{ {
@ -33,10 +33,10 @@ public:
const String & path_prefix_, const String & temp_path, zkutil::ZooKeeper & zookeeper_) const String & path_prefix_, const String & temp_path, zkutil::ZooKeeper & zookeeper_)
: zookeeper(zookeeper_), path_prefix(path_prefix_) : zookeeper(zookeeper_), path_prefix(path_prefix_)
{ {
/// Создадим вспомогательную эфемерную ноду. /// Let's create an secondary ephemeral node.
holder_path = zookeeper.create(temp_path + "/abandonable_lock-", "", zkutil::CreateMode::EphemeralSequential); holder_path = zookeeper.create(temp_path + "/abandonable_lock-", "", zkutil::CreateMode::EphemeralSequential);
/// Запишем в основную ноду путь к вспомогательной. /// Write the path to the secondary node in the main node.
path = zookeeper.create(path_prefix, holder_path, zkutil::CreateMode::PersistentSequential); path = zookeeper.create(path_prefix, holder_path, zkutil::CreateMode::PersistentSequential);
if (path.size() <= path_prefix.size()) if (path.size() <= path_prefix.size())
@ -56,7 +56,7 @@ public:
return path; return path;
} }
/// Распарсить число в конце пути. /// Parse the number at the end of the path.
UInt64 getNumber() const UInt64 getNumber() const
{ {
return parse<UInt64>(path.c_str() + path_prefix.size(), path.size() - path_prefix.size()); return parse<UInt64>(path.c_str() + path_prefix.size(), path.size() - path_prefix.size());
@ -69,7 +69,7 @@ public:
holder_path = ""; holder_path = "";
} }
/// Добавляет в список действия, эквивалентные unlock(). /// Adds actions equivalent to `unlock()` to the list.
void getUnlockOps(zkutil::Ops & ops) void getUnlockOps(zkutil::Ops & ops)
{ {
ops.emplace_back(std::make_unique<zkutil::Op::Remove>(path, -1)); ops.emplace_back(std::make_unique<zkutil::Op::Remove>(path, -1));
@ -84,7 +84,7 @@ public:
try try
{ {
zookeeper.tryRemoveEphemeralNodeWithRetries(holder_path); zookeeper.tryRemoveEphemeralNodeWithRetries(holder_path);
zookeeper.trySet(path, ""); /// Это не обязательно. zookeeper.trySet(path, ""); /// It's not necessary.
} }
catch (...) catch (...)
{ {
@ -96,21 +96,21 @@ public:
{ {
String holder_path; String holder_path;
/// Если нет основной ноды, UNLOCKED. /// If there is no main node, UNLOCKED.
if (!zookeeper.tryGet(path, holder_path)) if (!zookeeper.tryGet(path, holder_path))
return UNLOCKED; return UNLOCKED;
/// Если в основной ноде нет пути к вспомогательной, ABANDONED. /// If there is no path to the secondary node in the main node, ABANDONED.
if (holder_path.empty()) if (holder_path.empty())
return ABANDONED; return ABANDONED;
/// Если вспомогательная нода жива, LOCKED. /// If the secondary node is alive, LOCKED.
if (zookeeper.exists(holder_path)) if (zookeeper.exists(holder_path))
return LOCKED; return LOCKED;
/// Если вспомогательной ноды нет, нужно еще раз проверить существование основной ноды, /// If there is no secondary node, you need to test again the existence of the main node,
/// потому что за это время могли успеть вызвать unlock(). /// because during this time you might have time to call unlock().
/// Заодно уберем оттуда путь к вспомогательной ноде. /// At the same time, we will remove the path to the secondary node from there.
if (zookeeper.trySet(path, "") == ZOK) if (zookeeper.trySet(path, "") == ZOK)
return ABANDONED; return ABANDONED;

View File

@ -8,10 +8,10 @@
namespace DB namespace DB
{ {
/** Поддерживает множество названий активных кусков данных. /** Supports multiple names of active parts of data.
* Повторяет часть функциональности MergeTreeData. * Repeats part of the MergeTreeData functionality.
* TODO: обобщить с MergeTreeData. Можно этот класс оставить примерно как есть и использовать его из MergeTreeData. * TODO: generalize with MergeTreeData. It is possible to leave this class approximately as is and use it from MergeTreeData.
* Тогда в MergeTreeData можно сделать map<String, DataPartPtr> data_parts и all_data_parts. * Then in MergeTreeData you can make map<String, DataPartPtr> data_parts and all_data_parts.
*/ */
class ActiveDataPartSet class ActiveDataPartSet
{ {
@ -45,10 +45,10 @@ public:
return false; return false;
} }
/// Содержит другой кусок (получен после объединения другого куска с каким-то ещё) /// Contains another part (obtained after combining another part with some other)
bool contains(const Part & rhs) const bool contains(const Part & rhs) const
{ {
return month == rhs.month /// Куски за разные месяцы не объединяются return month == rhs.month /// Parts for different months are not combined
&& left_date <= rhs.left_date && left_date <= rhs.left_date
&& right_date >= rhs.right_date && right_date >= rhs.right_date
&& left <= rhs.left && left <= rhs.left
@ -59,19 +59,19 @@ public:
void add(const String & name); void add(const String & name);
/// Если не найдено - возвращает пустую строку. /// If not found, returns an empty string.
String getContainingPart(const String & name) const; String getContainingPart(const String & name) const;
Strings getParts() const; /// В порядке возрастания месяца и номера блока. Strings getParts() const; /// In ascending order of the month and block number.
size_t size() const; size_t size() const;
static String getPartName(DayNum_t left_date, DayNum_t right_date, Int64 left_id, Int64 right_id, UInt64 level); static String getPartName(DayNum_t left_date, DayNum_t right_date, Int64 left_id, Int64 right_id, UInt64 level);
/// Возвращает true если имя директории совпадает с форматом имени директории кусочков /// Returns true if the directory name matches the format of the directory name of the parts
static bool isPartDirectory(const String & dir_name, Poco::RegularExpression::MatchVec * out_matches = nullptr); static bool isPartDirectory(const String & dir_name, Poco::RegularExpression::MatchVec * out_matches = nullptr);
/// Кладет в DataPart данные из имени кусочка. /// Put data in DataPart from the name of the part.
static void parsePartName(const String & file_name, Part & part, const Poco::RegularExpression::MatchVec * matches = nullptr); static void parsePartName(const String & file_name, Part & part, const Poco::RegularExpression::MatchVec * matches = nullptr);
static bool contains(const String & outer_part_name, const String & inner_part_name); static bool contains(const String & outer_part_name, const String & inner_part_name);
@ -82,7 +82,7 @@ private:
mutable std::mutex mutex; mutable std::mutex mutex;
Parts parts; Parts parts;
/// Не блокируют mutex. /// Do not block mutex.
void addImpl(const String & name); void addImpl(const String & name);
String getContainingPartImpl(const String & name) const; String getContainingPartImpl(const String & name) const;
}; };

View File

@ -15,11 +15,11 @@
namespace DB namespace DB
{ {
/** Используя фиксированное количество потоков, выполнять произвольное количество задач в бесконечном цикле. /** Using a fixed number of threads, perform an arbitrary number of tasks in an infinite loop.
* При этом, одна задача может выполняться одновременно из разных потоков. * In this case, one task can run simultaneously from different threads.
* Предназначена для задач, выполняющих постоянную фоновую работу (например, слияния). * Designed for tasks that perform continuous background work (for example, merge).
* Задача - функция, возвращающая bool - сделала ли она какую-либо работу. * `Task` is a function that returns a bool - did it do any work.
* Если не сделала, то в следующий раз будет выполнена позже. * If not, then the next time will be done later.
*/ */
class BackgroundProcessingPool class BackgroundProcessingPool
{ {

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
/// Множество значений булевой переменной. То есть два булевых значения: может ли быть true, может ли быть false. /// Multiple Boolean values. That is, two Boolean values: can it be true, can it be false.
struct BoolMask struct BoolMask
{ {
bool can_be_true; bool can_be_true;

View File

@ -12,7 +12,7 @@ namespace DB
namespace DataPartsExchange namespace DataPartsExchange
{ {
/** Сервис для отправки кусков из таблицы *MergeTree. /** Service for sending parts from the table *MergeTree.
*/ */
class Service final : public InterserverIOEndpoint class Service final : public InterserverIOEndpoint
{ {
@ -36,7 +36,7 @@ private:
Logger * log; Logger * log;
}; };
/** Клиент для получения кусков из таблицы *MergeTree. /** Client for getting the parts from the table *MergeTree.
*/ */
class Fetcher final class Fetcher final
{ {
@ -46,7 +46,7 @@ public:
Fetcher(const Fetcher &) = delete; Fetcher(const Fetcher &) = delete;
Fetcher & operator=(const Fetcher &) = delete; Fetcher & operator=(const Fetcher &) = delete;
/// Скачивает кусок в tmp_директорию. Если to_detached - скачивает в директорию detached. /// Downloads a part to tmp_directory. If to_detached - downloads to the `detached` directory.
MergeTreeData::MutableDataPartPtr fetchPart( MergeTreeData::MutableDataPartPtr fetchPart(
const String & part_name, const String & part_name,
const String & replica_path, const String & replica_path,
@ -54,8 +54,8 @@ public:
int port, int port,
bool to_detached = false); bool to_detached = false);
/// Метод для перешардирования. Скачивает шардированный кусок /// Method for resharding. Downloads a sharded part
/// из заданного шарда в папку to_detached. /// from the specified shard to the `to_detached` folder.
MergeTreeData::MutableDataPartPtr fetchShardedPart( MergeTreeData::MutableDataPartPtr fetchShardedPart(
const InterserverIOEndpointLocation & location, const InterserverIOEndpointLocation & location,
const String & part_name, const String & part_name,
@ -74,7 +74,7 @@ private:
private: private:
MergeTreeData & data; MergeTreeData & data;
/// Нужно остановить передачу данных. /// You need to stop the data transfer.
std::atomic<bool> is_cancelled {false}; std::atomic<bool> is_cancelled {false};
Logger * log; Logger * log;
}; };

View File

@ -8,7 +8,7 @@ namespace DB
{ {
/** Пара засечек, определяющая диапазон строк в куске. Именно, диапазон имеет вид [begin * index_granularity, end * index_granularity). /** A pair of marks that defines the range of rows in a part. Specifically, the range has the form [begin * index_granularity, end * index_granularity).
*/ */
struct MarkRange struct MarkRange
{ {

View File

@ -13,10 +13,10 @@ using MergeTreeReadTaskPtr = std::unique_ptr<MergeTreeReadTask>;
using MergeTreeBlockSizePredictorPtr = std::shared_ptr<MergeTreeBlockSizePredictor>; using MergeTreeBlockSizePredictorPtr = std::shared_ptr<MergeTreeBlockSizePredictor>;
/** Если некоторых запрошенных столбцов нет в куске, /** If some of the requested columns are not in the part,
* то выясняем, какие столбцы может быть необходимо дополнительно прочитать, * then find out which columns may need to be read further,
* чтобы можно было вычислить DEFAULT выражение для этих столбцов. * so that you can calculate the DEFAULT expression for these columns.
* Добавляет их в columns. * Adds them to the `columns`.
*/ */
NameSet injectRequiredColumns(const MergeTreeData & storage, const MergeTreeData::DataPartPtr & part, Names & columns); NameSet injectRequiredColumns(const MergeTreeData & storage, const MergeTreeData::DataPartPtr & part, Names & columns);

View File

@ -400,7 +400,6 @@ public:
SortDescription getSortDescription() const { return sort_descr; } SortDescription getSortDescription() const { return sort_descr; }
/// Check that the part is not broken and calculate the checksums for it if they are not present. /// Check that the part is not broken and calculate the checksums for it if they are not present.
/// Проверить, что кусок не сломан и посчитать для него чексуммы, если их нет.
MutableDataPartPtr loadPartAndFixMetadata(const String & relative_path); MutableDataPartPtr loadPartAndFixMetadata(const String & relative_path);
/** Create local backup (snapshot) for parts with specified prefix. /** Create local backup (snapshot) for parts with specified prefix.

View File

@ -13,7 +13,7 @@ class MergeProgressCallback;
struct ReshardingJob; struct ReshardingJob;
/** Умеет выбирать куски для слияния и сливать их. /** Can select the parts to merge and merge them.
*/ */
class MergeTreeDataMerger class MergeTreeDataMerger
{ {
@ -36,12 +36,12 @@ public:
*/ */
size_t getMaxPartsSizeForMerge(size_t pool_size, size_t pool_used); size_t getMaxPartsSizeForMerge(size_t pool_size, size_t pool_used);
/** Выбирает, какие куски слить. Использует кучу эвристик. /** Selects which parts to merge. Uses a lot of heuristics.
* *
* can_merge - функция, определяющая, можно ли объединить пару соседних кусков. * can_merge - a function that determines if it is possible to merge a pair of adjacent parts.
* Эта функция должна координировать слияния со вставками и другими слияниями, обеспечивая, что: * This function must coordinate merge with inserts and other merges, ensuring that
* - Куски, между которыми еще может появиться новый кусок, нельзя сливать. См. METR-7001. * - Parts between which another part can still appear can not be merged. Refer to METR-7001.
* - Кусок, который уже сливается с кем-то в одном месте, нельзя начать сливать в кем-то другим в другом месте. * - A part that already merges with something in one place, you can not start to merge into something else in another place.
*/ */
bool selectPartsToMerge( bool selectPartsToMerge(
MergeTreeData::DataPartsVector & what, MergeTreeData::DataPartsVector & what,
@ -50,8 +50,8 @@ public:
size_t max_total_size_to_merge, size_t max_total_size_to_merge,
const AllowedMergingPredicate & can_merge); const AllowedMergingPredicate & can_merge);
/** Выбрать для слияния все куски в заданной партиции, если возможно. /** Select all the parts in the specified partition for merge, if possible.
* final - выбирать для слияния даже единственный кусок - то есть, позволять мерджить один кусок "сам с собой". * final - choose to merge even a single part - that is, allow to measure one part "with itself".
*/ */
bool selectAllPartsToMergeWithinPartition( bool selectAllPartsToMergeWithinPartition(
MergeTreeData::DataPartsVector & what, MergeTreeData::DataPartsVector & what,
@ -61,15 +61,15 @@ public:
DayNum_t partition, DayNum_t partition,
bool final); bool final);
/** Сливает куски. /** Merge the parts.
* Если reservation != nullptr, то и дело уменьшает размер зарезервированного места * If `reservation != nullptr`, now and then reduces the size of the reserved space
* приблизительно пропорционально количеству уже выписанных данных. * is approximately proportional to the amount of data already written.
* *
* Создаёт и возвращает временный кусок. * Creates and returns a temporary part.
* Чтобы закончить мердж, вызовите функцию renameTemporaryMergedPart. * To end the merge, call the function renameTemporaryMergedPart.
* *
* time_of_merge - время, когда мердж был назначен. * time_of_merge - the time when the merge was assigned.
* Важно при использовании ReplicatedGraphiteMergeTree для обеспечения одинакового мерджа на репликах. * Important when using ReplicatedGraphiteMergeTree to provide the same merge on replicas.
*/ */
MergeTreeData::MutableDataPartPtr mergePartsToTemporaryPart( MergeTreeData::MutableDataPartPtr mergePartsToTemporaryPart(
MergeTreeData::DataPartsVector & parts, const String & merged_name, MergeListEntry & merge_entry, MergeTreeData::DataPartsVector & parts, const String & merged_name, MergeListEntry & merge_entry,
@ -81,17 +81,17 @@ public:
const String & merged_name, const String & merged_name,
MergeTreeData::Transaction * out_transaction = nullptr); MergeTreeData::Transaction * out_transaction = nullptr);
/** Перешардирует заданную партицию. /** Reshards the specified partition.
*/ */
MergeTreeData::PerShardDataParts reshardPartition( MergeTreeData::PerShardDataParts reshardPartition(
const ReshardingJob & job, const ReshardingJob & job,
DiskSpaceMonitor::Reservation * disk_reservation = nullptr); DiskSpaceMonitor::Reservation * disk_reservation = nullptr);
/// Примерное количество места на диске, нужное для мерджа. С запасом. /// The approximate amount of disk space needed for merge. With a surplus.
static size_t estimateDiskSpaceForMerge(const MergeTreeData::DataPartsVector & parts); static size_t estimateDiskSpaceForMerge(const MergeTreeData::DataPartsVector & parts);
private: private:
/** Выбрать все куски принадлежащие одной партиции. /** Select all parts belonging to the same partition.
*/ */
MergeTreeData::DataPartsVector selectAllPartsFromPartition(DayNum_t partition); MergeTreeData::DataPartsVector selectAllPartsFromPartition(DayNum_t partition);
@ -145,7 +145,7 @@ private:
Logger * log; Logger * log;
/// Когда в последний раз писали в лог, что место на диске кончилось (чтобы не писать об этом слишком часто). /// When the last time you wrote to the log that the disk space was running out (not to write about this too often).
time_t disk_space_warning_time = 0; time_t disk_space_warning_time = 0;
CancellationHook cancellation_hook; CancellationHook cancellation_hook;

View File

@ -13,7 +13,7 @@ namespace DB
{ {
/// Чексумма одного файла. /// Checksum of one file.
struct MergeTreeDataPartChecksum struct MergeTreeDataPartChecksum
{ {
size_t file_size {}; size_t file_size {};
@ -34,8 +34,8 @@ struct MergeTreeDataPartChecksum
}; };
/** Контрольные суммы всех не временных файлов. /** Checksums of all non-temporary files.
* Для сжатых файлов хранятся чексумма и размер разжатых данных, чтобы не зависеть от способа сжатия. * For compressed files, the check sum and the size of the decompressed data are stored to not depend on the compression method.
*/ */
struct MergeTreeDataPartChecksums struct MergeTreeDataPartChecksums
{ {
@ -48,15 +48,15 @@ struct MergeTreeDataPartChecksums
void add(MergeTreeDataPartChecksums && rhs_checksums); void add(MergeTreeDataPartChecksums && rhs_checksums);
/// Проверяет, что множество столбцов и их контрольные суммы совпадают. Если нет - бросает исключение. /// Checks that the set of columns and their checksums are the same. If not, throws an exception.
/// Если have_uncompressed, для сжатых файлов сравнивает чексуммы разжатых данных. Иначе сравнивает только чексуммы файлов. /// If have_uncompressed, for compressed files it compares the checksums of the decompressed data. Otherwise, it compares only the checksums of the files.
void checkEqual(const MergeTreeDataPartChecksums & rhs, bool have_uncompressed) const; void checkEqual(const MergeTreeDataPartChecksums & rhs, bool have_uncompressed) const;
/// Проверяет, что в директории есть все нужные файлы правильных размеров. Не проверяет чексуммы. /// Checks that the directory contains all the needed files of the correct size. Does not check the checksum.
void checkSizes(const String & path) const; void checkSizes(const String & path) const;
/// Сериализует и десериализует в человекочитаемом виде. /// Serializes and deserializes in human readable form.
bool read(ReadBuffer & in); /// Возвращает false, если чексуммы в слишком старом формате. bool read(ReadBuffer & in); /// Returns false if the checksum is too old.
bool read_v2(ReadBuffer & in); bool read_v2(ReadBuffer & in);
bool read_v3(ReadBuffer & in); bool read_v3(ReadBuffer & in);
bool read_v4(ReadBuffer & in); bool read_v4(ReadBuffer & in);
@ -67,7 +67,7 @@ struct MergeTreeDataPartChecksums
return files.empty(); return files.empty();
} }
/// Контрольная сумма от множества контрольных сумм .bin файлов. /// Checksum from the set of checksums of .bin files.
void summaryDataChecksum(SipHash & hash) const; void summaryDataChecksum(SipHash & hash) const;
String toString() const; String toString() const;
@ -78,7 +78,7 @@ struct MergeTreeDataPartChecksums
class MergeTreeData; class MergeTreeData;
/// Описание куска с данными. /// Description of the data part.
struct MergeTreeDataPart : public ActiveDataPartSet::Part struct MergeTreeDataPart : public ActiveDataPartSet::Part
{ {
using Checksums = MergeTreeDataPartChecksums; using Checksums = MergeTreeDataPartChecksums;
@ -106,12 +106,12 @@ struct MergeTreeDataPart : public ActiveDataPartSet::Part
MergeTreeData & storage; MergeTreeData & storage;
size_t size = 0; /// in number of marks. size_t size = 0; /// in number of marks.
std::atomic<size_t> size_in_bytes {0}; /// размер в байтах, 0 - если не посчитано; std::atomic<size_t> size_in_bytes {0}; /// size in bytes, 0 - if not counted;
/// используется из нескольких потоков без блокировок (изменяется при ALTER). /// is used from several threads without locks (it is changed with ALTER).
time_t modification_time = 0; time_t modification_time = 0;
mutable time_t remove_time = std::numeric_limits<time_t>::max(); /// Когда кусок убрали из рабочего набора. mutable time_t remove_time = std::numeric_limits<time_t>::max(); /// When the part is removed from the working set.
/// Если true, деструктор удалит директорию с куском. /// If true, the destructor will delete the directory with the part.
bool is_temp = false; bool is_temp = false;
/// For resharding. /// For resharding.
@ -131,30 +131,30 @@ struct MergeTreeDataPart : public ActiveDataPartSet::Part
using ColumnToSize = std::map<std::string, size_t>; using ColumnToSize = std::map<std::string, size_t>;
/** Блокируется на запись при изменении columns, checksums или любых файлов куска. /** It is blocked for writing when changing columns, checksums or any part files.
* Блокируется на чтение при чтении columns, checksums или любых файлов куска. * Locked to read when reading columns, checksums or any part files.
*/ */
mutable Poco::RWLock columns_lock; mutable Poco::RWLock columns_lock;
/** Берется на все время ALTER куска: от начала записи временных фалов до их переименования в постоянные. /** It is taken for the whole time ALTER a part: from the beginning of the recording of the temporary files to their renaming to permanent.
* Берется при разлоченном columns_lock. * It is taken with unlocked `columns_lock`.
* *
* NOTE: "Можно" было бы обойтись без этого мьютекса, если бы можно было превращать ReadRWLock в WriteRWLock, не снимая блокировку. * NOTE: "You can" do without this mutex if you could turn ReadRWLock into WriteRWLock without removing the lock.
* Такое превращение невозможно, потому что создало бы дедлок, если делать его из двух потоков сразу. * This transformation is impossible, because it would create a deadlock, if you do it from two threads at once.
* Взятие этого мьютекса означает, что мы хотим заблокировать columns_lock на чтение с намерением потом, не * Taking this mutex means that we want to lock columns_lock on read with intention then, not
* снимая блокировку, заблокировать его на запись. * unblocking, block it for writing.
*/ */
mutable std::mutex alter_mutex; mutable std::mutex alter_mutex;
~MergeTreeDataPart(); ~MergeTreeDataPart();
/// Вычисляем суммарный размер всей директории со всеми файлами /// Calculate the total size of the entire directory with all the files
static size_t calcTotalSize(const String & from); static size_t calcTotalSize(const String & from);
void remove() const; void remove() const;
void renameTo(const String & new_name) const; void renameTo(const String & new_name) const;
/// Переименовывает кусок, дописав к имени префикс. to_detached - также перенести в директорию detached. /// Renames a piece by appending a prefix to the name. To_detached - also moved to the detached directory.
void renameAddPrefix(bool to_detached, const String & prefix) const; void renameAddPrefix(bool to_detached, const String & prefix) const;
/// Loads index file. Also calculates this->size if size=0 /// Loads index file. Also calculates this->size if size=0

View File

@ -10,15 +10,15 @@ namespace DB
class PKCondition; class PKCondition;
/** Выполняет запросы SELECT на данных из merge-дерева. /** Executes SELECT queries on data from the merge tree.
*/ */
class MergeTreeDataSelectExecutor class MergeTreeDataSelectExecutor
{ {
public: public:
MergeTreeDataSelectExecutor(MergeTreeData & data_); MergeTreeDataSelectExecutor(MergeTreeData & data_);
/** При чтении, выбирается набор кусков, покрывающий нужный диапазон индекса. /** When reading, selects a set of parts that covers the desired range of the index.
* max_block_number_to_read - если не ноль - не читать все куски, у которых правая граница больше этого порога. * max_block_number_to_read - if not zero, do not read all the parts whose right border is greater than this threshold.
*/ */
BlockInputStreams read( BlockInputStreams read(
const Names & column_names, const Names & column_names,
@ -28,7 +28,7 @@ public:
QueryProcessingStage::Enum & processed_stage, QueryProcessingStage::Enum & processed_stage,
size_t max_block_size, size_t max_block_size,
unsigned threads, unsigned threads,
size_t * inout_part_index, /// Если не nullptr, из этого счетчика берутся значения для виртуального столбца _part_index. size_t * inout_part_index, /// If not nullptr, from this counter values are taken for the virtual column _part_index.
Int64 max_block_number_to_read) const; Int64 max_block_number_to_read) const;
private: private:
@ -59,13 +59,13 @@ private:
const Settings & settings, const Settings & settings,
const Context & context) const; const Context & context) const;
/// Получить приблизительное значение (оценку снизу - только по полным засечкам) количества строк, попадающего под индекс. /// Get the approximate value (bottom estimate - only by full marks) of the number of rows falling under the index.
size_t getApproximateTotalRowsToRead( size_t getApproximateTotalRowsToRead(
const MergeTreeData::DataPartsVector & parts, const MergeTreeData::DataPartsVector & parts,
const PKCondition & key_condition, const PKCondition & key_condition,
const Settings & settings) const; const Settings & settings) const;
/// Создать выражение "Sign == 1". /// Create the expression "Sign == 1".
void createPositiveSignCondition( void createPositiveSignCondition(
ExpressionActionsPtr & out_expression, ExpressionActionsPtr & out_expression,
String & out_column, String & out_column,

View File

@ -36,7 +36,7 @@ struct BlockWithDateInterval
using BlocksWithDateIntervals = std::list<BlockWithDateInterval>; using BlocksWithDateIntervals = std::list<BlockWithDateInterval>;
/** Записывает новые куски с данными в merge-дерево. /** Writes new parts of data to the merge tree.
*/ */
class MergeTreeDataWriter class MergeTreeDataWriter
{ {

View File

@ -11,9 +11,9 @@ class MergeTreePartChecker
public: public:
struct Settings struct Settings
{ {
bool verbose = false; /// Пишет в stderr прогресс и ошибки, и не останавливается при первой ошибке. bool verbose = false; /// Writes progress and errors to stderr, and does not stop at the first error.
bool require_checksums = false; /// Требует, чтобы был columns.txt. bool require_checksums = false; /// Requires column.txt to be.
bool require_column_files = false; /// Требует, чтобы для всех столбцов из columns.txt были файлы. bool require_column_files = false; /// Requires that all columns from columns.txt have files.
size_t index_granularity = 8192; size_t index_granularity = 8192;
Settings & setVerbose(bool verbose_) { verbose = verbose_; return *this; } Settings & setVerbose(bool verbose_) { verbose = verbose_; return *this; }
@ -22,16 +22,16 @@ public:
Settings & setIndexGranularity(size_t index_granularity_) { index_granularity = index_granularity_; return *this; } Settings & setIndexGranularity(size_t index_granularity_) { index_granularity = index_granularity_; return *this; }
}; };
/** Полностью проверяет данные кусочка: /** Completely checks the part data
* - Вычисляет контрольные суммы и сравнивает с checksums.txt. * - Calculates checksums and compares them with checksums.txt.
* - Для массивов и строк проверяет соответствие размеров и количества данных. * - For arrays and strings, checks the correspondence of the size and amount of data.
* - Проверяет правильность засечек. * - Checks the correctness of marks.
* Бросает исключение, если кусок испорчен или если проверить не получилось (TODO: можно попробовать разделить эти случаи). * Throws an exception if the piece is corrupted or if the check fails (TODO: you can try to separate these cases).
*/ */
static void checkDataPart( static void checkDataPart(
String path, String path,
const Settings & settings, const Settings & settings,
const DataTypes & primary_key_data_types, /// Проверять первичный ключ. Если не надо - передайте пустой массив. const DataTypes & primary_key_data_types, /// Check the primary key. If it is not necessary, pass an empty array.
MergeTreeData::DataPart::Checksums * out_checksums = nullptr, MergeTreeData::DataPart::Checksums * out_checksums = nullptr,
std::atomic<bool> * is_cancelled = nullptr); std::atomic<bool> * is_cancelled = nullptr);
}; };

View File

@ -26,7 +26,7 @@ using ShardedBlocksWithDateIntervals = std::list<ShardedBlockWithDateInterval>;
struct ReshardingJob; struct ReshardingJob;
/** Создаёт новые шардированные куски с данными. /** Creates new shard parts of data.
*/ */
class MergeTreeSharder final class MergeTreeSharder final
{ {
@ -35,10 +35,10 @@ public:
MergeTreeSharder(const MergeTreeSharder &) = delete; MergeTreeSharder(const MergeTreeSharder &) = delete;
MergeTreeSharder & operator=(const MergeTreeSharder &) = delete; MergeTreeSharder & operator=(const MergeTreeSharder &) = delete;
/** Разбивает блок на блоки по ключу шардирования, каждый из которых /** Breaks the block into blocks by the sharding key, each of which
* нужно записать в отдельный кусок. Работает детерминированно: если * must be written to a separate part. It works deterministically: if
* отдать на вход такой же блок, на выходе получатся такие же блоки в * give the same block to the input, the output will be the same blocks in the
* таком же порядке. * in the same order.
*/ */
ShardedBlocksWithDateIntervals shardBlock(const Block & block); ShardedBlocksWithDateIntervals shardBlock(const Block & block);

View File

@ -65,7 +65,7 @@ protected:
void addStream(const String & path, const String & name, const IDataType & type, size_t estimated_size, void addStream(const String & path, const String & name, const IDataType & type, size_t estimated_size,
size_t level, const String & filename, bool skip_offsets); size_t level, const String & filename, bool skip_offsets);
/// Записать данные одного столбца. /// Write data of one column.
void writeData(const String & name, const IDataType & type, const IColumn & column, OffsetColumns & offset_columns, void writeData(const String & name, const IDataType & type, const IColumn & column, OffsetColumns & offset_columns,
size_t level, bool skip_offsets); size_t level, bool skip_offsets);
@ -73,7 +73,7 @@ protected:
ColumnStreams column_streams; ColumnStreams column_streams;
/// Смещение до первой строчки блока, для которой надо записать индекс. /// The offset to the first row of the block for which you want to write the index.
size_t index_offset = 0; size_t index_offset = 0;
size_t min_compress_block_size; size_t min_compress_block_size;
@ -90,8 +90,8 @@ private:
}; };
/** Для записи одного куска. /** To write one part.
* Данные относятся к одному месяцу, и пишутся в один кускок. * The data refers to one month, and are written in one part.
*/ */
class MergedBlockOutputStream : public IMergedBlockOutputStream class MergedBlockOutputStream : public IMergedBlockOutputStream
{ {
@ -112,11 +112,11 @@ public:
std::string getPartPath() const; std::string getPartPath() const;
/// Если данные заранее отсортированы. /// If the data is pre-sorted.
void write(const Block & block) override; void write(const Block & block) override;
/** Если данные не отсортированы, но мы заранее вычислили перестановку, после которой они станут сортированными. /** If the data is not sorted, but we have previously calculated the permutation, after which they will be sorted.
* Этот метод используется для экономии оперативки, так как не нужно держать одновременно два блока - исходный и отсортированный. * This method is used to save RAM, since you do not need to keep two blocks at once - the original one and the sorted one.
*/ */
void writeWithPermutation(const Block & block, const IColumn::Permutation * permutation); void writeWithPermutation(const Block & block, const IColumn::Permutation * permutation);
@ -130,14 +130,14 @@ public:
MergeTreeData::DataPart::Index & getIndex(); MergeTreeData::DataPart::Index & getIndex();
/// Сколько засечек уже записано. /// How many marks are already written.
size_t marksCount(); size_t marksCount();
private: private:
void init(); void init();
/** Если задана permutation, то переставляет значения в столбцах при записи. /** If `permutation` is given, it rearranges the values in the columns when writing.
* Это нужно, чтобы не держать целый блок в оперативке для его сортировки. * This is necessary to not keep the whole block in the RAM to sort it.
*/ */
void writeImpl(const Block & block, const IColumn::Permutation * permutation); void writeImpl(const Block & block, const IColumn::Permutation * permutation);
@ -153,7 +153,7 @@ private:
}; };
/// Записывает только те, столбцы, что лежат в block /// Writes only those columns that are in `block`
class MergedColumnOnlyOutputStream : public IMergedBlockOutputStream class MergedColumnOnlyOutputStream : public IMergedBlockOutputStream
{ {
public: public:

View File

@ -17,7 +17,7 @@ class IFunction;
using FunctionPtr = std::shared_ptr<IFunction>; using FunctionPtr = std::shared_ptr<IFunction>;
/** Диапазон с открытыми или закрытыми концами; возможно, неограниченный. /** Range with open or closed ends; Perhaps unlimited.
*/ */
struct Range struct Range
{ {
@ -26,21 +26,21 @@ private:
static bool less(const Field & lhs, const Field & rhs); static bool less(const Field & lhs, const Field & rhs);
public: public:
Field left; /// левая граница, если есть Field left; /// the left border, if any
Field right; /// правая граница, если есть Field right; /// the right border, if any
bool left_bounded = false; /// ограничен ли слева bool left_bounded = false; /// limited to the left
bool right_bounded = false; /// ограничен ли справа bool right_bounded = false; /// limited to the right
bool left_included = false; /// включает левую границу, если есть bool left_included = false; /// includes the left border, if any
bool right_included = false; /// включает правую границу, если есть bool right_included = false; /// includes the right border, if any
/// Всё множество. /// The whole set.
Range() {} Range() {}
/// Одна точка. /// One point.
Range(const Field & point) Range(const Field & point)
: left(point), right(point), left_bounded(true), right_bounded(true), left_included(true), right_included(true) {} : left(point), right(point), left_bounded(true), right_bounded(true), left_included(true), right_included(true) {}
/// Ограниченный с двух сторон диапазон. /// A bounded two-sided range.
Range(const Field & left_, bool left_included_, const Field & right_, bool right_included_) Range(const Field & left_, bool left_included_, const Field & right_, bool right_included_)
: left(left_), right(right_), : left(left_), right(right_),
left_bounded(true), right_bounded(true), left_bounded(true), right_bounded(true),
@ -69,9 +69,9 @@ public:
return r; return r;
} }
/** Оптимизировать диапазон. Если у него есть открытая граница и тип Field "неплотный" /** Optimize the range. If it has an open boundary and the Field type is "loose"
* - то преобразовать её в закрытую, сузив на единицу. * - then convert it to closed, narrowing by one.
* То есть, например, превратить (0,2) в [1]. * That is, for example, turn (0,2) into [1].
*/ */
void shrinkToIncludedIfPossible() void shrinkToIncludedIfPossible()
{ {
@ -110,13 +110,13 @@ public:
|| ((!left_included || !right_included) && !less(left, right))); || ((!left_included || !right_included) && !less(left, right)));
} }
/// x входит в range /// x contained in the range
bool contains(const Field & x) const bool contains(const Field & x) const
{ {
return !leftThan(x) && !rightThan(x); return !leftThan(x) && !rightThan(x);
} }
/// x находится левее /// x is to the left
bool rightThan(const Field & x) const bool rightThan(const Field & x) const
{ {
return (left_bounded return (left_bounded
@ -124,7 +124,7 @@ public:
: false); : false);
} }
/// x находится правее /// x is to the right
bool leftThan(const Field & x) const bool leftThan(const Field & x) const
{ {
return (right_bounded return (right_bounded
@ -134,7 +134,7 @@ public:
bool intersectsRange(const Range & r) const bool intersectsRange(const Range & r) const
{ {
/// r левее меня. /// r to the left of me.
if (r.right_bounded if (r.right_bounded
&& left_bounded && left_bounded
&& (less(r.right, left) && (less(r.right, left)
@ -142,11 +142,11 @@ public:
&& equals(r.right, left)))) && equals(r.right, left))))
return false; return false;
/// r правее меня. /// r to the right of me.
if (r.left_bounded if (r.left_bounded
&& right_bounded && right_bounded
&& (less(right, r.left) /// ...} {... && (less(right, r.left) /// ...} {...
|| ((!right_included || !r.left_included) /// ...)[... или ...](... || ((!right_included || !r.left_included) /// ...) [... or ...] (...
&& equals(r.left, right)))) && equals(r.left, right))))
return false; return false;
@ -155,7 +155,7 @@ public:
bool containsRange(const Range & r) const bool containsRange(const Range & r) const
{ {
/// r начинается левее меня. /// r starts to the left of me.
if (left_bounded if (left_bounded
&& (!r.left_bounded && (!r.left_bounded
|| less(r.left, left) || less(r.left, left)
@ -164,7 +164,7 @@ public:
&& equals(r.left, left)))) && equals(r.left, left))))
return false; return false;
/// r заканчивается правее меня. /// r ends right of me.
if (right_bounded if (right_bounded
&& (!r.right_bounded && (!r.right_bounded
|| less(right, r.right) || less(right, r.right)
@ -190,59 +190,59 @@ public:
class ASTSet; class ASTSet;
/** Условие на индекс. /** Condition on the index.
* *
* Состоит из условий на принадлежность ключа всевозможным диапазонам или множествам, * Consists of the conditions for the key belonging to all possible ranges or sets,
* а также логических связок AND/OR/NOT над этими условиями. * as well as logical links AND/OR/NOT above these conditions.
* *
* Составляет reverse polish notation от этих условий * Constructs a reverse polish notation from these conditions
* и умеет вычислять (интерпретировать) её выполнимость над диапазонами ключа. * and can calculate (interpret) its feasibility over key ranges.
*/ */
class PKCondition class PKCondition
{ {
public: public:
/// Не учитывает секцию SAMPLE. all_columns - набор всех столбцов таблицы. /// Does not include the SAMPLE section. all_columns - the set of all columns of the table.
PKCondition(ASTPtr & query, const Context & context, const NamesAndTypesList & all_columns, const SortDescription & sort_descr, PKCondition(ASTPtr & query, const Context & context, const NamesAndTypesList & all_columns, const SortDescription & sort_descr,
const Block & pk_sample_block); const Block & pk_sample_block);
/// Выполнимо ли условие в диапазоне ключей. /// Whether the condition is feasible in the key range.
/// left_pk и right_pk должны содержать все поля из sort_descr в соответствующем порядке. /// left_pk and right_pk must contain all fields in the sort_descr in the appropriate order.
/// data_types - типы столбцов первичного ключа. /// data_types - the types of the primary key columns.
bool mayBeTrueInRange(size_t used_key_size, const Field * left_pk, const Field * right_pk, const DataTypes & data_types) const; bool mayBeTrueInRange(size_t used_key_size, const Field * left_pk, const Field * right_pk, const DataTypes & data_types) const;
/// Выполнимо ли условие в полубесконечном (не ограниченном справа) диапазоне ключей. /// Is the condition valid in a semi-infinite (not limited to the right) key range.
/// left_pk должен содержать все поля из sort_descr в соответствующем порядке. /// left_pk must contain all the fields in the sort_descr in the appropriate order.
bool mayBeTrueAfter(size_t used_key_size, const Field * left_pk, const DataTypes & data_types) const; bool mayBeTrueAfter(size_t used_key_size, const Field * left_pk, const DataTypes & data_types) const;
/// Проверяет, что индекс не может быть использован. /// Checks that the index can not be used.
bool alwaysUnknownOrTrue() const; bool alwaysUnknownOrTrue() const;
/// Получить максимальный номер используемого в условии элемента первичного ключа. /// Get the maximum number of the primary key element used in the condition.
size_t getMaxKeyColumn() const; size_t getMaxKeyColumn() const;
/// Наложить дополнительное условие: значение в столбце column должно быть в диапазоне range. /// Impose an additional condition: the value in the column column must be in the `range` range.
/// Возвращает, есть ли такой столбец в первичном ключе. /// Returns whether there is such a column in the primary key.
bool addCondition(const String & column, const Range & range); bool addCondition(const String & column, const Range & range);
String toString() const; String toString() const;
/// Выражение хранится в виде обратной польской строки (Reverse Polish Notation). /// The expression is stored as Reverse Polish Notation.
struct RPNElement struct RPNElement
{ {
enum Function enum Function
{ {
/// Атомы логического выражения. /// Atoms of a Boolean expression.
FUNCTION_IN_RANGE, FUNCTION_IN_RANGE,
FUNCTION_NOT_IN_RANGE, FUNCTION_NOT_IN_RANGE,
FUNCTION_IN_SET, FUNCTION_IN_SET,
FUNCTION_NOT_IN_SET, FUNCTION_NOT_IN_SET,
FUNCTION_UNKNOWN, /// Может принимать любое значение. FUNCTION_UNKNOWN, /// Can take any value.
/// Операторы логического выражения. /// Operators of the logical expression.
FUNCTION_NOT, FUNCTION_NOT,
FUNCTION_AND, FUNCTION_AND,
FUNCTION_OR, FUNCTION_OR,
/// Константы /// Constants
ALWAYS_FALSE, ALWAYS_FALSE,
ALWAYS_TRUE, ALWAYS_TRUE,
}; };
@ -257,18 +257,18 @@ public:
Function function = FUNCTION_UNKNOWN; Function function = FUNCTION_UNKNOWN;
/// Для FUNCTION_IN_RANGE и FUNCTION_NOT_IN_RANGE. /// For FUNCTION_IN_RANGE and FUNCTION_NOT_IN_RANGE.
Range range; Range range;
size_t key_column; size_t key_column;
/// Для FUNCTION_IN_SET, FUNCTION_NOT_IN_SET /// For FUNCTION_IN_SET, FUNCTION_NOT_IN_SET
ASTPtr in_function; ASTPtr in_function;
/** Цепочка возможно-монотонных функций. /** A chain of possibly monotone functions.
* Если столбец первичного ключа завёрнут в функции, которые могут быть монотонными в некоторых диапазонах значений * If the primary key column is wrapped in functions that can be monotonous in some value ranges
* (например: -toFloat64(toDayOfWeek(date))), то здесь будут расположены функции: toDayOfWeek, toFloat64, negate. * (for example: -toFloat64(toDayOfWeek(date))), then here the functions will be located: toDayOfWeek, toFloat64, negate.
*/ */
using MonotonicFunctionsChain = std::vector<FunctionPtr>; using MonotonicFunctionsChain = std::vector<FunctionPtr>;
mutable MonotonicFunctionsChain monotonic_functions_chain; /// Выполнение функции не нарушает константность. mutable MonotonicFunctionsChain monotonic_functions_chain; /// The function execution does not violate the constancy.
}; };
static Block getBlockWithConstants( static Block getBlockWithConstants(

View File

@ -12,7 +12,7 @@ class Context;
namespace RemoteDiskSpaceMonitor namespace RemoteDiskSpaceMonitor
{ {
/** Сервис для получения информации о свободном месте на диске. /** Service to get information about free disk space.
*/ */
class Service final : public InterserverIOEndpoint class Service final : public InterserverIOEndpoint
{ {
@ -27,7 +27,7 @@ private:
const Context & context; const Context & context;
}; };
/** Клиент для получения информации о свободном месте на удалённом диске. /** Client to get information about free space on a remote disk.
*/ */
class Client final class Client final
{ {

View File

@ -11,7 +11,7 @@ class Context;
namespace RemoteQueryExecutor namespace RemoteQueryExecutor
{ {
/** Сервис для выполнения SQL запросов. /** Service for executing SQL queries.
*/ */
class Service final : public InterserverIOEndpoint class Service final : public InterserverIOEndpoint
{ {
@ -26,7 +26,7 @@ private:
Context & context; Context & context;
}; };
/** Клиент для удалённого выполнения SQL запросов. /** Client for remote execution of SQL queries.
*/ */
class Client final class Client final
{ {

View File

@ -8,7 +8,7 @@
namespace DB namespace DB
{ {
/// Позволяет узнать, куда отправлять запросы, чтобы попасть на реплику. /// Lets you know where to send requests to get to the replica.
struct ReplicatedMergeTreeAddress struct ReplicatedMergeTreeAddress
{ {

View File

@ -12,10 +12,10 @@ namespace DB
class StorageReplicatedMergeTree; class StorageReplicatedMergeTree;
/** Следит за изменением структуры таблицы в ZooKeeper и выполняет необходимые преобразования. /** Keeps track of changing the table structure in ZooKeeper and performs the necessary conversions.
* *
* NOTE Это не имеет отношения к манипуляциям с партициями, * NOTE This has nothing to do with manipulating partitions,
* которые обрабатываются через очередь репликации. * which are processed through the replication queue.
*/ */
class ReplicatedMergeTreeAlterThread class ReplicatedMergeTreeAlterThread
{ {

View File

@ -10,7 +10,7 @@ namespace DB
class StorageReplicatedMergeTree; class StorageReplicatedMergeTree;
/** Удаляет устаревшие данные таблицы типа ReplicatedMergeTree. /** Removes obsolete data from a table of type ReplicatedMergeTree.
*/ */
class ReplicatedMergeTreeCleanupThread class ReplicatedMergeTreeCleanupThread
{ {
@ -31,17 +31,17 @@ private:
void run(); void run();
void iterate(); void iterate();
/// Удалить старые куски с диска и из ZooKeeper. /// Delete old chunks from disk and from ZooKeeper.
void clearOldParts(); void clearOldParts();
/// Удалить из ZooKeeper старые записи в логе. /// Remove old records from ZooKeeper.
void clearOldLogs(); void clearOldLogs();
/// Удалить из ZooKeeper старые хеши блоков. Это делает ведущая реплика. /// Remove old block hashes from ZooKeeper. This makes a leading replica.
void clearOldBlocks(); void clearOldBlocks();
/// TODO Удаление старых quorum/failed_parts /// TODO Removing old quorum/failed_parts
/// TODO Удаление старых nonincrement_block_numbers /// TODO Removing old nonincrement_block_numbers
}; };

View File

@ -26,16 +26,16 @@ namespace ErrorCodes
} }
/// Запись о том, что нужно сделать. Только данные (их можно копировать). /// Record about what needs to be done. Only data (you can copy them).
struct ReplicatedMergeTreeLogEntryData struct ReplicatedMergeTreeLogEntryData
{ {
enum Type enum Type
{ {
EMPTY, /// Не используется. EMPTY, /// Not used.
GET_PART, /// Получить кусок с другой реплики. GET_PART, /// Get the part from another replica.
MERGE_PARTS, /// Слить куски. MERGE_PARTS, /// Merge the parts.
DROP_RANGE, /// Удалить куски в указанном месяце в указанном диапазоне номеров. DROP_RANGE, /// Delete the parts in the specified month in the specified number range.
ATTACH_PART, /// Перенести кусок из директории detached или unreplicated. ATTACH_PART, /// Move a part from the `detached` or `unreplicated` directory.
}; };
String typeToString() const String typeToString() const
@ -58,38 +58,38 @@ struct ReplicatedMergeTreeLogEntryData
String znode_name; String znode_name;
Type type = EMPTY; Type type = EMPTY;
String source_replica; /// Пустая строка значит, что эта запись была добавлена сразу в очередь, а не скопирована из лога. String source_replica; /// Empty string means that this entry was added to the queue immediately, and not copied from the log.
/// Имя куска, получающегося в результате. /// The name of resulting part.
/// Для DROP_RANGE имя несуществующего куска. Нужно удалить все куски, покрытые им. /// For DROP_RANGE, the name of a non-existent part. You need to remove all the parts covered by it.
String new_part_name; String new_part_name;
String block_id; /// Для кусков нулевого уровня - идентификатор блока для дедупликации (имя ноды в /blocks/). String block_id; /// For parts of level zero, the block identifier for deduplication (node name in /blocks /).
Strings parts_to_merge; Strings parts_to_merge;
/// Для DROP_RANGE, true значит, что куски нужно не удалить, а перенести в директорию detached. /// For DROP_RANGE, true means that the parts need not be deleted, but moved to the `detached` directory.
bool detach = false; bool detach = false;
/// Для ATTACH_PART имя куска в директории detached или unreplicated. /// For ATTACH_PART, the name of the part in the `detached` or `unreplicated` directory.
String source_part_name; String source_part_name;
/// Нужно переносить из директории unreplicated, а не detached. /// Must be moved from the `unreplicated` directory, not `detached`.
bool attach_unreplicated = false; bool attach_unreplicated = false;
/// Доступ под queue_mutex, см. ReplicatedMergeTreeQueue. /// Access under queue_mutex, see ReplicatedMergeTreeQueue.
bool currently_executing = false; /// Выполняется ли действие сейчас. bool currently_executing = false; /// Whether the action is executing now.
/// Эти несколько полей имеют лишь информационный характер (для просмотра пользователем с помощью системных таблиц). /// These several fields are informational only (for viewing by the user using system tables).
/// Доступ под queue_mutex, см. ReplicatedMergeTreeQueue. /// Access under queue_mutex, see ReplicatedMergeTreeQueue.
size_t num_tries = 0; /// Количество попыток выполнить действие (с момента старта сервера; включая выполняющееся). size_t num_tries = 0; /// The number of attempts to perform the action (since the server started, including the running one).
std::exception_ptr exception; /// Последний эксепшен, в случае безуспешной попытки выполнить действие. std::exception_ptr exception; /// The last exception, in the case of an unsuccessful attempt to perform the action.
time_t last_attempt_time = 0; /// Время начала последней попытки выполнить действие. time_t last_attempt_time = 0; /// The time at which the last attempt was attempted to complete the action.
size_t num_postponed = 0; /// Количество раз, когда действие было отложено. size_t num_postponed = 0; /// The number of times the action was postponed.
String postpone_reason; /// Причина, по которой действие было отложено, если оно отложено. String postpone_reason; /// The reason why the action was postponed, if it was postponed.
time_t last_postpone_time = 0; /// Время последнего раза, когда действие было отложено. time_t last_postpone_time = 0; /// The time of the last time the action was postponed.
/// Время создания или время копирования из общего лога в очередь конкретной реплики. /// Creation time or the time to copy from the general log to the queue of a particular replica.
time_t create_time = 0; time_t create_time = 0;
/// Величина кворума (для GET_PART) - ненулевое значение при включенной кворумной записи. /// The quorum value (for GET_PART) is a non-zero value when the quorum write is enabled.
size_t quorum = 0; size_t quorum = 0;
}; };
@ -98,7 +98,7 @@ struct ReplicatedMergeTreeLogEntry : ReplicatedMergeTreeLogEntryData
{ {
using Ptr = std::shared_ptr<ReplicatedMergeTreeLogEntry>; using Ptr = std::shared_ptr<ReplicatedMergeTreeLogEntry>;
std::condition_variable execution_complete; /// Пробуждается когда currently_executing становится false. std::condition_variable execution_complete; /// Awake when currently_executing becomes false.
static Ptr parse(const String & s, const Stat & stat); static Ptr parse(const String & s, const Stat & stat);
}; };

View File

@ -18,19 +18,19 @@ namespace DB
class StorageReplicatedMergeTree; class StorageReplicatedMergeTree;
/** Проверяет целостность кусков, запрошенных для проверки. /** Checks the integrity of the parts requested for validation.
* *
* Определяет лишние куски и убирает их из рабочего набора. * Identifies the extra parts and removes them from the working set.
* Находит отсутствующие куски и добавляет их для скачивания с реплик. * Find the missing parts and add them for download from replicas.
* Проверяет целостность данных и, в случае нарушения, * Checks the integrity of the data and, in the event of a violation,
* убирает кусок из рабочего набора и добавляет для скачивания с реплик. * removes a part from the working set and adds it for download from replicas.
*/ */
class ReplicatedMergeTreePartCheckThread class ReplicatedMergeTreePartCheckThread
{ {
public: public:
ReplicatedMergeTreePartCheckThread(StorageReplicatedMergeTree & storage_); ReplicatedMergeTreePartCheckThread(StorageReplicatedMergeTree & storage_);
/// Разбор очереди для проверки осуществляется в фоновом потоке, который нужно сначала запустить. /// Processing of the queue to be checked is done in the background thread, which you must first start.
void start(); void start();
void stop(); void stop();
@ -58,11 +58,11 @@ public:
TemporarilyStop temporarilyStop() { return TemporarilyStop(this); } TemporarilyStop temporarilyStop() { return TemporarilyStop(this); }
/// Добавить кусок (для которого есть подозрения, что он отсутствует, повреждён или не нужен) в очередь для проверки. /// Add a part (for which there are suspicions that it is missing, damaged or not needed) in the queue for check.
/// delay_to_check_seconds - проверять не раньше чем через указанное количество секунд. /// delay_to_check_seconds - check no sooner than the specified number of seconds.
void enqueuePart(const String & name, time_t delay_to_check_seconds = 0); void enqueuePart(const String & name, time_t delay_to_check_seconds = 0);
/// Получить количество кусков в очереди для проверки. /// Get the number of parts in the queue for check.
size_t size() const; size_t size() const;
~ReplicatedMergeTreePartCheckThread() ~ReplicatedMergeTreePartCheckThread()
@ -80,12 +80,12 @@ private:
Logger * log; Logger * log;
using StringSet = std::set<String>; using StringSet = std::set<String>;
using PartToCheck = std::pair<String, time_t>; /// Имя куска и минимальное время для проверки (или ноль, если не важно). using PartToCheck = std::pair<String, time_t>; /// The name of the part and the minimum time to check (or zero, if not important).
using PartsToCheckQueue = std::list<PartToCheck>; using PartsToCheckQueue = std::list<PartToCheck>;
/** Куски, для которых нужно проверить одно из двух: /** Parts for which you want to check one of two:
* - Если кусок у нас есть, сверить, его данные с его контрольными суммами, а их с ZooKeeper. * - If we have the part, check, its data with its checksums, and them with ZooKeeper.
* - Если куска у нас нет, проверить, есть ли он (или покрывающий его кусок) хоть у кого-то. * - If we do not have a part, check to see if it (or the part covering it) exists anywhere.
*/ */
StringSet parts_set; StringSet parts_set;

View File

@ -33,7 +33,7 @@ private:
} }
}; };
/// Для вычисления min_unprocessed_insert_time, max_processed_insert_time, по которым вычисляется отставание реплик. /// To calculate min_unprocessed_insert_time, max_processed_insert_time, for which the replica lag is calculated.
using InsertsByTime = std::set<LogEntryPtr, ByTime>; using InsertsByTime = std::set<LogEntryPtr, ByTime>;
@ -41,8 +41,8 @@ private:
String replica_path; String replica_path;
String logger_name; String logger_name;
/** Очередь того, что нужно сделать на этой реплике, чтобы всех догнать. Берется из ZooKeeper (/replicas/me/queue/). /** The queue of what you need to do on this line to catch up. It is taken from ZooKeeper (/replicas/me/queue/).
* В ZK записи в хронологическом порядке. Здесь - не обязательно. * In ZK records in chronological order. Here it is not necessary.
*/ */
Queue queue; Queue queue;
@ -52,51 +52,51 @@ private:
time_t last_queue_update = 0; time_t last_queue_update = 0;
/// Куски, которые появятся в результате действий, выполняемых прямо сейчас фоновыми потоками (этих действий нет в очереди). /// parts that will appear as a result of actions performed right now by background threads (these actions are not in the queue).
/// Используется, чтобы не выполнять в тот же момент другие действия с этими кусками. /// Used to not perform other actions at the same time with these parts.
StringSet future_parts; StringSet future_parts;
/// На доступ к queue, future_parts, ... /// To access the queue, future_parts, ...
std::mutex mutex; std::mutex mutex;
/// Обеспечивает только один одновременный вызов pullLogsToQueue. /// Provides only one simultaneous call to pullLogsToQueue.
std::mutex pull_logs_to_queue_mutex; std::mutex pull_logs_to_queue_mutex;
/** Каким будет множество активных кусков после выполнения всей текущей очереди - добавления новых кусков и выполнения слияний. /** What will be the set of active parts after running the entire current queue - adding new parts and performing merges.
* Используется, чтобы определять, какие мерджи уже были назначены: * Used to determine which merges have already been assigned:
* - если в этом множестве есть кусок, то мерджи более мелких кусков внутри его диапазона не делаются. * - if there is a part in this set, then the smaller parts inside its range are not made.
* Дополнительно, сюда также добавляются специальные элементы, чтобы явно запретить мерджи в некотором диапазоне (см. disableMergesInRange). * Additionally, special elements are also added here to explicitly disallow the merge in a certain range (see disableMergesInRange).
* Это множество защищено своим mutex-ом. * This set is protected by its mutex.
*/ */
ActiveDataPartSet virtual_parts; ActiveDataPartSet virtual_parts;
Logger * log = nullptr; Logger * log = nullptr;
/// Положить набор (уже существующих) кусков в virtual_parts. /// Put a set of (already existing) parts in virtual_parts.
void initVirtualParts(const MergeTreeData::DataParts & parts); void initVirtualParts(const MergeTreeData::DataParts & parts);
/// Загрузить (инициализировать) очередь из ZooKeeper (/replicas/me/queue/). /// Load (initialize) a queue from ZooKeeper (/replicas/me/queue/).
void load(zkutil::ZooKeeperPtr zookeeper); void load(zkutil::ZooKeeperPtr zookeeper);
void insertUnlocked(LogEntryPtr & entry); void insertUnlocked(LogEntryPtr & entry);
void remove(zkutil::ZooKeeperPtr zookeeper, LogEntryPtr & entry); void remove(zkutil::ZooKeeperPtr zookeeper, LogEntryPtr & entry);
/** Можно ли сейчас попробовать выполнить это действие. Если нет, нужно оставить его в очереди и попробовать выполнить другое. /** Can I now try this action. If not, you need to leave it in the queue and try another one.
* Вызывается под queue_mutex. * Called under queue_mutex.
*/ */
bool shouldExecuteLogEntry(const LogEntry & entry, String & out_postpone_reason, MergeTreeDataMerger & merger, MergeTreeData & data); bool shouldExecuteLogEntry(const LogEntry & entry, String & out_postpone_reason, MergeTreeDataMerger & merger, MergeTreeData & data);
/// После удаления элемента очереди, обновить времена insert-ов в оперативке. Выполняется под queue_mutex. /// After removing the queue element, update the insertion times in the RAM. Running under queue_mutex.
/// Возвращает информацию, какие времена изменились - эту информацию можно передать в updateTimesInZooKeeper. /// Returns information about what times have changed - this information can be passed to updateTimesInZooKeeper.
void updateTimesOnRemoval(const LogEntryPtr & entry, bool & min_unprocessed_insert_time_changed, bool & max_processed_insert_time_changed); void updateTimesOnRemoval(const LogEntryPtr & entry, bool & min_unprocessed_insert_time_changed, bool & max_processed_insert_time_changed);
/// Обновить времена insert-ов в ZooKeeper. /// Update the insertion times in ZooKeeper.
void updateTimesInZooKeeper(zkutil::ZooKeeperPtr zookeeper, bool min_unprocessed_insert_time_changed, bool max_processed_insert_time_changed); void updateTimesInZooKeeper(zkutil::ZooKeeperPtr zookeeper, bool min_unprocessed_insert_time_changed, bool max_processed_insert_time_changed);
/// Помечает элемент очереди как выполняющийся. /// Marks the element of the queue as running.
class CurrentlyExecuting class CurrentlyExecuting
{ {
private: private:
@ -105,7 +105,7 @@ private:
friend class ReplicatedMergeTreeQueue; friend class ReplicatedMergeTreeQueue;
/// Создаётся только в функции selectEntryToProcess. Вызывается под mutex-ом. /// Created only in the selectEntryToProcess function. It is called under mutex.
CurrentlyExecuting(ReplicatedMergeTreeQueue::LogEntryPtr & entry, ReplicatedMergeTreeQueue & queue); CurrentlyExecuting(ReplicatedMergeTreeQueue::LogEntryPtr & entry, ReplicatedMergeTreeQueue & queue);
public: public:
~CurrentlyExecuting(); ~CurrentlyExecuting();
@ -117,55 +117,55 @@ public:
void initialize(const String & zookeeper_path_, const String & replica_path_, const String & logger_name_, void initialize(const String & zookeeper_path_, const String & replica_path_, const String & logger_name_,
const MergeTreeData::DataParts & parts, zkutil::ZooKeeperPtr zookeeper); const MergeTreeData::DataParts & parts, zkutil::ZooKeeperPtr zookeeper);
/** Вставить действие в конец очереди. /** Paste action to the end of the queue.
* Для восстановления битых кусков во время работы. * To restore broken parts during operation.
* Не вставляет само действие в ZK (сделайте это самостоятельно). * Do not insert the action itself into ZK (do it yourself).
*/ */
void insert(zkutil::ZooKeeperPtr zookeeper, LogEntryPtr & entry); void insert(zkutil::ZooKeeperPtr zookeeper, LogEntryPtr & entry);
/** Удалить действие с указанным куском (в качестве new_part_name) из очереди. /** Delete the action with the specified part (as new_part_name) from the queue.
* Вызывается для невыполнимых действий в очереди - старых потерянных кусков. * Called for unreachable actions in the queue - old lost parts.
*/ */
bool remove(zkutil::ZooKeeperPtr zookeeper, const String & part_name); bool remove(zkutil::ZooKeeperPtr zookeeper, const String & part_name);
/** Скопировать новые записи из общего лога в очередь этой реплики. Установить log_pointer в соответствующее значение. /** Copy the new entries from the shared log to the queue of this replica. Set the log_pointer to the appropriate value.
* Если next_update_event != nullptr, вызовет это событие, когда в логе появятся новые записи. * If next_update_event != nullptr, will call this event when new entries appear in the log.
* Возвращает true, если новые записи были. * Returns true if new entries have been.
*/ */
bool pullLogsToQueue(zkutil::ZooKeeperPtr zookeeper, zkutil::EventPtr next_update_event); bool pullLogsToQueue(zkutil::ZooKeeperPtr zookeeper, zkutil::EventPtr next_update_event);
/** Удалить из очереди действия с кусками, покрываемыми part_name (из ZK и из оперативки). /** Remove the action from the queue with the parts covered by part_name (from ZK and from the RAM).
* А также дождаться завершения их выполнения, если они сейчас выполняются. * And also wait for the completion of their execution, if they are now being executed.
*/ */
void removeGetsAndMergesInRange(zkutil::ZooKeeperPtr zookeeper, const String & part_name); void removeGetsAndMergesInRange(zkutil::ZooKeeperPtr zookeeper, const String & part_name);
/** В случае, когда для выполнения мерджа в part_name недостаёт кусков /** In the case where there are not enough parts to perform the merge in part_name
* - переместить действия со сливаемыми кусками в конец очереди * - move actions with merged parts to the end of the queue
* (чтобы раньше скачать готовый смердженный кусок с другой реплики). * (in order to download a already merged part from another replica).
*/ */
StringSet moveSiblingPartsForMergeToEndOfQueue(const String & part_name); StringSet moveSiblingPartsForMergeToEndOfQueue(const String & part_name);
/** Выбрать следующее действие для обработки. /** Select the next action to process.
* merger используется только чтобы проверить, не приостановлены ли мерджи. * merger is used only to check if the merges is not suspended.
*/ */
using SelectedEntry = std::pair<ReplicatedMergeTreeQueue::LogEntryPtr, std::unique_ptr<CurrentlyExecuting>>; using SelectedEntry = std::pair<ReplicatedMergeTreeQueue::LogEntryPtr, std::unique_ptr<CurrentlyExecuting>>;
SelectedEntry selectEntryToProcess(MergeTreeDataMerger & merger, MergeTreeData & data); SelectedEntry selectEntryToProcess(MergeTreeDataMerger & merger, MergeTreeData & data);
/** Выполнить функцию func для обработки действия. /** Execute `func` function to handle the action.
* При этом, на время выполнения, отметить элемент очереди как выполняющийся * In this case, at runtime, mark the queue element as running
* (добавить в future_parts и другое). * (add into future_parts and more).
* Если в процессе обработки было исключение - сохраняет его в entry. * If there was an exception during processing, it saves it in `entry`.
* Возвращает true, если в процессе обработки не было исключений. * Returns true if there were no exceptions during the processing.
*/ */
bool processEntry(std::function<zkutil::ZooKeeperPtr()> get_zookeeper, LogEntryPtr & entry, const std::function<bool(LogEntryPtr &)> func); bool processEntry(std::function<zkutil::ZooKeeperPtr()> get_zookeeper, LogEntryPtr & entry, const std::function<bool(LogEntryPtr &)> func);
/// Будет ли кусок в будущем слит в более крупный (или мерджи кусков в данном диапазоне запрещены)? /// Will a part in the future be merged into a larger part (or merges of parts in this range are prohibited)?
bool partWillBeMergedOrMergesDisabled(const String & part_name) const; bool partWillBeMergedOrMergesDisabled(const String & part_name) const;
/// Запретить слияния в указанном диапазоне. /// Prohibit merges in the specified range.
void disableMergesInRange(const String & part_name); void disableMergesInRange(const String & part_name);
/// Посчитать количество слияний в очереди. /// Count the number of merges in the queue.
size_t countMerges(); size_t countMerges();
struct Status struct Status
@ -182,21 +182,21 @@ public:
UInt32 last_queue_update; UInt32 last_queue_update;
}; };
/// Получить информацию об очереди. /// Get information about the queue.
Status getStatus(); Status getStatus();
/// Получить данные элементов очереди. /// Get the data of the queue elements.
using LogEntriesData = std::vector<ReplicatedMergeTreeLogEntryData>; using LogEntriesData = std::vector<ReplicatedMergeTreeLogEntryData>;
void getEntries(LogEntriesData & res); void getEntries(LogEntriesData & res);
/// Получить информацию о временах insert-ов. /// Get information about the insertion times.
void getInsertTimes(time_t & out_min_unprocessed_insert_time, time_t & out_max_processed_insert_time) const; void getInsertTimes(time_t & out_min_unprocessed_insert_time, time_t & out_max_processed_insert_time) const;
}; };
/** Преобразовать число в строку формате суффиксов автоинкрементных нод в ZooKeeper. /** Convert a number to a string in the format of the suffixes of auto-incremental nodes in ZooKeeper.
* Поддерживаются также отрицательные числа - для них имя ноды выглядит несколько глупо * Negative numbers are also supported - for them the name of the node looks somewhat silly
* и не соответствует никакой автоинкрементной ноде в ZK. * and does not match any auto-incremented node in ZK.
*/ */
String padIndex(Int64 index); String padIndex(Int64 index);

View File

@ -13,9 +13,9 @@
namespace DB namespace DB
{ {
/** Для реализации функциональности "кворумная запись". /** To implement the functionality of the "quorum write".
* Информация о том, на каких репликах появился вставленный кусок данных, * Information about which replicas the inserted part of data appeared on,
* и на скольких репликах он должен быть. * and on how many replicas it should be.
*/ */
struct ReplicatedMergeTreeQuorumEntry struct ReplicatedMergeTreeQuorumEntry
{ {

View File

@ -13,10 +13,10 @@ namespace DB
class StorageReplicatedMergeTree; class StorageReplicatedMergeTree;
/** Инициализирует сессию в ZK. /** Initializes ZK session.
* Выставляет эфемерные ноды. Выставляет нужные для обнаружения реплики значения нод. * Exposes ephemeral nodes. It sets the node values that are required for replica detection.
* Запускает участие в выборе лидера. Запускает все фоновые потоки. * Starts participation in the leader selection. Starts all background threads.
* Затем следит за тем, не истекла ли сессия. И если истекла - переинициализирует её. * Then monitors whether the session has expired. And if it expired, it will reinitialize it.
*/ */
class ReplicatedMergeTreeRestartingThread class ReplicatedMergeTreeRestartingThread
{ {
@ -51,23 +51,23 @@ private:
Poco::Event wakeup_event; Poco::Event wakeup_event;
std::atomic<bool> need_stop {false}; std::atomic<bool> need_stop {false};
/// Случайные данные, которые мы записали в /replicas/me/is_active. /// The random data we wrote into `/replicas/me/is_active`.
String active_node_identifier; String active_node_identifier;
std::thread thread; std::thread thread;
void run(); void run();
/// Запустить или остановить фоновые потоки. Используется для частичной переинициализации при пересоздании сессии в ZooKeeper. /// Start or stop background threads. Used for partial reinitialization when re-creating a session in ZooKeeper.
bool tryStartup(); /// Возвращает false, если недоступен ZooKeeper. bool tryStartup(); /// Returns false if ZooKeeper is not available.
/// Отметить в ZooKeeper, что эта реплика сейчас активна. /// Note in ZooKeeper that this replica is currently active.
void activateReplica(); void activateReplica();
/// Удалить куски, для которых кворум пофейлился (за то время, когда реплика была неактивной). /// Delete the parts for which the quorum has failed (for the time when the replica was inactive).
void removeFailedQuorumParts(); void removeFailedQuorumParts();
/// Если есть недостигнутый кворум, и у нас есть кусок, то добавить эту реплику в кворум. /// If there is an unreachable quorum, and we have a part, then add this replica to the quorum.
void updateQuorumIfWeHavePart(); void updateQuorumIfWeHavePart();
void partialShutdown(); void partialShutdown();

View File

@ -10,14 +10,14 @@ namespace DB
class StorageReplicatedMergeTree; class StorageReplicatedMergeTree;
/** Описание задачи перешардирования. /** Description of the task of rescheduling.
*/ */
struct ReshardingJob final struct ReshardingJob final
{ {
public: public:
ReshardingJob() = default; ReshardingJob() = default;
/// Создаёт описание на основе его сериализованного представления. /// Creates a description based on its serialized representation.
ReshardingJob(const std::string & serialized_job); ReshardingJob(const std::string & serialized_job);
ReshardingJob(const std::string & database_name_, const std::string & table_name_, ReshardingJob(const std::string & database_name_, const std::string & table_name_,
@ -32,7 +32,7 @@ public:
operator bool() const; operator bool() const;
/// Сериализует описание задачи. /// Serializes the task description.
std::string toString() const; std::string toString() const;
bool isCoordinated() const; bool isCoordinated() const;

View File

@ -73,7 +73,7 @@ public:
UInt64 subscribe(const std::string & coordinator_id, const std::string & query); UInt64 subscribe(const std::string & coordinator_id, const std::string & query);
/// Cancel the aforementionned subscription. /// Cancel the aforementionned subscription.
void unsubscribe(const std::string & coordinator_id); void unsubscribe(const std::string & coordinator_id);
/// Увеличить количество партиций входящих в одну распределённую задачу. Вызывается с исполнителя. /// Increase the number of partitions included in one distributed task. Called from the executor.
void addPartitions(const std::string & coordinator_id, const PartitionList & partition_list); void addPartitions(const std::string & coordinator_id, const PartitionList & partition_list);
/// Rearrange partitions into two categories: coordinated job, uncoordinated job. /// Rearrange partitions into two categories: coordinated job, uncoordinated job.
/// Returns an iterator to the beginning of the list of uncoordinated jobs. /// Returns an iterator to the beginning of the list of uncoordinated jobs.
@ -196,9 +196,9 @@ private:
/// Perform one job. /// Perform one job.
void perform(const std::string & job_descriptor, const std::string & job_name); void perform(const std::string & job_descriptor, const std::string & job_name);
/// Разбить куски входящие в партицию на несколько, согласно ключу шардирования. /// Split the parts of the partition into several, according to the sharding key.
/// Оновременно перегруппировать эти куски по шардам и слить куски в каждой группе. /// Simultaneously regroup these parts by shards and merge the parts in each group.
/// При завершении этого процесса создаётся новая партиция для каждого шарда. /// When this process is completed, a new partition is created for each shard.
void createShardedPartitions(); void createShardedPartitions();
/// Upload all the partitions resulting from source partition resharding to their /// Upload all the partitions resulting from source partition resharding to their

View File

@ -14,7 +14,7 @@ class StorageReplicatedMergeTree;
namespace ShardedPartitionUploader namespace ShardedPartitionUploader
{ {
/** Сервис для получения кусков из партиции таблицы *MergeTree. /** Service for retrieving parts from the partitions of the *MergeTree table.
*/ */
class Service final : public InterserverIOEndpoint class Service final : public InterserverIOEndpoint
{ {
@ -31,7 +31,7 @@ private:
Logger * log = &Logger::get("ShardedPartitionUploader::Service"); Logger * log = &Logger::get("ShardedPartitionUploader::Service");
}; };
/** Клиент для отправления кусков из партиции таблицы *MergeTree. /** Client for sending parts from the partition of the *MergeTree table.
*/ */
class Client final class Client final
{ {

View File

@ -18,23 +18,23 @@ namespace DB
class Context; class Context;
/** При вставке, буферизует данные в оперативке, пока не превышены некоторые пороги. /** During insertion, buffers the data in the RAM until certain thresholds are exceeded.
* Когда пороги превышены - сбрасывает данные в другую таблицу. * When thresholds are exceeded, flushes the data to another table.
* При чтении, читает как из своих буферов, так и из подчинённой таблицы. * When reading, it reads both from its buffers and from the subordinate table.
* *
* Буфер представляет собой набор из num_shards блоков. * The buffer is a set of num_shards blocks.
* При записи, выбирается номер блока по остатку от деления ThreadNumber на num_shards (или один из других), * When writing, select the block number by the remainder of the `ThreadNumber` division by `num_shards` (or one of the others),
* и в соответствующий блок добавляются строчки. * and add rows to the corresponding block.
* При использовании блока, он блокируется некоторым mutex-ом. Если при записи, соответствующий блок уже занят * When using a block, it is blocked by some mutex. If during write the corresponding block is already occupied
* - пробуем заблокировать следующий по кругу блок, и так не более num_shards раз (далее блокируемся). * - try to block the next block clockwise, and so no more than `num_shards` times (further blocked).
* Пороги проверяются при вставке, а также, периодически, в фоновом потоке (чтобы реализовать пороги по времени). * Thresholds are checked on insertion, and, periodically, in the background thread (to implement time thresholds).
* Пороги действуют независимо для каждого shard-а. Каждый shard может быть сброшен независимо от других. * Thresholds act independently for each shard. Each shard can be flushed independently of the others.
* Если в таблицу вставляется блок, который сам по себе превышает max-пороги, то он записывается сразу в подчинённую таблицу без буферизации. * If a block is inserted into the table, which itself exceeds the max-thresholds, it is written directly to the subordinate table without buffering.
* Пороги могут быть превышены. Например, если max_rows = 1 000 000, в буфере уже было 500 000 строк, * Thresholds can be exceeded. For example, if max_rows = 1 000 000, the buffer already had 500 000 rows,
* и добавляется кусок из 800 000 строк, то в буфере окажется 1 300 000 строк, и затем такой блок будет записан в подчинённую таблицу * and a part of 800,000 lines is added, then there will be 1 300 000 rows in the buffer, and then such a block will be written to the subordinate table
* *
* При уничтожении таблицы типа Buffer и при завершении работы, все данные сбрасываются. * When you destroy a Buffer type table and when you quit, all data is discarded.
* Данные в буфере не реплицируются, не логгируются на диск, не индексируются. При грубом перезапуске сервера, данные пропадают. * The data in the buffer is not replicated, not logged to disk, not indexed. With a rough restart of the server, the data is lost.
*/ */
class StorageBuffer : private ext::shared_ptr_helper<StorageBuffer>, public IStorage class StorageBuffer : private ext::shared_ptr_helper<StorageBuffer>, public IStorage
{ {
@ -43,16 +43,16 @@ friend class BufferBlockInputStream;
friend class BufferBlockOutputStream; friend class BufferBlockOutputStream;
public: public:
/// Пороги. /// Thresholds.
struct Thresholds struct Thresholds
{ {
time_t time; /// Количество секунд от момента вставки первой строчки в блок. time_t time; /// The number of seconds from the insertion of the first row into the block.
size_t rows; /// Количество строк в блоке. size_t rows; /// The number of rows in the block.
size_t bytes; /// Количество (несжатых) байт в блоке. size_t bytes; /// The number of (uncompressed) bytes in the block.
}; };
/** num_shards - уровень внутреннего параллелизма (количество независимых буферов) /** num_shards - the level of internal parallelism (the number of independent buffers)
* Буфер сбрасывается, если превышены все минимальные пороги или хотя бы один из максимальных. * The buffer is reset if all minimum thresholds or at least one of the maximum thresholds are exceeded.
*/ */
static StoragePtr create(const std::string & name_, NamesAndTypesListPtr columns_, static StoragePtr create(const std::string & name_, NamesAndTypesListPtr columns_,
const NamesAndTypesList & materialized_columns_, const NamesAndTypesList & materialized_columns_,
@ -78,7 +78,7 @@ public:
BlockOutputStreamPtr write(ASTPtr query, const Settings & settings) override; BlockOutputStreamPtr write(ASTPtr query, const Settings & settings) override;
/// Сбрасывает все буферы в подчинённую таблицу. /// Resets all buffers to the subordinate table.
void shutdown() override; void shutdown() override;
bool optimize(const String & partition, bool final, const Settings & settings) override; bool optimize(const String & partition, bool final, const Settings & settings) override;
@ -90,7 +90,7 @@ public:
bool supportsIndexForIn() const override { return true; } bool supportsIndexForIn() const override { return true; }
bool supportsParallelReplicas() const override { return true; } bool supportsParallelReplicas() const override { return true; }
/// Структура подчинённой таблицы не проверяется и не изменяется. /// The structure of the subordinate table is not checked and does not change.
void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context) override; void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context) override;
private: private:
@ -106,7 +106,7 @@ private:
std::mutex mutex; std::mutex mutex;
}; };
/// Имеется num_shards независимых буферов. /// There are `num_shards` of independent buffers.
const size_t num_shards; const size_t num_shards;
std::vector<Buffer> buffers; std::vector<Buffer> buffers;
@ -115,12 +115,12 @@ private:
const String destination_database; const String destination_database;
const String destination_table; const String destination_table;
bool no_destination; /// Если задано - не записывать данные из буфера, а просто опустошать буфер. bool no_destination; /// If set, do not write data from the buffer, but simply empty the buffer.
Poco::Logger * log; Poco::Logger * log;
Poco::Event shutdown_event; Poco::Event shutdown_event;
/// Выполняет сброс данных по таймауту. /// Resets data by timeout.
std::thread flush_thread; std::thread flush_thread;
StorageBuffer(const std::string & name_, NamesAndTypesListPtr columns_, StorageBuffer(const std::string & name_, NamesAndTypesListPtr columns_,
@ -132,12 +132,12 @@ private:
const String & destination_database_, const String & destination_table_); const String & destination_database_, const String & destination_table_);
void flushAllBuffers(bool check_thresholds = true); void flushAllBuffers(bool check_thresholds = true);
/// Сбросить буфер. Если выставлено check_thresholds - сбрасывает только если превышены пороги. /// Reset the buffer. If check_thresholds is set - resets only if thresholds are exceeded.
void flushBuffer(Buffer & buffer, bool check_thresholds); void flushBuffer(Buffer & buffer, bool check_thresholds);
bool checkThresholds(const Buffer & buffer, time_t current_time, size_t additional_rows = 0, size_t additional_bytes = 0) const; bool checkThresholds(const Buffer & buffer, time_t current_time, size_t additional_rows = 0, size_t additional_bytes = 0) const;
bool checkThresholdsImpl(size_t rows, size_t bytes, time_t time_passed) const; bool checkThresholdsImpl(size_t rows, size_t bytes, time_t time_passed) const;
/// Аргумент table передаётся, так как иногда вычисляется заранее. Он должен соответствовать destination-у. /// `table` argument is passed, as it is sometimes evaluated beforehand. It must match the `destination`.
void writeBlockToDestination(const Block & block, StoragePtr table); void writeBlockToDestination(const Block & block, StoragePtr table);
void flushThread(); void flushThread();

View File

@ -13,8 +13,8 @@ class DatabaseCloud;
class Context; class Context;
/** Облачная таблица. Может находиться только в облачной базе данных. /** Cloud table. It can only be in the cloud database.
* При записи в таблицу, данные записываются в локальные таблицы на нескольких серверах облака. * When writing to a table, data is written to local tables on multiple cloud servers.
*/ */
class StorageCloud : private ext::shared_ptr_helper<StorageCloud>, public IStorage class StorageCloud : private ext::shared_ptr_helper<StorageCloud>, public IStorage
{ {
@ -32,7 +32,7 @@ public:
std::string getName() const override { return "Cloud"; } std::string getName() const override { return "Cloud"; }
std::string getTableName() const override { return name; } std::string getTableName() const override { return name; }
/// Проверка откладывается до метода read. Там проверяется поддержка у использующихся таблиц. /// The check is postponed to the `read` method. It checks the support of the tables used.
bool supportsSampling() const override { return true; } bool supportsSampling() const override { return true; }
bool supportsPrewhere() const override { return true; } bool supportsPrewhere() const override { return true; }
bool supportsFinal() const override { return true; } bool supportsFinal() const override { return true; }
@ -50,7 +50,7 @@ public:
size_t max_block_size = DEFAULT_BLOCK_SIZE, size_t max_block_size = DEFAULT_BLOCK_SIZE,
unsigned threads = 1) override; unsigned threads = 1) override;
void drop() override {} /// Вся нужная работа в DatabaseCloud::removeTable void drop() override {} /// All the necessary work in `DatabaseCloud::removeTable`
void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override
{ {

View File

@ -18,11 +18,11 @@ class Context;
class StorageDistributedDirectoryMonitor; class StorageDistributedDirectoryMonitor;
/** Распределённая таблица, находящаяся на нескольких серверах. /** A distributed table that resides on multiple servers.
* Использует данные заданной БД и таблицы на каждом сервере. * Uses data from the specified database and tables on each server.
* *
* Можно передать один адрес, а не несколько. * You can pass one address, not several.
* В этом случае, таблицу можно считать удалённой, а не распределённой. * In this case, the table can be considered remote, rather than distributed.
*/ */
class StorageDistributed : private ext::shared_ptr_helper<StorageDistributed>, public IStorage class StorageDistributed : private ext::shared_ptr_helper<StorageDistributed>, public IStorage
{ {
@ -32,23 +32,23 @@ class StorageDistributed : private ext::shared_ptr_helper<StorageDistributed>, p
public: public:
static StoragePtr create( static StoragePtr create(
const std::string & name_, /// Имя таблицы. const std::string & name_, /// The name of the table.
NamesAndTypesListPtr columns_, /// Список столбцов. NamesAndTypesListPtr columns_, /// List of columns.
const NamesAndTypesList & materialized_columns_, const NamesAndTypesList & materialized_columns_,
const NamesAndTypesList & alias_columns_, const NamesAndTypesList & alias_columns_,
const ColumnDefaults & column_defaults_, const ColumnDefaults & column_defaults_,
const String & remote_database_, /// БД на удалённых серверах. const String & remote_database_, /// database on remote servers.
const String & remote_table_, /// Имя таблицы на удалённых серверах. const String & remote_table_, /// The name of the table on the remote servers.
const String & cluster_name, const String & cluster_name,
Context & context_, Context & context_,
const ASTPtr & sharding_key_, const ASTPtr & sharding_key_,
const String & data_path_); const String & data_path_);
static StoragePtr create( static StoragePtr create(
const std::string & name_, /// Имя таблицы. const std::string & name_, /// The name of the table.
NamesAndTypesListPtr columns_, /// Список столбцов. NamesAndTypesListPtr columns_, /// List of columns.
const String & remote_database_, /// БД на удалённых серверах. const String & remote_database_, /// database on remote servers.
const String & remote_table_, /// Имя таблицы на удалённых серверах. const String & remote_table_, /// The name of the table on the remote servers.
ClusterPtr & owned_cluster_, ClusterPtr & owned_cluster_,
Context & context_); Context & context_);
@ -78,8 +78,8 @@ public:
void drop() override {} void drop() override {}
void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override { name = new_table_name; } void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override { name = new_table_name; }
/// в подтаблицах добавлять и удалять столбы нужно вручную /// in the sub-tables, you need to manually add and delete columns
/// структура подтаблиц не проверяется /// the structure of the sub-table is not checked
void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context) override; void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context) override;
void shutdown() override; void shutdown() override;
@ -90,7 +90,7 @@ public:
const ASTPtr & sharding_key_expr, bool do_copy, const Field & coordinator, const ASTPtr & sharding_key_expr, bool do_copy, const Field & coordinator,
const Settings & settings) override; const Settings & settings) override;
/// От каждой реплики получить описание соответствующей локальной таблицы. /// From each replica, get a description of the corresponding local table.
BlockInputStreams describe(const Context & context, const Settings & settings); BlockInputStreams describe(const Context & context, const Settings & settings);
const ExpressionActionsPtr & getShardingKeyExpr() const { return sharding_key_expr; } const ExpressionActionsPtr & getShardingKeyExpr() const { return sharding_key_expr; }
@ -156,7 +156,7 @@ private:
bool has_sharding_key; bool has_sharding_key;
ExpressionActionsPtr sharding_key_expr; ExpressionActionsPtr sharding_key_expr;
String sharding_key_column_name; String sharding_key_column_name;
String path; /// Может быть пустым, если data_path_ пустой. В этом случае, директория для данных для отправки не создаётся. String path; /// Can be empty if data_path_ is empty. In this case, a directory for the data to be sent is not created.
std::unordered_map<std::string, std::unique_ptr<StorageDistributedDirectoryMonitor>> directory_monitors; std::unordered_map<std::string, std::unique_ptr<StorageDistributedDirectoryMonitor>> directory_monitors;
}; };

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Позволяет создать таблицу по имени движка. /** Allows you to create a table by the name of the engine.
*/ */
class StorageFactory : public Singleton<StorageFactory> class StorageFactory : public Singleton<StorageFactory>
{ {

View File

@ -13,12 +13,12 @@ class Join;
using JoinPtr = std::shared_ptr<Join>; using JoinPtr = std::shared_ptr<Join>;
/** Позволяет сохранить состояние для последующего использования в правой части JOIN. /** Allows you save the state for later use on the right side of the JOIN.
* При вставке в таблицу, данные будут вставлены в состояние, * When inserted into a table, the data will be inserted into the state,
* а также записаны в файл-бэкап, для восстановления после перезапуска. * and also written to the backup file, to restore after the restart.
* Чтение из таблицы напрямую невозможно - возможно лишь указание в правой части JOIN. * Reading from the table is not possible directly - only specifying on the right side of JOIN is possible.
* *
* При использовании, JOIN должен быть соответствующего типа (ANY|ALL LEFT|INNER ...). * When using, JOIN must be of the appropriate type (ANY|ALL LEFT|INNER ...).
*/ */
class StorageJoin : private ext::shared_ptr_helper<StorageJoin>, public StorageSetOrJoinBase class StorageJoin : private ext::shared_ptr_helper<StorageJoin>, public StorageSetOrJoinBase
{ {
@ -43,10 +43,10 @@ public:
String getName() const override { return "Join"; } String getName() const override { return "Join"; }
/// Получить доступ к внутренностям. /// Access the innards.
JoinPtr & getJoin() { return join; } JoinPtr & getJoin() { return join; }
/// Убедиться, что структура данных подходит для осуществления JOIN такого типа. /// Verify that the data structure is suitable for implementing this type of JOIN.
void assertCompatible(ASTTableJoin::Kind kind_, ASTTableJoin::Strictness strictness_) const; void assertCompatible(ASTTableJoin::Kind kind_, ASTTableJoin::Strictness strictness_) const;
private: private:

View File

@ -21,22 +21,22 @@ namespace ErrorCodes
} }
/** Смещение до каждой некоторой пачки значений. /** Offsets to every single set of values.
* Эти пачки имеют одинаковый размер в разных столбцах. * These sets are the same size in different columns.
* Они нужны, чтобы можно было читать данные в несколько потоков. * They are needed so that you can read the data in several threads.
*/ */
struct Mark struct Mark
{ {
size_t rows; /// Сколько строк содержится в этой пачке и всех предыдущих. size_t rows; /// How many lines are contained in this set and all previous ones.
size_t offset; /// Смещение до пачки в сжатом файле. size_t offset; /// The offset to the set in the compressed file.
}; };
using Marks = std::vector<Mark>; using Marks = std::vector<Mark>;
/** Реализует хранилище, подходящее для логов. /** Implements a repository that is suitable for logs.
* Ключи не поддерживаются. * Keys are not supported.
* Данные хранятся в сжатом виде. * The data is stored in a compressed form.
*/ */
class StorageLog : private ext::shared_ptr_helper<StorageLog>, public IStorage class StorageLog : private ext::shared_ptr_helper<StorageLog>, public IStorage
{ {
@ -45,9 +45,9 @@ friend class LogBlockInputStream;
friend class LogBlockOutputStream; friend class LogBlockOutputStream;
public: public:
/** Подцепить таблицу с соответствующим именем, по соответствующему пути (с / на конце), /** hook the table with the appropriate name, along the appropriate path (with / at the end),
* (корректность имён и путей не проверяется) * (the correctness of names and paths is not verified)
* состоящую из указанных столбцов; создать файлы, если их нет. * consisting of the specified columns; Create files if they do not exist.
*/ */
static StoragePtr create( static StoragePtr create(
const std::string & path_, const std::string & path_,
@ -82,11 +82,11 @@ public:
void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override; void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override;
/// Данные столбца /// Column data
struct ColumnData struct ColumnData
{ {
/// Задает номер столбца в файле с засечками. /// Specifies the column number in the marks file.
/// Не обязательно совпадает с номером столбца среди столбцов таблицы: здесь нумеруются также столбцы с длинами массивов. /// Does not necessarily match the column number among the columns of the table: columns with lengths of arrays are also numbered here.
size_t column_index; size_t column_index;
Poco::File data_file; Poco::File data_file;
@ -112,12 +112,12 @@ protected:
const ColumnDefaults & column_defaults_, const ColumnDefaults & column_defaults_,
size_t max_compress_block_size_); size_t max_compress_block_size_);
/// Прочитать файлы с засечками, если они ещё не прочитаны. /// Read marks files if they are not already read.
/// Делается лениво, чтобы при большом количестве таблиц, сервер быстро стартовал. /// It is done lazily, so that with a large number of tables, the server starts quickly.
/// Нельзя вызывать с залоченным на запись rwlock. /// You can not call with a write locked `rwlock`.
void loadMarks(); void loadMarks();
/// Можно вызывать при любом состоянии rwlock. /// Can be called with any state of `rwlock`.
size_t marksCount(); size_t marksCount();
BlockInputStreams read( BlockInputStreams read(
@ -143,7 +143,7 @@ private:
void loadMarksImpl(bool load_null_marks); void loadMarksImpl(bool load_null_marks);
/// Порядок добавления файлов не должен меняться: он соответствует порядку столбцов в файле с засечками. /// The order of adding files should not change: it corresponds to the order of the columns in the marks file.
void addFile(const String & column_name, const IDataType & type, size_t level = 0); void addFile(const String & column_name, const IDataType & type, size_t level = 0);
bool loaded_marks; bool loaded_marks;
@ -157,12 +157,12 @@ protected:
FileChecker file_checker; FileChecker file_checker;
private: private:
/** Для обычных столбцов, в засечках указано количество строчек в блоке. /** For normal columns, the number of rows in the block is specified in the marks.
* Для столбцов-массивов и вложенных структур, есть более одной группы засечек, соответствующих разным файлам: * For array columns and nested structures, there are more than one group of marks that correspond to different files
* - для внутренностей (файла name.bin) - указано суммарное количество элементов массивов в блоке, * - for insides (file name.bin) - the total number of array elements in the block is specified,
* - для размеров массивов (файла name.size0.bin) - указано количество строчек (самих целых массивов) в блоке. * - for array sizes (file name.size0.bin) - the number of rows (the whole arrays themselves) in the block is specified.
* *
* Вернуть первую попавшуюся группу засечек, в которых указано количество строчек, а не внутренностей массивов. * Return the first group of marks that contain the number of rows, but not the internals of the arrays.
*/ */
const Marks & getMarksWithRealRowCount() const; const Marks & getMarksWithRealRowCount() const;

View File

@ -15,10 +15,10 @@ namespace DB
class StorageMemory; class StorageMemory;
/** Реализует хранилище в оперативке. /** Implements storage in the RAM.
* Подходит для временных данных. * Suitable for temporary data.
* В нём не поддерживаются ключи. * It does not support keys.
* Данные хранятся в виде набора блоков и никуда дополнительно не сохраняются. * Data is stored as a set of blocks and is not stored anywhere else.
*/ */
class StorageMemory : private ext::shared_ptr_helper<StorageMemory>, public IStorage class StorageMemory : private ext::shared_ptr_helper<StorageMemory>, public IStorage
{ {
@ -63,7 +63,7 @@ private:
String name; String name;
NamesAndTypesListPtr columns; NamesAndTypesListPtr columns;
/// Сами данные. list - чтобы при вставке в конец, существующие итераторы не инвалидировались. /// The data itself. `list` - so that when inserted to the end, the existing iterators are not invalidated.
BlocksList data; BlocksList data;
std::mutex mutex; std::mutex mutex;

View File

@ -9,8 +9,8 @@
namespace DB namespace DB
{ {
/** Таблица, представляющая собой объединение произвольного количества других таблиц. /** A table that represents the union of an arbitrary number of other tables.
* У всех таблиц должна быть одинаковая структура. * All tables must have the same structure.
*/ */
class StorageMerge : private ext::shared_ptr_helper<StorageMerge>, public IStorage class StorageMerge : private ext::shared_ptr_helper<StorageMerge>, public IStorage
{ {
@ -18,26 +18,26 @@ friend class ext::shared_ptr_helper<StorageMerge>;
public: public:
static StoragePtr create( static StoragePtr create(
const std::string & name_, /// Имя таблицы. const std::string & name_, /// The name of the table.
NamesAndTypesListPtr columns_, /// Список столбцов. NamesAndTypesListPtr columns_, /// List of columns.
const String & source_database_, /// В какой БД искать таблицы-источники. const String & source_database_, /// In which database to look for source tables.
const String & table_name_regexp_, /// Регексп имён таблиц-источников. const String & table_name_regexp_, /// Regex names of source tables.
const Context & context_); /// Известные таблицы. const Context & context_); /// Known tables.
static StoragePtr create( static StoragePtr create(
const std::string & name_, /// Имя таблицы. const std::string & name_, /// The name of the table.
NamesAndTypesListPtr columns_, /// Список столбцов. NamesAndTypesListPtr columns_, /// List of columns.
const NamesAndTypesList & materialized_columns_, const NamesAndTypesList & materialized_columns_,
const NamesAndTypesList & alias_columns_, const NamesAndTypesList & alias_columns_,
const ColumnDefaults & column_defaults_, const ColumnDefaults & column_defaults_,
const String & source_database_, /// В какой БД искать таблицы-источники. const String & source_database_, /// In which database to look for source tables.
const String & table_name_regexp_, /// Регексп имён таблиц-источников. const String & table_name_regexp_, /// Regex names of source tables.
const Context & context_); /// Известные таблицы. const Context & context_); /// Known tables.
std::string getName() const override { return "Merge"; } std::string getName() const override { return "Merge"; }
std::string getTableName() const override { return name; } std::string getTableName() const override { return name; }
/// Проверка откладывается до метода read. Там проверяется поддержка у использующихся таблиц. /// The check is delayed to the read method. It checks the support of the tables used.
bool supportsSampling() const override { return true; } bool supportsSampling() const override { return true; }
bool supportsPrewhere() const override { return true; } bool supportsPrewhere() const override { return true; }
bool supportsFinal() const override { return true; } bool supportsFinal() const override { return true; }
@ -59,8 +59,8 @@ public:
void drop() override {} void drop() override {}
void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override { name = new_table_name; } void rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) override { name = new_table_name; }
/// в подтаблицах добавлять и удалять столбы нужно вручную /// you need to add and remove columns in the sub-tables manually
/// структура подтаблиц не проверяется /// the structure of sub-tables is not checked
void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context) override; void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context) override;
private: private:

View File

@ -533,7 +533,7 @@ void StorageMergeTree::attachPartition(ASTPtr query, const Field & field, bool u
LOG_INFO(log, "Finished attaching part"); LOG_INFO(log, "Finished attaching part");
} }
/// New parts with other data may appear in place of deleted pieces. /// New parts with other data may appear in place of deleted parts.
context.resetCaches(); context.resetCaches();
} }

View File

@ -14,7 +14,7 @@
namespace DB namespace DB
{ {
/** См. описание структуры данных в MergeTreeData. /** See the description of the data structure in MergeTreeData.
*/ */
class StorageMergeTree : private ext::shared_ptr_helper<StorageMergeTree>, public IStorage class StorageMergeTree : private ext::shared_ptr_helper<StorageMergeTree>, public IStorage
{ {
@ -22,13 +22,13 @@ friend class ext::shared_ptr_helper<StorageMergeTree>;
friend class MergeTreeBlockOutputStream; friend class MergeTreeBlockOutputStream;
public: public:
/** Подцепить таблицу с соответствующим именем, по соответствующему пути (с / на конце), /** hook the table with the appropriate name, along the appropriate path (with / at the end),
* (корректность имён и путей не проверяется) * (correctness of names and paths are not checked)
* состоящую из указанных столбцов. * consisting of the specified columns.
* *
* primary_expr_ast - выражение для сортировки; * primary_expr_ast - expression for sorting;
* date_column_name - имя столбца с датой; * date_column_name - the name of the column with the date;
* index_granularity - на сколько строчек пишется одно значение индекса. * index_granularity - fow how many rows one index value is written.
*/ */
static StoragePtr create( static StoragePtr create(
const String & path_, const String & path_,
@ -42,7 +42,7 @@ public:
Context & context_, Context & context_,
ASTPtr & primary_expr_ast_, ASTPtr & primary_expr_ast_,
const String & date_column_name_, const String & date_column_name_,
const ASTPtr & sampling_expression_, /// nullptr, если семплирование не поддерживается. const ASTPtr & sampling_expression_, /// nullptr, if sampling is not supported.
size_t index_granularity_, size_t index_granularity_,
const MergeTreeData::MergingParams & merging_params_, const MergeTreeData::MergingParams & merging_params_,
bool has_force_restore_data_flag, bool has_force_restore_data_flag,
@ -85,7 +85,7 @@ public:
BlockOutputStreamPtr write(ASTPtr query, const Settings & settings) override; BlockOutputStreamPtr write(ASTPtr query, const Settings & settings) override;
/** Выполнить очередной шаг объединения кусков. /** Perform the next step in combining the parts.
*/ */
bool optimize(const String & partition, bool final, const Settings & settings) override bool optimize(const String & partition, bool final, const Settings & settings) override
{ {

View File

@ -11,8 +11,8 @@
namespace DB namespace DB
{ {
/** При записи, ничего не делает. /** When writing, does nothing.
* При чтении, возвращает пустоту. * When reading, returns nothing.
*/ */
class StorageNull : private ext::shared_ptr_helper<StorageNull>, public IStorage class StorageNull : private ext::shared_ptr_helper<StorageNull>, public IStorage
{ {

View File

@ -127,8 +127,8 @@ static const auto MERGE_SELECTING_SLEEP_MS = 5 * 1000;
* Why is this number 200? * Why is this number 200?
* The fact is that previously negative block numbers were not supported. * The fact is that previously negative block numbers were not supported.
* And also, the merge is done that way so that when you increase the number of parts, insertion of new parts slows down on purpose, * And also, the merge is done that way so that when you increase the number of parts, insertion of new parts slows down on purpose,
* until mergers have time to reduce the number of parts; and it was calculated for about 200 pieces. * until mergers have time to reduce the number of parts; and it was calculated for about 200 parts.
* So, when you insert all the parts from the other table into the table, 200 numbers are sure enough. * So, when you insert all the parts from the other table into the table, 200 is sure enough.
* In turn, this number is chosen almost at random. * In turn, this number is chosen almost at random.
*/ */
extern const Int64 RESERVED_BLOCK_NUMBERS = 200; extern const Int64 RESERVED_BLOCK_NUMBERS = 200;
@ -2803,7 +2803,7 @@ void StorageReplicatedMergeTree::dropPartition(
String fake_part_name = getFakePartNameForDrop(month_name, left, right); String fake_part_name = getFakePartNameForDrop(month_name, left, right);
/** Forbid to choose the parts to be deleted for merging. /** Forbid to choose the parts to be deleted for merging.
* Invariant: after the `DROP_RANGE` entry appears in the log, merge of deleted pieces will not appear in the log. * Invariant: after the `DROP_RANGE` entry appears in the log, merge of deleted parts will not appear in the log.
*/ */
{ {
std::lock_guard<std::mutex> merge_selecting_lock(merge_selecting_mutex); std::lock_guard<std::mutex> merge_selecting_lock(merge_selecting_mutex);

View File

@ -28,45 +28,45 @@
namespace DB namespace DB
{ {
/** Движок, использующий merge-дерево (см. MergeTreeData) и реплицируемый через ZooKeeper. /** The engine that uses the merge tree (see MergeTreeData) and replicated through ZooKeeper.
* *
* ZooKeeper используется для следующих вещей: * ZooKeeper is used for the following things:
* - структура таблицы (/metadata, /columns) * - the structure of the table (/ metadata, /columns)
* - лог действий с данными (/log/log-..., /replicas/replica_name/queue/queue-...); * - action log with data (/log/log-...,/replicas/replica_name/queue/queue-...);
* - список реплик (/replicas), признак активности реплики (/replicas/replica_name/is_active), адреса реплик (/replicas/replica_name/host); * - a replica list (/replicas), and replica activity tag (/replicas/replica_name/is_active), replica addresses (/replicas/replica_name/host);
* - выбор реплики-лидера (/leader_election) - это та реплика, которая назначает мерджи; * - select the leader replica (/leader_election) - this is the replica that assigns the merge;
* - набор кусков данных на каждой реплике (/replicas/replica_name/parts); * - a set of parts of data on each replica (/replicas/replica_name/parts);
* - список последних N блоков данных с чексуммами, для дедупликации (/blocks); * - list of the last N blocks of data with checksum, for deduplication (/blocks);
* - список инкрементальных номеров блоков (/block_numbers), которые мы сейчас собираемся вставить, * - the list of incremental block numbers (/block_numbers) that we are about to insert,
* или которые были неиспользованы (/nonincremental_block_numbers) * or that were unused (/nonincremental_block_numbers)
* для обеспечения линейного порядка вставки данных и мерджа данных только по интервалам в этой последовательности; * to ensure the linear order of data insertion and data merge only on the intervals in this sequence;
* - координация записей с кворумом (/quorum). * - coordinates writes with quorum (/quorum).
*/ */
/** У реплицируемых таблиц есть общий лог (/log/log-...). /** The replicated tables have a common log (/log/log-...).
* Лог - последовательность записей (LogEntry) о том, что делать. * Log - a sequence of entries (LogEntry) about what to do.
* Каждая запись - это одно из: * Each entry is one of:
* - обычная вставка данных (GET), * - normal data insertion (GET),
* - мердж (MERGE), * - merge (MERGE),
* - чуть менее обычная вставка данных (ATTACH), * - slightly less common data insertion (ATTACH),
* - удаление партиции (DROP). * - delete the partition (DROP).
* *
* Каждая реплика копирует (queueUpdatingThread, pullLogsToQueue) записи из лога в свою очередь (/replicas/replica_name/queue/queue-...), * Each replica copies (queueUpdatingThread, pullLogsToQueue) entries from the log to its queue (/replicas/replica_name/queue/queue-...)
* и затем выполняет их (queueTask). * and then executes them (queueTask).
* Не смотря на название "очередь", выполнение может переупорядочиваться, при необходимости (shouldExecuteLogEntry, executeLogEntry). * Despite the name of the "queue", execution can be reordered, if necessary (shouldExecuteLogEntry, executeLogEntry).
* Кроме того, записи в очереди могут генерироваться самостоятельно (не из лога), в следующих случаях: * In addition, the records in the queue can be generated independently (not from the log), in the following cases:
* - при создании новой реплики, туда помещаются действия на GET с других реплик (createReplica); * - when creating a new replica, actions are put on GET from other replicas (createReplica);
* - если кусок повреждён (removePartAndEnqueueFetch) или отсутствовал при проверке (при старте - checkParts, во время работы - searchForMissingPart), * - if the part is corrupt (removePartAndEnqueueFetch) or absent during the check (at start - checkParts, while running - searchForMissingPart),
* туда помещаются действия на GET с других реплик; * actions are put on GET from other replicas;
* *
* У реплики, на которую был сделан INSERT, в очереди тоже будет запись о GET этих данных. * The replica to which INSERT was made in the queue will also have an entry of the GET of this data.
* Такая запись считается выполненной, как только обработчик очереди её увидит. * Such an entry is considered to be executed as soon as the queue handler sees it.
* *
* У записи в логе есть время создания. Это время генерируется по часам на сервере, который создал запись * The log entry has a creation time. This time is generated by the clock of server that created entry
* - того, на которых пришёл соответствующий запрос INSERT или ALTER. * - the one on which the corresponding INSERT or ALTER query came.
* *
* Для записей в очереди, которые реплика сделала для себя самостоятельно, * For the entries in the queue that the replica made for itself,
* в качестве времени будет браться время создания соответствующего куска на какой-либо из реплик. * as the time will take the time of creation the appropriate part on any of the replicas.
*/ */
class StorageReplicatedMergeTree : private ext::shared_ptr_helper<StorageReplicatedMergeTree>, public IStorage class StorageReplicatedMergeTree : private ext::shared_ptr_helper<StorageReplicatedMergeTree>, public IStorage
@ -74,7 +74,7 @@ class StorageReplicatedMergeTree : private ext::shared_ptr_helper<StorageReplica
friend class ext::shared_ptr_helper<StorageReplicatedMergeTree>; friend class ext::shared_ptr_helper<StorageReplicatedMergeTree>;
public: public:
/** Если !attach, либо создает новую таблицу в ZK, либо добавляет реплику в существующую таблицу. /** If !attach, either creates a new table in ZK, or adds a replica to an existing table.
*/ */
static StoragePtr create( static StoragePtr create(
const String & zookeeper_path_, const String & zookeeper_path_,
@ -88,7 +88,7 @@ public:
Context & context_, Context & context_,
ASTPtr & primary_expr_ast_, ASTPtr & primary_expr_ast_,
const String & date_column_name_, const String & date_column_name_,
const ASTPtr & sampling_expression_, /// nullptr, если семплирование не поддерживается. const ASTPtr & sampling_expression_, /// nullptr, if sampling is not supported.
size_t index_granularity_, size_t index_granularity_,
const MergeTreeData::MergingParams & merging_params_, const MergeTreeData::MergingParams & merging_params_,
bool has_force_restore_data_flag, bool has_force_restore_data_flag,
@ -148,7 +148,7 @@ public:
const ASTPtr & sharding_key_expr, bool do_copy, const Field & coordinator, const ASTPtr & sharding_key_expr, bool do_copy, const Field & coordinator,
const Settings & settings) override; const Settings & settings) override;
/** Удаляет реплику из ZooKeeper. Если других реплик нет, удаляет всю таблицу из ZooKeeper. /** Removes a replica from ZooKeeper. If there are no other replicas, it deletes the entire table from ZooKeeper.
*/ */
void drop() override; void drop() override;
@ -163,7 +163,7 @@ public:
MergeTreeData * getUnreplicatedData() { return unreplicated_data.get(); } MergeTreeData * getUnreplicatedData() { return unreplicated_data.get(); }
/** Для системной таблицы replicas. */ /** For the system table replicas. */
struct Status struct Status
{ {
bool is_leader; bool is_leader;
@ -181,7 +181,7 @@ public:
UInt8 active_replicas; UInt8 active_replicas;
}; };
/// Получить статус таблицы. Если with_zk_fields = false - не заполнять поля, требующие запросов в ZK. /// Get the status of the table. If with_zk_fields = false - do not fill in the fields that require queries to ZK.
void getStatus(Status & res, bool with_zk_fields = true); void getStatus(Status & res, bool with_zk_fields = true);
using LogEntriesData = std::vector<ReplicatedMergeTreeLogEntryData>; using LogEntriesData = std::vector<ReplicatedMergeTreeLogEntryData>;
@ -189,7 +189,7 @@ public:
void getReplicaDelays(time_t & out_absolute_delay, time_t & out_relative_delay); void getReplicaDelays(time_t & out_absolute_delay, time_t & out_relative_delay);
/// Добавить кусок в очередь кусков, чьи данные нужно проверить в фоновом потоке. /// Add a part to the queue of parts whose data you want to check in the background thread.
void enqueuePartForCheck(const String & part_name, time_t delay_to_check_seconds = 0) void enqueuePartForCheck(const String & part_name, time_t delay_to_check_seconds = 0)
{ {
part_check_thread.enqueuePart(part_name, delay_to_check_seconds); part_check_thread.enqueuePart(part_name, delay_to_check_seconds);
@ -216,14 +216,14 @@ private:
Context & context; Context & context;
zkutil::ZooKeeperPtr current_zookeeper; /// Используйте только с помощью методов ниже. zkutil::ZooKeeperPtr current_zookeeper; /// Use only the methods below.
std::mutex current_zookeeper_mutex; /// Для пересоздания сессии в фоновом потоке. std::mutex current_zookeeper_mutex; /// To recreate the session in the background thread.
zkutil::ZooKeeperPtr tryGetZooKeeper(); zkutil::ZooKeeperPtr tryGetZooKeeper();
zkutil::ZooKeeperPtr getZooKeeper(); zkutil::ZooKeeperPtr getZooKeeper();
void setZooKeeper(zkutil::ZooKeeperPtr zookeeper); void setZooKeeper(zkutil::ZooKeeperPtr zookeeper);
/// Если true, таблица в офлайновом режиме, и в нее нельзя писать. /// If true, the table is offline and can not be written to it.
bool is_readonly = false; bool is_readonly = false;
String database_name; String database_name;
@ -234,8 +234,8 @@ private:
String replica_name; String replica_name;
String replica_path; String replica_path;
/** Очередь того, что нужно сделать на этой реплике, чтобы всех догнать. Берется из ZooKeeper (/replicas/me/queue/). /** The queue of what needs to be done on this replica to catch up with everyone. It is taken from ZooKeeper (/replicas/me/queue/).
* В ZK записи в хронологическом порядке. Здесь - не обязательно. * In ZK entries in chronological order. Here it is not necessary.
*/ */
ReplicatedMergeTreeQueue queue; ReplicatedMergeTreeQueue queue;
@ -243,12 +243,12 @@ private:
*/ */
zkutil::EphemeralNodeHolderPtr replica_is_active_node; zkutil::EphemeralNodeHolderPtr replica_is_active_node;
/** Версия ноды /columns в ZooKeeper, соответствующая текущим data.columns. /** Version node /columns in ZooKeeper corresponding to the current data.columns.
* Читать и изменять вместе с data.columns - под TableStructureLock. * Read and modify along with the data.columns - under TableStructureLock.
*/ */
int columns_version = -1; int columns_version = -1;
/** Является ли эта реплика "ведущей". Ведущая реплика выбирает куски для слияния. /** Is this replica "master". The master replica selects the parts to merge.
*/ */
bool is_leader_node = false; bool is_leader_node = false;
std::mutex leader_node_mutex; std::mutex leader_node_mutex;
@ -272,46 +272,46 @@ private:
zkutil::LeaderElectionPtr leader_election; zkutil::LeaderElectionPtr leader_election;
/// Для чтения данных из директории unreplicated. /// To read data from the `unreplicated` directory.
std::unique_ptr<MergeTreeData> unreplicated_data; std::unique_ptr<MergeTreeData> unreplicated_data;
std::unique_ptr<MergeTreeDataSelectExecutor> unreplicated_reader; std::unique_ptr<MergeTreeDataSelectExecutor> unreplicated_reader;
std::unique_ptr<MergeTreeDataMerger> unreplicated_merger; std::unique_ptr<MergeTreeDataMerger> unreplicated_merger;
std::mutex unreplicated_mutex; /// Для мерджей и удаления нереплицируемых кусков. std::mutex unreplicated_mutex; /// For merge and removal of non-replicable parts.
/// Нужно ли завершить фоновые потоки (кроме restarting_thread). /// Do I need to complete background threads (except restarting_thread)?
std::atomic<bool> shutdown_called {false}; std::atomic<bool> shutdown_called {false};
Poco::Event shutdown_event; Poco::Event shutdown_event;
/// Limiting parallel fetches per one table /// Limiting parallel fetches per one table
std::atomic_uint current_table_fetches {0}; std::atomic_uint current_table_fetches {0};
/// Потоки: /// Streams
/// Поток, следящий за обновлениями в логах всех реплик и загружающий их в очередь. /// A thread that keeps track of the updates in the logs of all replicas and loads them into the queue.
std::thread queue_updating_thread; std::thread queue_updating_thread;
zkutil::EventPtr queue_updating_event = std::make_shared<Poco::Event>(); zkutil::EventPtr queue_updating_event = std::make_shared<Poco::Event>();
/// Задание, выполняющее действия из очереди. /// A task that performs actions from the queue.
BackgroundProcessingPool::TaskHandle queue_task_handle; BackgroundProcessingPool::TaskHandle queue_task_handle;
/// Поток, выбирающий куски для слияния. /// A thread that selects parts to merge.
std::thread merge_selecting_thread; std::thread merge_selecting_thread;
Poco::Event merge_selecting_event; Poco::Event merge_selecting_event;
std::mutex merge_selecting_mutex; /// Берется на каждую итерацию выбора кусков для слияния. std::mutex merge_selecting_mutex; /// It is taken for each iteration of the selection of parts to merge.
/// Поток, удаляющий старые куски, записи в логе и блоки. /// A thread that removes old parts, log entries, and blocks.
std::unique_ptr<ReplicatedMergeTreeCleanupThread> cleanup_thread; std::unique_ptr<ReplicatedMergeTreeCleanupThread> cleanup_thread;
/// Поток, обрабатывающий переподключение к ZooKeeper при истечении сессии. /// A thread that processes reconnection to ZooKeeper when the session expires.
std::unique_ptr<ReplicatedMergeTreeRestartingThread> restarting_thread; std::unique_ptr<ReplicatedMergeTreeRestartingThread> restarting_thread;
/// Поток, следящий за изменениями списка столбцов в ZooKeeper и обновляющий куски в соответствии с этими изменениями. /// A thread monitoring changes to the column list in ZooKeeper and updating the parts in accordance with these changes.
std::unique_ptr<ReplicatedMergeTreeAlterThread> alter_thread; std::unique_ptr<ReplicatedMergeTreeAlterThread> alter_thread;
/// Поток, проверяющий данные кусков, а также очередь кусков для проверки. /// A thread that checks the data of the parts, as well as the queue of the parts to be checked.
ReplicatedMergeTreePartCheckThread part_check_thread; ReplicatedMergeTreePartCheckThread part_check_thread;
/// Событие, пробуждающее метод alter от ожидания завершения запроса ALTER. /// An event that awakens `alter` method from waiting for the completion of the ALTER query.
zkutil::EventPtr alter_query_event = std::make_shared<Poco::Event>(); zkutil::EventPtr alter_query_event = std::make_shared<Poco::Event>();
Logger * log; Logger * log;
@ -334,102 +334,102 @@ private:
bool has_force_restore_data_flag, bool has_force_restore_data_flag,
const MergeTreeSettings & settings_); const MergeTreeSettings & settings_);
/// Инициализация. /// Initialization.
/** Создает минимальный набор нод в ZooKeeper. /** Creates the minimum set of nodes in ZooKeeper.
*/ */
void createTableIfNotExists(); void createTableIfNotExists();
/** Создает реплику в ZooKeeper и добавляет в очередь все, что нужно, чтобы догнать остальные реплики. /** Creates a replica in ZooKeeper and adds to the queue all that it takes to catch up with the rest of the replicas.
*/ */
void createReplica(); void createReplica();
/** Создать узлы в ZK, которые должны быть всегда, но которые могли не существовать при работе старых версий сервера. /** Create nodes in the ZK, which must always be, but which might not exist when older versions of the server are running.
*/ */
void createNewZooKeeperNodes(); void createNewZooKeeperNodes();
/** Проверить, что список столбцов и настройки таблицы совпадают с указанными в ZK (/metadata). /** Verify that the list of columns and table settings match those specified in ZK (/metadata).
* Если нет - бросить исключение. * If not, throw an exception.
*/ */
void checkTableStructure(bool skip_sanity_checks, bool allow_alter); void checkTableStructure(bool skip_sanity_checks, bool allow_alter);
/** Проверить, что множество кусков соответствует тому, что в ZK (/replicas/me/parts/). /** Check that the set of parts corresponds to that in ZK (/replicas/me/parts/).
* Если каких-то кусков, описанных в ZK нет локально, бросить исключение. * If any parts described in ZK are not locally, throw an exception.
* Если какие-то локальные куски не упоминаются в ZK, удалить их. * If any local parts are not mentioned in ZK, remove them.
* Но если таких слишком много, на всякий случай бросить исключение - скорее всего, это ошибка конфигурации. * But if there are too many, throw an exception just in case - it's probably a configuration error.
*/ */
void checkParts(bool skip_sanity_checks); void checkParts(bool skip_sanity_checks);
/** Проверить, что чексумма куска совпадает с чексуммой того же куска на какой-нибудь другой реплике. /** Check that the part's checksum is the same as the checksum of the same part on some other replica.
* Если ни у кого нет такого куска, ничего не проверяет. * If no one has such a part, nothing checks.
* Не очень надежно: если две реплики добавляют кусок почти одновременно, ни одной проверки не произойдет. * Not very reliable: if two replicas add a part almost at the same time, no checks will occur.
* Кладет в ops действия, добавляющие данные о куске в ZooKeeper. * Adds actions to `ops` that add data about the part into ZooKeeper.
* Вызывать под TableStructureLock. * Call under TableStructureLock.
*/ */
void checkPartAndAddToZooKeeper(const MergeTreeData::DataPartPtr & part, zkutil::Ops & ops, String name_override = ""); void checkPartAndAddToZooKeeper(const MergeTreeData::DataPartPtr & part, zkutil::Ops & ops, String name_override = "");
/** Исходит из допущения, что такого куска ещё нигде нет (Это обеспечено, если номер куска выделен с помощью AbandonableLock). /** Based on the assumption that there is no such part anywhere else (This is provided if the part number is highlighted with AbandonableLock).
* Кладет в ops действия, добавляющие данные о куске в ZooKeeper. * Adds actions to `ops` that add data about the part into ZooKeeper.
* Вызывать под TableStructureLock. * Call under TableStructureLock.
*/ */
void addNewPartToZooKeeper(const MergeTreeData::DataPartPtr & part, zkutil::Ops & ops, String name_override = ""); void addNewPartToZooKeeper(const MergeTreeData::DataPartPtr & part, zkutil::Ops & ops, String name_override = "");
/// Кладет в ops действия, удаляющие кусок из ZooKeeper. /// Adds actions to `ops` that remove a part from ZooKeeper.
void removePartFromZooKeeper(const String & part_name, zkutil::Ops & ops); void removePartFromZooKeeper(const String & part_name, zkutil::Ops & ops);
/// Убирает кусок из ZooKeeper и добавляет в очередь задание скачать его. Предполагается это делать с битыми кусками. /// Removes a part from ZooKeeper and adds a task to the queue to download it. It is supposed to do this with broken parts.
void removePartAndEnqueueFetch(const String & part_name); void removePartAndEnqueueFetch(const String & part_name);
/// Выполнение заданий из очереди. /// Running jobs from the queue.
/** Копирует новые записи из логов всех реплик в очередь этой реплики. /** Copies the new entries from the logs of all replicas to the queue of this replica.
* Если next_update_event != nullptr, вызовет это событие, когда в логе появятся новые записи. * If next_update_event != nullptr, calls this event when new entries appear in the log.
*/ */
void pullLogsToQueue(zkutil::EventPtr next_update_event = nullptr); void pullLogsToQueue(zkutil::EventPtr next_update_event = nullptr);
/** Выполнить действие из очереди. Бросает исключение, если что-то не так. /** Execute the action from the queue. Throws an exception if something is wrong.
* Возвращает, получилось ли выполнить. Если не получилось, запись нужно положить в конец очереди. * Returns whether or not it succeeds. If it did not work, write it to the end of the queue.
*/ */
bool executeLogEntry(const LogEntry & entry); bool executeLogEntry(const LogEntry & entry);
void executeDropRange(const LogEntry & entry); void executeDropRange(const LogEntry & entry);
bool executeAttachPart(const LogEntry & entry); /// Возвращает false, если куска нет, и его нужно забрать с другой реплики. bool executeAttachPart(const LogEntry & entry); /// Returns false if the part is absent, and it needs to be picked up from another replica.
/** Обновляет очередь. /** Updates the queue.
*/ */
void queueUpdatingThread(); void queueUpdatingThread();
/** Выполняет действия из очереди. /** Performs actions from the queue.
*/ */
bool queueTask(); bool queueTask();
/// Выбор кусков для слияния. /// Select the parts to merge.
void becomeLeader(); void becomeLeader();
/** Выбирает куски для слияния и записывает в лог. /** Selects the parts to merge and writes to the log.
*/ */
void mergeSelectingThread(); void mergeSelectingThread();
using MemoizedPartsThatCouldBeMerged = std::set<std::pair<std::string, std::string>>; using MemoizedPartsThatCouldBeMerged = std::set<std::pair<std::string, std::string>>;
/// Можно ли мерджить куски в указанном диапазоне? memo - необязательный параметр. /// Is it possible to merge parts in the specified range? `memo` is an optional parameter.
bool canMergeParts( bool canMergeParts(
const MergeTreeData::DataPartPtr & left, const MergeTreeData::DataPartPtr & left,
const MergeTreeData::DataPartPtr & right, const MergeTreeData::DataPartPtr & right,
MemoizedPartsThatCouldBeMerged * memo); MemoizedPartsThatCouldBeMerged * memo);
/** Записать выбранные куски для слияния в лог, /** Write the selected parts to merge into the log,
* Вызывать при заблокированном merge_selecting_mutex. * Call when merge_selecting_mutex is locked.
* Возвращает false, если какого-то куска нет в ZK. * Returns false if any part is not in ZK.
*/ */
bool createLogEntryToMergeParts( bool createLogEntryToMergeParts(
const MergeTreeData::DataPartsVector & parts, const MergeTreeData::DataPartsVector & parts,
const String & merged_name, const String & merged_name,
ReplicatedMergeTreeLogEntryData * out_log_entry = nullptr); ReplicatedMergeTreeLogEntryData * out_log_entry = nullptr);
/// Обмен кусками. /// Exchange parts.
/** Возвращает пустую строку, если куска ни у кого нет. /** Returns an empty string if no one has a part.
*/ */
String findReplicaHavingPart(const String & part_name, bool active); String findReplicaHavingPart(const String & part_name, bool active);
@ -440,9 +440,9 @@ private:
*/ */
String findReplicaHavingCoveringPart(const String & part_name, bool active, String & out_covering_part_name); String findReplicaHavingCoveringPart(const String & part_name, bool active, String & out_covering_part_name);
/** Скачать указанный кусок с указанной реплики. /** Download the specified part from the specified replica.
* Если to_detached, то кусок помещается в директорию detached. * If `to_detached`, the part is placed in the `detached` directory.
* Если quorum != 0, то обновляется узел для отслеживания кворума. * If quorum != 0, then the node for tracking the quorum is updated.
* Returns false if part is already fetching right now. * Returns false if part is already fetching right now.
*/ */
bool fetchPart(const String & part_name, const String & replica_path, bool to_detached, size_t quorum); bool fetchPart(const String & part_name, const String & replica_path, bool to_detached, size_t quorum);
@ -450,42 +450,42 @@ private:
std::unordered_set<String> currently_fetching_parts; std::unordered_set<String> currently_fetching_parts;
std::mutex currently_fetching_parts_mutex; std::mutex currently_fetching_parts_mutex;
/** При отслеживаемом кворуме - добавить реплику в кворум для куска. /** With the quorum being tracked, add a replica to the quorum for the part.
*/ */
void updateQuorum(const String & part_name); void updateQuorum(const String & part_name);
AbandonableLockInZooKeeper allocateBlockNumber(const String & month_name); AbandonableLockInZooKeeper allocateBlockNumber(const String & month_name);
/** Дождаться, пока все реплики, включая эту, выполнят указанное действие из лога. /** Wait until all replicas, including this, execute the specified action from the log.
* Если одновременно с этим добавляются реплики, может не дождаться добавленную реплику. * If replicas are added at the same time, it can not wait the added replica .
*/ */
void waitForAllReplicasToProcessLogEntry(const ReplicatedMergeTreeLogEntryData & entry); void waitForAllReplicasToProcessLogEntry(const ReplicatedMergeTreeLogEntryData & entry);
/** Дождаться, пока указанная реплика выполнит указанное действие из лога. /** Wait until the specified replica executes the specified action from the log.
*/ */
void waitForReplicaToProcessLogEntry(const String & replica_name, const ReplicatedMergeTreeLogEntryData & entry); void waitForReplicaToProcessLogEntry(const String & replica_name, const ReplicatedMergeTreeLogEntryData & entry);
/// Кинуть исключение, если таблица readonly. /// Throw an exception if the table is readonly.
void assertNotReadonly() const; void assertNotReadonly() const;
/** Получить блокировку, которая защищает заданную партицию от задачи слияния. /** Get a lock that protects the specified partition from the merge task.
* Блокировка является рекурсивной. * The lock is recursive.
*/ */
std::string acquirePartitionMergeLock(const std::string & partition_name); std::string acquirePartitionMergeLock(const std::string & partition_name);
/** Заявить, что больше не ссылаемся на блокировку соответствующую заданной /** Declare that we no longer refer to the lock corresponding to the specified
* партиции. Если ссылок больше нет, блокировка уничтожается. * partition. If there are no more links, the lock is destroyed.
*/ */
void releasePartitionMergeLock(const std::string & partition_name); void releasePartitionMergeLock(const std::string & partition_name);
/// Проверить наличие узла в ZK. Если он есть - запомнить эту информацию, и затем сразу отвечать true. /// Check for a node in ZK. If it is, remember this information, and then immediately answer true.
std::unordered_set<std::string> existing_nodes_cache; std::unordered_set<std::string> existing_nodes_cache;
std::mutex existing_nodes_cache_mutex; std::mutex existing_nodes_cache_mutex;
bool existsNodeCached(const std::string & path); bool existsNodeCached(const std::string & path);
/// Перешардирование. /// Resharding.
struct ReplicaSpaceInfo struct ReplicaSpaceInfo
{ {
long double factor = 0.0; long double factor = 0.0;
@ -494,16 +494,16 @@ private:
using ReplicaToSpaceInfo = std::map<std::string, ReplicaSpaceInfo>; using ReplicaToSpaceInfo = std::map<std::string, ReplicaSpaceInfo>;
/** Проверяет, что структуры локальной и реплицируемых таблиц совпадают. /** Checks that the structures of the local and replicated tables are the same.
*/ */
void enforceShardsConsistency(const WeightedZooKeeperPaths & weighted_zookeeper_paths); void enforceShardsConsistency(const WeightedZooKeeperPaths & weighted_zookeeper_paths);
/** Получить информацию о свободном месте на репликах + дополнительную информацию /** Get information about free space on replicas + additional information
* для функции checkSpaceForResharding. * for the function checkSpaceForResharding.
*/ */
ReplicaToSpaceInfo gatherReplicaSpaceInfo(const WeightedZooKeeperPaths & weighted_zookeeper_paths); ReplicaToSpaceInfo gatherReplicaSpaceInfo(const WeightedZooKeeperPaths & weighted_zookeeper_paths);
/** Проверяет, что имеется достаточно свободного места локально и на всех репликах. /** Checks that there is enough free space locally and on all replicas.
*/ */
bool checkSpaceForResharding(const ReplicaToSpaceInfo & replica_to_space_info, size_t partition_size) const; bool checkSpaceForResharding(const ReplicaToSpaceInfo & replica_to_space_info, size_t partition_size) const;
}; };

View File

@ -12,7 +12,7 @@ class Set;
using SetPtr = std::shared_ptr<Set>; using SetPtr = std::shared_ptr<Set>;
/** Общая часть StorageSet и StorageJoin. /** Common part of StorageSet and StorageJoin.
*/ */
class StorageSetOrJoinBase : private ext::shared_ptr_helper<StorageSetOrJoinBase>, public IStorage class StorageSetOrJoinBase : private ext::shared_ptr_helper<StorageSetOrJoinBase>, public IStorage
{ {
@ -40,24 +40,24 @@ protected:
String name; String name;
NamesAndTypesListPtr columns; NamesAndTypesListPtr columns;
UInt64 increment = 0; /// Для имён файлов бэкапа. UInt64 increment = 0; /// For the backup file names.
/// Восстановление из бэкапа. /// Restore from backup.
void restore(); void restore();
private: private:
void restoreFromFile(const String & file_path); void restoreFromFile(const String & file_path);
/// Вставить блок в состояние. /// Insert the block into the state.
virtual void insertBlock(const Block & block) = 0; virtual void insertBlock(const Block & block) = 0;
virtual size_t getSize() const = 0; virtual size_t getSize() const = 0;
}; };
/** Позволяет сохранить множество для последующего использования в правой части оператора IN. /** Lets you save the set for later use on the right side of the IN statement.
* При вставке в таблицу, данные будут вставлены в множество, * When inserted into a table, the data will be inserted into the set,
* а также записаны в файл-бэкап, для восстановления после перезапуска. * and also written to a file-backup, for recovery after a restart.
* Чтение из таблицы напрямую невозможно - возможно лишь указание в правой части оператора IN. * Reading from the table is not possible directly - it is possible to specify only the right part of the IN statement.
*/ */
class StorageSet : private ext::shared_ptr_helper<StorageSet>, public StorageSetOrJoinBase class StorageSet : private ext::shared_ptr_helper<StorageSet>, public StorageSetOrJoinBase
{ {
@ -77,7 +77,7 @@ public:
String getName() const override { return "Set"; } String getName() const override { return "Set"; }
/// Получить доступ к внутренностям. /// Access the insides.
SetPtr & getSet() { return set; } SetPtr & getSet() { return set; }
private: private:

View File

@ -14,8 +14,8 @@
namespace DB namespace DB
{ {
/** Реализует хранилище, подходящее для маленьких кусочков лога. /** Implements a repository that is suitable for small pieces of the log.
* При этом, хранит все столбцы в одном файле формата Native, с расположенным рядом индексом. * In doing so, stores all the columns in a single Native file, with a nearby index.
*/ */
class StorageStripeLog : private ext::shared_ptr_helper<StorageStripeLog>, public IStorage class StorageStripeLog : private ext::shared_ptr_helper<StorageStripeLog>, public IStorage
{ {
@ -24,10 +24,10 @@ friend class StripeLogBlockInputStream;
friend class StripeLogBlockOutputStream; friend class StripeLogBlockOutputStream;
public: public:
/** Подцепить таблицу с соответствующим именем, по соответствующему пути (с / на конце), /** hook the table with the appropriate name, along the appropriate path (with / at the end),
* (корректность имён и путей не проверяется) * (the correctness of names and paths is not checked)
* состоящую из указанных столбцов. * consisting of the specified columns.
* Если не указано attach - создать директорию, если её нет. * If not specified `attach` - create a directory if it does not exist.
*/ */
static StoragePtr create( static StoragePtr create(
const std::string & path_, const std::string & path_,
@ -59,7 +59,7 @@ public:
bool checkData() const override; bool checkData() const override;
/// Данные файла. /// Data of the file.
struct ColumnData struct ColumnData
{ {
Poco::File data_file; Poco::File data_file;

View File

@ -14,8 +14,8 @@
namespace DB namespace DB
{ {
/** Реализует хранилище, подходящее для маленьких кусочков лога. /** Implements a repository that is suitable for small pieces of the log.
* Отличается от StorageLog отсутствием файлов с засечками. * It differs from StorageLog in the absence of mark files.
*/ */
class StorageTinyLog : private ext::shared_ptr_helper<StorageTinyLog>, public IStorage class StorageTinyLog : private ext::shared_ptr_helper<StorageTinyLog>, public IStorage
{ {
@ -24,10 +24,10 @@ friend class TinyLogBlockInputStream;
friend class TinyLogBlockOutputStream; friend class TinyLogBlockOutputStream;
public: public:
/** Подцепить таблицу с соответствующим именем, по соответствующему пути (с / на конце), /** hook the table with the appropriate name, along the appropriate path (with / at the end),
* (корректность имён и путей не проверяется) * (the correctness of names and paths is not verified)
* состоящую из указанных столбцов. * consisting of the specified columns.
* Если не указано attach - создать директорию, если её нет. * If not specified `attach` - create a directory if it does not exist.
*/ */
static StoragePtr create( static StoragePtr create(
const std::string & path_, const std::string & path_,
@ -61,7 +61,7 @@ public:
bool checkData() const override; bool checkData() const override;
/// Данные столбца /// Column data
struct ColumnData struct ColumnData
{ {
Poco::File data_file; Poco::File data_file;

View File

@ -29,7 +29,7 @@ public:
const NamesAndTypesList & getColumnsListImpl() const override { return *columns; } const NamesAndTypesList & getColumnsListImpl() const override { return *columns; }
ASTPtr getInnerQuery() const { return inner_query.clone(); }; ASTPtr getInnerQuery() const { return inner_query.clone(); };
/// Пробрасывается внутрь запроса и решается на его уровне. /// It is passed inside the query and solved at its level.
bool supportsSampling() const override { return true; } bool supportsSampling() const override { return true; }
bool supportsFinal() const override { return true; } bool supportsFinal() const override { return true; }
@ -66,7 +66,7 @@ protected:
const ColumnDefaults & column_defaults_); const ColumnDefaults & column_defaults_);
private: private:
/// Достать из самого внутреннего подзапроса имя базы данных и таблицы: select_database_name, select_table_name. /// extract the name of the database and the table from the most internal subquery: `select_database_name, select_table_name`.
void extractDependentTable(const ASTSelectQuery & query); void extractDependentTable(const ASTSelectQuery & query);
}; };

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу databases, которая позволяет получить информацию о всех БД. /** Implements `databases` system table, which allows you to get information about all databases.
*/ */
class StorageSystemDatabases : private ext::shared_ptr_helper<StorageSystemDatabases>, public IStorage class StorageSystemDatabases : private ext::shared_ptr_helper<StorageSystemDatabases>, public IStorage
{ {

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу events, которая позволяет получить информацию для профайлинга. /** Implements `events` system table, which allows you to obtain information for profiling.
*/ */
class StorageSystemEvents : private ext::shared_ptr_helper<StorageSystemEvents>, public IStorage class StorageSystemEvents : private ext::shared_ptr_helper<StorageSystemEvents>, public IStorage
{ {

View File

@ -10,8 +10,8 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу functions, которая позволяет получить список /** Implements `functions`system table, which allows you to get a list
* всех обычных и агрегатных функций. * all normal and aggregate functions.
*/ */
class StorageSystemFunctions : private ext::shared_ptr_helper<StorageSystemFunctions>, public IStorage class StorageSystemFunctions : private ext::shared_ptr_helper<StorageSystemFunctions>, public IStorage
{ {

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу metrics, которая позволяет получить информацию о работе сервера. /** Implements `metrics` system table, which provides information about the operation of the server.
*/ */
class StorageSystemMetrics : private ext::shared_ptr_helper<StorageSystemMetrics>, public IStorage class StorageSystemMetrics : private ext::shared_ptr_helper<StorageSystemMetrics>, public IStorage
{ {

View File

@ -10,9 +10,9 @@ namespace DB
class Context; class Context;
/** Реализует хранилище для системной таблицы Numbers. /** Implements a repository for the system table Numbers.
* Таблица содержит единственный столбец number UInt64. * The table contains the only column number UInt64.
* Из этой таблицы можно прочитать все натуральные числа, начиная с 0 (до 2^64 - 1, а потом заново). * From this table, you can read all natural numbers, starting from 0 (to 2^64 - 1, and then again).
*/ */
class StorageSystemNumbers : private ext::shared_ptr_helper<StorageSystemNumbers>, public IStorage class StorageSystemNumbers : private ext::shared_ptr_helper<StorageSystemNumbers>, public IStorage
{ {

View File

@ -10,10 +10,10 @@ namespace DB
class Context; class Context;
/** Реализует хранилище для системной таблицы One. /** Implements storage for the system table One.
* Таблица содержит единственный столбец dummy UInt8 и единственную строку со значением 0. * The table contains a single column of dummy UInt8 and a single row with a value of 0.
* Используется, если в запросе не указана таблица. * Used when the table is not specified in the query.
* Аналог таблицы DUAL в Oracle и MySQL. * Analog of the DUAL table in Oracle and MySQL.
*/ */
class StorageSystemOne : private ext::shared_ptr_helper<StorageSystemOne>, public IStorage class StorageSystemOne : private ext::shared_ptr_helper<StorageSystemOne>, public IStorage
{ {

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу processes, которая позволяет получить информацию о запросах, исполняющихся в данный момент. /** Implements `processes` system table, which allows you to get information about the queries that are currently executing.
*/ */
class StorageSystemProcesses : private ext::shared_ptr_helper<StorageSystemProcesses>, public IStorage class StorageSystemProcesses : private ext::shared_ptr_helper<StorageSystemProcesses>, public IStorage
{ {

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу replicas, которая позволяет получить информацию о статусе реплицируемых таблиц. /** Implements `replicas` system table, which provides information about the status of the replicated tables.
*/ */
class StorageSystemReplicas : private ext::shared_ptr_helper<StorageSystemReplicas>, public IStorage class StorageSystemReplicas : private ext::shared_ptr_helper<StorageSystemReplicas>, public IStorage
{ {

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу replication_queue, которая позволяет посмотреть очереди репликации для реплицируемых таблиц. /** Implements the `replication_queue` system table, which allows you to view the replication queues for the replicated tables.
*/ */
class StorageSystemReplicationQueue : private ext::shared_ptr_helper<StorageSystemReplicationQueue>, public IStorage class StorageSystemReplicationQueue : private ext::shared_ptr_helper<StorageSystemReplicationQueue>, public IStorage
{ {

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу tables, которая позволяет получить информацию о всех таблицах. /** Implements the system table `tables`, which allows you to get information about all tables.
*/ */
class StorageSystemTables : private ext::shared_ptr_helper<StorageSystemTables>, public IStorage class StorageSystemTables : private ext::shared_ptr_helper<StorageSystemTables>, public IStorage
{ {

View File

@ -10,7 +10,7 @@ namespace DB
class Context; class Context;
/** Реализует системную таблицу zookeeper, которая позволяет просматривать данные в ZooKeeper в целях отладки. /** Implements `zookeeper` system table, which allows you to view the data in ZooKeeper for debugging purposes.
*/ */
class StorageSystemZooKeeper : private ext::shared_ptr_helper<StorageSystemZooKeeper>, public IStorage class StorageSystemZooKeeper : private ext::shared_ptr_helper<StorageSystemZooKeeper>, public IStorage
{ {

View File

@ -5,8 +5,8 @@
namespace DB namespace DB
{ {
/** Знает имена и типы всех возможных виртуальных столбцов. /** Knows the names and types of all possible virtual columns.
* Нужно для движков, перенаправляющих запрос в другие таблицы, не зная заранее, какие в них есть виртуальные столбцы. * It is necessary for engines that redirect a request to other tables without knowing in advance what virtual columns they contain.
*/ */
class VirtualColumnFactory class VirtualColumnFactory
{ {

View File

@ -14,24 +14,24 @@ class IStorage;
using StoragePtr = std::shared_ptr<IStorage>; using StoragePtr = std::shared_ptr<IStorage>;
/** Интерфейс для табличных функций. /** Interface for table functions.
* *
* Табличные функции не имеют отношения к другим функциям. * Table functions are not relevant to other functions.
* Табличная функция может быть указана в секции FROM вместо [db.]table * The table function can be specified in the FROM section instead of the [db.]Table
* Табличная функция возвращает временный объект StoragePtr, который используется для выполнения запроса. * The table function returns a temporary StoragePtr object that is used to execute the query.
* *
* Пример: * Example:
* SELECT count() FROM remote('example01-01-1', merge, hits) * SELECT count() FROM remote('example01-01-1', merge, hits)
* - пойти на example01-01-1, в БД merge, таблицу hits. * - go to `example01-01-1`, in `merge` database, `hits` table.
*/ */
class ITableFunction class ITableFunction
{ {
public: public:
/// Получить основное имя функции. /// Get the main function name.
virtual std::string getName() const = 0; virtual std::string getName() const = 0;
/// Создать storage в соответствии с запросом /// Create storage according to the query
virtual StoragePtr execute(ASTPtr ast_function, Context & context) const = 0; virtual StoragePtr execute(ASTPtr ast_function, Context & context) const = 0;
virtual ~ITableFunction() {}; virtual ~ITableFunction() {};

View File

@ -6,7 +6,7 @@
namespace DB namespace DB
{ {
/** Позволяет получить табличную функцию по ее имени. /** Lets you get a table function by its name.
*/ */
class TableFunctionFactory class TableFunctionFactory
{ {

View File

@ -7,9 +7,9 @@ namespace DB
{ {
/* /*
* merge(db_name, tables_regexp)- создаёт временный StorageMerge. * merge (db_name, tables_regexp) - creates a temporary StorageMerge.
* руктура таблицы берётся из первой попавшейся таблицы, подходящей под регексп. * The structure of the table is taken from the first table that came up, suitable for regexp.
* Если такой таблицы нет - кидается исключение. * If there is no such table, an exception is thrown.
*/ */
class TableFunctionMerge: public ITableFunction class TableFunctionMerge: public ITableFunction
{ {

View File

@ -7,11 +7,11 @@ namespace DB
{ {
/* /*
* remote('address', db, table) - создаёт временный StorageDistributed. * remote ('address', db, table) - creates a temporary StorageDistributed.
* Чтобы получить структуру таблицы, делается запрос DESC TABLE на удалённый сервер. * To get the table structure, a DESC TABLE request is made to the remote server.
* Например: * For example
* SELECT count() FROM remote('example01-01-1', merge, hits) - пойти на example01-01-1, в БД merge, таблицу hits. * SELECT count() FROM remote('example01-01-1', merge, hits) - go to `example01-01-1`, in the merge database, the hits table.
* В качестве имени хоста может быть указано также выражение, генерирующее множество шардов и реплик - см. ниже. * An expression that generates a lot of shards and replicas can also be specified as the host name - see below.
*/ */
class TableFunctionRemote : public ITableFunction class TableFunctionRemote : public ITableFunction
{ {

View File

@ -6,10 +6,10 @@
namespace DB namespace DB
{ {
/* shardByHash(cluster, 'key', db, table) - создаёт временный StorageDistributed, /* shardByHash(cluster, 'key', db, table) - creates a temporary StorageDistributed,
* используя кластер cluster, и выбирая из него только один шард путём хэширования строки key. * using the cluster `cluster`, and selecting from it only one shard by hashing the string key.
* *
* Аналогично функции remote, чтобы получить структуру таблицы, делается запрос DESC TABLE на удалённый сервер. * Similarly to the `remote` function, to get the table structure, a DESC TABLE request is made to the remote server.
*/ */
class TableFunctionShardByHash : public ITableFunction class TableFunctionShardByHash : public ITableFunction
{ {

View File

@ -9,8 +9,8 @@ namespace DB
class Cluster; class Cluster;
class Context; class Context;
/// Узнать имена и типы столбцов таблицы на первом попавшемся сервере кластера. /// Find the names and types of the table columns on any server in the cluster.
/// Используется для реализации табличной функции remote и других. /// Used to implement the `remote` table function and others.
NamesAndTypesList getStructureOfRemoteTable( NamesAndTypesList getStructureOfRemoteTable(
const Cluster & cluster, const Cluster & cluster,
const std::string & database, const std::string & database,