diff --git a/dbms/include/DB/Storages/MergeTree/MergeTreeDataMerger.h b/dbms/include/DB/Storages/MergeTree/MergeTreeDataMerger.h index b8319fad14d..0c6faa85a98 100644 --- a/dbms/include/DB/Storages/MergeTree/MergeTreeDataMerger.h +++ b/dbms/include/DB/Storages/MergeTree/MergeTreeDataMerger.h @@ -48,11 +48,19 @@ public: /** Сливает куски. * Если reservation != nullptr, то и дело уменьшает размер зарезервированного места * приблизительно пропорционально количеству уже выписанных данных. + * + * Создаёт и возвращает временный кусок. + * Чтобы закончить мердж, вызовите функцию renameTemporaryMergedPart. */ - MergeTreeData::DataPartPtr mergeParts( + MergeTreeData::MutableDataPartPtr mergePartsToTemporaryPart( MergeTreeData::DataPartsVector & parts, const String & merged_name, MergeListEntry & merge_entry, - size_t aio_threshold, MergeTreeData::Transaction * out_transaction = nullptr, - DiskSpaceMonitor::Reservation * disk_reservation = nullptr); + size_t aio_threshold, DiskSpaceMonitor::Reservation * disk_reservation = nullptr); + + MergeTreeData::DataPartPtr renameMergedTemporaryPart( + MergeTreeData::DataPartsVector & parts, + MergeTreeData::MutableDataPartPtr & new_data_part, + const String & merged_name, + MergeTreeData::Transaction * out_transaction = nullptr); /** Перешардирует заданную партицию. */ diff --git a/dbms/include/DB/Storages/MergeTree/MergeTreePartChecker.h b/dbms/include/DB/Storages/MergeTree/MergeTreePartChecker.h index 34b23c5bd29..291a1d2f355 100644 --- a/dbms/include/DB/Storages/MergeTree/MergeTreePartChecker.h +++ b/dbms/include/DB/Storages/MergeTree/MergeTreePartChecker.h @@ -32,7 +32,8 @@ public: String path, const Settings & settings, const DataTypes & primary_key_data_types, /// Проверять первичный ключ. Если не надо - передайте пустой массив. - MergeTreeData::DataPart::Checksums * out_checksums = nullptr); + MergeTreeData::DataPart::Checksums * out_checksums = nullptr, + volatile bool * is_cancelled = nullptr); }; } diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp index a4ba04f6f08..2110bbab3fe 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp @@ -313,6 +313,7 @@ bool MergeTreeDataMerger::selectPartsToMerge(MergeTreeData::DataPartsVector & pa return found; } + MergeTreeData::DataPartsVector MergeTreeDataMerger::selectAllPartsFromPartition(DayNum_t partition) { MergeTreeData::DataPartsVector parts_from_partition; @@ -332,11 +333,11 @@ MergeTreeData::DataPartsVector MergeTreeDataMerger::selectAllPartsFromPartition( return parts_from_partition; } + /// parts должны быть отсортированы. -MergeTreeData::DataPartPtr MergeTreeDataMerger::mergeParts( +MergeTreeData::MutableDataPartPtr MergeTreeDataMerger::mergePartsToTemporaryPart( MergeTreeData::DataPartsVector & parts, const String & merged_name, MergeList::Entry & merge_entry, - size_t aio_threshold, MergeTreeData::Transaction * out_transaction, - DiskSpaceMonitor::Reservation * disk_reservation) + size_t aio_threshold, DiskSpaceMonitor::Reservation * disk_reservation) { merge_entry->num_parts = parts.size(); @@ -486,6 +487,16 @@ MergeTreeData::DataPartPtr MergeTreeDataMerger::mergeParts( new_data_part->size_in_bytes = MergeTreeData::DataPart::calcTotalSize(new_part_tmp_path); new_data_part->is_sharded = false; + return new_data_part; +} + + +MergeTreeData::DataPartPtr MergeTreeDataMerger::renameMergedTemporaryPart( + MergeTreeData::DataPartsVector & parts, + MergeTreeData::MutableDataPartPtr & new_data_part, + const String & merged_name, + MergeTreeData::Transaction * out_transaction) +{ /// Переименовываем новый кусок, добавляем в набор и убираем исходные куски. auto replaced_parts = data.renameTempPartAndReplace(new_data_part, nullptr, out_transaction); @@ -522,10 +533,10 @@ MergeTreeData::DataPartPtr MergeTreeDataMerger::mergeParts( } LOG_TRACE(log, "Merged " << parts.size() << " parts: from " << parts.front()->name << " to " << parts.back()->name); - return new_data_part; } + MergeTreeData::PerShardDataParts MergeTreeDataMerger::reshardPartition( const ReshardingJob & job, DiskSpaceMonitor::Reservation * disk_reservation) { diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp index 46c24709b25..a1ac984f912 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp @@ -41,9 +41,9 @@ void MergeTreeDataPartChecksum::checkEqual(const MergeTreeDataPartChecksum & rhs if (!rhs.is_compressed) throw Exception("No uncompressed checksum for file " + name, ErrorCodes::CHECKSUM_DOESNT_MATCH); if (rhs.uncompressed_size != uncompressed_size) - throw Exception("Unexpected size of file " + name + " in data part", ErrorCodes::BAD_SIZE_OF_FILE_IN_DATA_PART); + throw Exception("Unexpected uncompressed size of file " + name + " in data part", ErrorCodes::BAD_SIZE_OF_FILE_IN_DATA_PART); if (rhs.uncompressed_hash != uncompressed_hash) - throw Exception("Checksum mismatch for file " + name + " in data part", ErrorCodes::CHECKSUM_DOESNT_MATCH); + throw Exception("Checksum mismatch for uncompressed file " + name + " in data part", ErrorCodes::CHECKSUM_DOESNT_MATCH); return; } if (rhs.file_size != file_size) diff --git a/dbms/src/Storages/MergeTree/MergeTreePartChecker.cpp b/dbms/src/Storages/MergeTree/MergeTreePartChecker.cpp index 95156eb9f97..32bf5ffddac 100644 --- a/dbms/src/Storages/MergeTree/MergeTreePartChecker.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreePartChecker.cpp @@ -27,11 +27,15 @@ namespace ErrorCodes } +namespace +{ + struct Stream { static const size_t UNKNOWN = std::numeric_limits::max(); - DataTypePtr type; + bool data_type_is_string = false; + size_t data_type_fixed_length = 0; String path; String name; @@ -43,9 +47,36 @@ struct Stream ReadBufferFromFile mrk_file_buf; HashingReadBuffer mrk_hashing_buf; - Stream(const String & path_, const String & name_, DataTypePtr type_) : type(type_), path(path_), name(name_), + Stream(const String & path_, const String & name_, DataTypePtr type) : path(path_), name(name_), file_buf(path + name + ".bin"), compressed_hashing_buf(file_buf), uncompressing_buf(compressed_hashing_buf), - uncompressed_hashing_buf(uncompressing_buf), mrk_file_buf(path + name + ".mrk"), mrk_hashing_buf(mrk_file_buf) {} + uncompressed_hashing_buf(uncompressing_buf), mrk_file_buf(path + name + ".mrk"), mrk_hashing_buf(mrk_file_buf) + { + data_type_is_string = typeid_cast(type.get()); + + if (!data_type_is_string) + { + if (typeid_cast(type.get()) + || typeid_cast(type.get())) + data_type_fixed_length = sizeof(UInt8); + else if (typeid_cast(type.get()) + || typeid_cast(type.get()) + || typeid_cast(type.get())) + data_type_fixed_length = sizeof(UInt16); + else if (typeid_cast(type.get()) + || typeid_cast(type.get()) + || typeid_cast(type.get()) + || typeid_cast(type.get())) + data_type_fixed_length = sizeof(UInt32); + else if (typeid_cast(type.get()) + || typeid_cast(type.get()) + || typeid_cast(type.get())) + data_type_fixed_length = sizeof(UInt64); + else if (auto string = typeid_cast(type.get())) + data_type_fixed_length = string->getN(); + else + throw Exception("Unexpected data type: " + type->getName() + " of column " + name, ErrorCodes::UNKNOWN_TYPE); + } + } bool marksEOF() { @@ -60,7 +91,7 @@ struct Stream size_t read(size_t rows) { - if (typeid_cast(type.get())) + if (data_type_is_string) { for (size_t i = 0; i < rows; ++i) { @@ -79,33 +110,11 @@ struct Stream } else { - size_t length; - if( typeid_cast(type.get()) || - typeid_cast(type.get())) - length = sizeof(UInt8); - else if(typeid_cast(type.get()) || - typeid_cast(type.get()) || - typeid_cast(type.get())) - length = sizeof(UInt16); - else if(typeid_cast(type.get()) || - typeid_cast(type.get()) || - typeid_cast(type.get()) || - typeid_cast(type.get())) - length = sizeof(UInt32); - else if(typeid_cast(type.get()) || - typeid_cast(type.get()) || - typeid_cast(type.get())) - length = sizeof(UInt64); - else if (auto string = typeid_cast(type.get())) - length = string->getN(); - else - throw Exception("Unexpected data type: " + type->getName() + " of column " + name, ErrorCodes::UNKNOWN_TYPE); - - size_t size = uncompressed_hashing_buf.tryIgnore(length * rows); - if (size % length) - throw Exception("Read " + toString(size) + " bytes, which is not divisible by " + toString(length), + size_t size = uncompressed_hashing_buf.tryIgnore(data_type_fixed_length * rows); + if (size % data_type_fixed_length) + throw Exception("Read " + toString(size) + " bytes, which is not divisible by " + toString(data_type_fixed_length), ErrorCodes::CORRUPTED_DATA); - return size / length; + return size / data_type_fixed_length; } } @@ -175,8 +184,13 @@ struct Stream }; /// Возвращает количество строк. Добавляет в checksums чексуммы всех файлов столбца. -static size_t checkColumn(const String & path, const String & name, DataTypePtr type, const MergeTreePartChecker::Settings & settings, - MergeTreeData::DataPart::Checksums & checksums) +static size_t checkColumn( + const String & path, + const String & name, + DataTypePtr type, + const MergeTreePartChecker::Settings & settings, + MergeTreeData::DataPart::Checksums & checksums, + volatile bool * is_cancelled) { size_t rows = 0; @@ -191,6 +205,9 @@ static size_t checkColumn(const String & path, const String & name, DataTypePtr ColumnUInt64::Container_t sizes; while (true) { + if (is_cancelled && *is_cancelled) + return 0; + if (sizes_stream.marksEOF()) break; @@ -233,6 +250,9 @@ static size_t checkColumn(const String & path, const String & name, DataTypePtr size_t rows = 0; while (true) { + if (is_cancelled && *is_cancelled) + return 0; + if (data_stream.marksEOF()) break; @@ -260,11 +280,15 @@ static size_t checkColumn(const String & path, const String & name, DataTypePtr } } +} + + void MergeTreePartChecker::checkDataPart( String path, const Settings & settings, const DataTypes & primary_key_data_types, - MergeTreeData::DataPart::Checksums * out_checksums) + MergeTreeData::DataPart::Checksums * out_checksums, + volatile bool * is_cancelled) { CurrentMetrics::Increment metric_increment{CurrentMetrics::ReplicatedChecks}; @@ -307,6 +331,9 @@ void MergeTreePartChecker::checkDataPart( while (!hashing_buf.eof()) { + if (is_cancelled && *is_cancelled) + return; + ++marks_in_primary_key; for (size_t j = 0; j < key_size; ++j) primary_key_data_types[j].get()->deserializeBinary(*tmp_columns[j].get(), hashing_buf); @@ -322,6 +349,9 @@ void MergeTreePartChecker::checkDataPart( checksums_data.files["primary.idx"] = MergeTreeData::DataPart::Checksums::Checksum(primary_idx_size, hashing_buf.getHash()); } + if (is_cancelled && *is_cancelled) + return; + String any_column_name; size_t rows = Stream::UNKNOWN; std::exception_ptr first_exception; @@ -344,7 +374,11 @@ void MergeTreePartChecker::checkDataPart( continue; } - size_t cur_rows = checkColumn(path, column.name, column.type, settings, checksums_data); + size_t cur_rows = checkColumn(path, column.name, column.type, settings, checksums_data, is_cancelled); + + if (is_cancelled && *is_cancelled) + return; + if (cur_rows != Stream::UNKNOWN) { if (rows == Stream::UNKNOWN) diff --git a/dbms/src/Storages/StorageMergeTree.cpp b/dbms/src/Storages/StorageMergeTree.cpp index 8e4b7a81fc0..19a3a69c2d8 100644 --- a/dbms/src/Storages/StorageMergeTree.cpp +++ b/dbms/src/Storages/StorageMergeTree.cpp @@ -257,7 +257,11 @@ bool StorageMergeTree::merge(size_t aio_threshold, bool aggressive, BackgroundPr } const auto & merge_entry = context.getMergeList().insert(database_name, table_name, merged_name); - merger.mergeParts(merging_tagger->parts, merged_name, *merge_entry, aio_threshold, nullptr, &*merging_tagger->reserved_space); + + auto new_part = merger.mergePartsToTemporaryPart( + merging_tagger->parts, merged_name, *merge_entry, aio_threshold, &*merging_tagger->reserved_space); + + merger.renameMergedTemporaryPart(merging_tagger->parts, new_part, merged_name, nullptr); return true; } diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 5642bc341d7..3510f448397 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -83,6 +83,8 @@ namespace ErrorCodes extern const int RESHARDING_INVALID_QUERY; extern const int RWLOCK_NO_SUCH_LOCK; extern const int NO_SUCH_BARRIER; + extern const int CHECKSUM_DOESNT_MATCH; + extern const int BAD_SIZE_OF_FILE_IN_DATA_PART; } @@ -817,7 +819,8 @@ void StorageReplicatedMergeTree::checkParts(bool skip_sanity_checks) } -void StorageReplicatedMergeTree::checkPartAndAddToZooKeeper(const MergeTreeData::DataPartPtr & part, zkutil::Ops & ops, String part_name) +void StorageReplicatedMergeTree::checkPartAndAddToZooKeeper( + const MergeTreeData::DataPartPtr & part, zkutil::Ops & ops, String part_name) { auto zookeeper = getZooKeeper(); @@ -1036,28 +1039,55 @@ bool StorageReplicatedMergeTree::executeLogEntry(const LogEntry & entry, Backgro MergeTreeData::Transaction transaction; size_t aio_threshold = context.getSettings().min_bytes_to_use_direct_io; - MergeTreeData::DataPartPtr part = merger.mergeParts( - parts, entry.new_part_name, *merge_entry, aio_threshold, &transaction, reserved_space); + auto part = merger.mergePartsToTemporaryPart( + parts, entry.new_part_name, *merge_entry, aio_threshold, reserved_space); zkutil::Ops ops; - checkPartAndAddToZooKeeper(part, ops); - /** TODO: Переименование нового куска лучше делать здесь, а не пятью строчками выше, - * чтобы оно было как можно ближе к zookeeper->multi. - */ + try + { + /// Здесь проверяются чексуммы и заполняется ops. Реально кусок добавляется в ZK чуть ниже, при выполнении multi. + checkPartAndAddToZooKeeper(part, ops, entry.new_part_name); + } + catch (const Exception & e) + { + if (e.code() == ErrorCodes::CHECKSUM_DOESNT_MATCH + || e.code() == ErrorCodes::BAD_SIZE_OF_FILE_IN_DATA_PART) + { + do_fetch = true; + part->remove(); - zookeeper->multi(ops); + LOG_ERROR(log, getCurrentExceptionMessage(false) << ". " + "Data after merge is not byte-identical to data on another replicas. " + "There could be several reasons: " + "1. Using newer version of compression library after server update. " + "2. Using another compression method. " + "3. Non-deterministic compression algorithm (highly unlikely). " + "4. Non-deterministic merge algorithm due to logical error in code. " + "5. Data corruption in memory due to bug in code. " + "6. Data corruption in memory due to hardware issue. " + "7. Manual modification of source data after server starup. " + "8. Manual modification of checksums stored in ZooKeeper. " + "We will download merged part from replica to force byte-identical result."); + } + } - /** Удаление старых кусков из ZK и с диска делается отложенно - см. ReplicatedMergeTreeCleanupThread, clearOldParts. - */ + if (!do_fetch) + { + merger.renameMergedTemporaryPart(parts, part, entry.new_part_name, &transaction); + zookeeper->multi(ops); - /** При ZCONNECTIONLOSS или ZOPERATIONTIMEOUT можем зря откатить локальные изменения кусков. - * Это не проблема, потому что в таком случае слияние останется в очереди, и мы попробуем снова. - */ - transaction.commit(); - merge_selecting_event.set(); + /** Удаление старых кусков из ZK и с диска делается отложенно - см. ReplicatedMergeTreeCleanupThread, clearOldParts. + */ - ProfileEvents::increment(ProfileEvents::ReplicatedPartMerges); + /** При ZCONNECTIONLOSS или ZOPERATIONTIMEOUT можем зря откатить локальные изменения кусков. + * Это не проблема, потому что в таком случае слияние останется в очереди, и мы попробуем снова. + */ + transaction.commit(); + merge_selecting_event.set(); + + ProfileEvents::increment(ProfileEvents::ReplicatedPartMerges); + } } } else @@ -2101,8 +2131,15 @@ void StorageReplicatedMergeTree::checkPart(const String & part_name) settings.setIndexGranularity(data.index_granularity); settings.setRequireChecksums(true); settings.setRequireColumnFiles(true); + MergeTreePartChecker::checkDataPart( - data.getFullPath() + part_name, settings, data.primary_key_data_types); + data.getFullPath() + part_name, settings, data.primary_key_data_types, nullptr, &shutdown_called); + + if (shutdown_called) + { + LOG_INFO(log, "Checking part was cancelled."); + return; + } LOG_INFO(log, "Checker: Part " << part_name << " looks good."); } @@ -2131,6 +2168,11 @@ void StorageReplicatedMergeTree::checkPart(const String & part_name) } else { + /// TODO Надо сделать так, чтобы кусок всё-таки проверился через некоторое время. + /// Иначе возможна ситуация, что кусок не добавился в ZK, + /// но остался в файловой системе и в множестве активных кусков. + /// И тогда в течение долгого времени (до перезапуска), данные на репликах будут разными. + LOG_TRACE(log, "Checker: Young part " << part_name << " with age " << (time(0) - part->modification_time) << " seconds hasn't been added to ZooKeeper yet. It's ok."); @@ -2179,6 +2221,9 @@ void StorageReplicatedMergeTree::partCheckThread() checkPart(part_name); + if (shutdown_called) + break; + /// Удалим кусок из очереди проверок. { std::lock_guard lock(parts_to_check_mutex); @@ -2587,7 +2632,11 @@ bool StorageReplicatedMergeTree::optimize(const Settings & settings) return false; const auto & merge_entry = context.getMergeList().insert(database_name, table_name, merged_name); - unreplicated_merger->mergeParts(parts, merged_name, *merge_entry, settings.min_bytes_to_use_direct_io); + + auto new_part = unreplicated_merger->mergePartsToTemporaryPart( + parts, merged_name, *merge_entry, settings.min_bytes_to_use_direct_io); + + unreplicated_merger->renameMergedTemporaryPart(parts, new_part, merged_name, nullptr); return true; } diff --git a/dbms/tests/queries/0_stateless/00232_format_readable_size.reference b/dbms/tests/queries/0_stateless/00232_format_readable_size.reference index 6cb84710f61..92c078dcfcb 100644 --- a/dbms/tests/queries/0_stateless/00232_format_readable_size.reference +++ b/dbms/tests/queries/0_stateless/00232_format_readable_size.reference @@ -1,35 +1,35 @@ 1 1.00 B 1 1.00 B 1 1.00 B -2.7182818284590455 2.72 B 2 2.00 B 2 2.00 B -7.38905609893065 7.39 B 7 7.00 B 7 7.00 B -20.085536923187668 20.09 B 20 20.00 B 20 20.00 B -54.598150033144236 54.60 B 54 54.00 B 54 54.00 B -148.4131591025766 148.41 B 148 148.00 B 148 148.00 B -403.4287934927351 403.43 B 403 403.00 B 403 403.00 B -1096.6331584284585 1.07 KiB 1096 1.07 KiB 1096 1.07 KiB -2980.9579870417283 2.91 KiB 2980 2.91 KiB 2980 2.91 KiB -8103.083927575384 7.91 KiB 8103 7.91 KiB 8103 7.91 KiB -22026.465794806718 21.51 KiB 22026 21.51 KiB 22026 21.51 KiB -59874.14171519782 58.47 KiB 59874 58.47 KiB 59874 58.47 KiB -162754.79141900392 158.94 KiB 162754 158.94 KiB 162754 158.94 KiB -442413.3920089205 432.04 KiB 442413 432.04 KiB 442413 432.04 KiB -1202604.2841647768 1.15 MiB 1202604 1.15 MiB 1202604 1.15 MiB -3269017.3724721107 3.12 MiB 3269017 3.12 MiB 3269017 3.12 MiB -8886110.520507872 8.47 MiB 8886110 8.47 MiB 8886110 8.47 MiB -24154952.753575303 23.04 MiB 24154952 23.04 MiB 24154952 23.04 MiB -65659969.13733051 62.62 MiB 65659969 62.62 MiB 65659969 62.62 MiB -178482300.96318728 170.21 MiB 178482300 170.21 MiB 178482300 170.21 MiB -485165195.4097903 462.69 MiB 485165195 462.69 MiB 485165195 462.69 MiB -1318815734.4832149 1.23 GiB 1318815734 1.23 GiB 1318815734 1.23 GiB -3584912846.1315913 3.34 GiB 3584912846 3.34 GiB -710054450 -677.16 MiB +2.718282 2.72 B 2 2.00 B 2 2.00 B +7.389056 7.39 B 7 7.00 B 7 7.00 B +20.085537 20.09 B 20 20.00 B 20 20.00 B +54.59815 54.60 B 54 54.00 B 54 54.00 B +148.413159 148.41 B 148 148.00 B 148 148.00 B +403.428793 403.43 B 403 403.00 B 403 403.00 B +1096.633158 1.07 KiB 1096 1.07 KiB 1096 1.07 KiB +2980.957987 2.91 KiB 2980 2.91 KiB 2980 2.91 KiB +8103.083928 7.91 KiB 8103 7.91 KiB 8103 7.91 KiB +22026.465795 21.51 KiB 22026 21.51 KiB 22026 21.51 KiB +59874.141715 58.47 KiB 59874 58.47 KiB 59874 58.47 KiB +162754.791419 158.94 KiB 162754 158.94 KiB 162754 158.94 KiB +442413.392009 432.04 KiB 442413 432.04 KiB 442413 432.04 KiB +1202604.284165 1.15 MiB 1202604 1.15 MiB 1202604 1.15 MiB +3269017.372472 3.12 MiB 3269017 3.12 MiB 3269017 3.12 MiB +8886110.520508 8.47 MiB 8886110 8.47 MiB 8886110 8.47 MiB +24154952.753575 23.04 MiB 24154952 23.04 MiB 24154952 23.04 MiB +65659969.137331 62.62 MiB 65659969 62.62 MiB 65659969 62.62 MiB +178482300.963187 170.21 MiB 178482300 170.21 MiB 178482300 170.21 MiB +485165195.40979 462.69 MiB 485165195 462.69 MiB 485165195 462.69 MiB +1318815734.483214 1.23 GiB 1318815734 1.23 GiB 1318815734 1.23 GiB +3584912846.131592 3.34 GiB 3584912846 3.34 GiB -710054450 -677.16 MiB 9744803446.248903 9.08 GiB 9744803446 9.08 GiB 1154868854 1.08 GiB 26489122129.84347 24.67 GiB 26489122129 24.67 GiB 719318353 686.00 MiB 72004899337.38588 67.06 GiB 72004899337 67.06 GiB -1009544695 -962.78 MiB -195729609428.83875 182.29 GiB 195729609428 182.29 GiB -1838886188 -1.71 GiB +195729609428.83878 182.29 GiB 195729609428 182.29 GiB -1838886188 -1.71 GiB 532048240601.79865 495.51 GiB 532048240601 495.51 GiB -527704103 -503.26 MiB 1446257064291.475 1.32 TiB 1446257064291 1.32 TiB -1146914461 -1.07 GiB 3931334297144.042 3.58 TiB 3931334297144 3.58 TiB 1439221304 1.34 GiB -10686474581524.46 9.72 TiB 10686474581524 9.72 TiB 595949076 568.34 MiB -29048849665247.42 26.42 TiB 29048849665247 26.42 TiB 1985842399 1.85 GiB +10686474581524.463 9.72 TiB 10686474581524 9.72 TiB 595949076 568.34 MiB +29048849665247.426 26.42 TiB 29048849665247 26.42 TiB 1985842399 1.85 GiB 78962960182680.69 71.82 TiB 78962960182680 71.82 TiB -13554280 -12.93 MiB 214643579785916.06 195.22 TiB 214643579785916 195.22 TiB -1705798980 -1.59 GiB 583461742527454.9 530.66 TiB 583461742527454 530.66 TiB -974699554 -929.55 MiB @@ -40,7 +40,7 @@ 86593400423993740 76.91 PiB 86593400423993744 76.91 PiB 673862032 642.64 MiB 235385266837020000 209.06 PiB 235385266837020000 209.06 PiB 791567712 754.90 MiB 639843493530054900 568.30 PiB 639843493530054912 568.30 PiB 1874080000 1.75 GiB -1739274941520501200 1.51 EiB 1739274941520501248 1.51 EiB 538008064 513.08 MiB +1739274941520501000 1.51 EiB 1739274941520500992 1.51 EiB 538007808 513.08 MiB 4727839468229346000 4.10 EiB 4727839468229346304 4.10 EiB 2061616128 1.92 GiB 12851600114359308000 11.15 EiB 12851600114359308288 11.15 EiB -1681813504 -1.57 GiB 34934271057485095000 30.30 EiB 0 0.00 B 0 0.00 B @@ -49,9 +49,9 @@ 701673591209763100000 608.60 EiB 0 0.00 B 0 0.00 B 1.9073465724950998e21 1.62 ZiB 0 0.00 B 0 0.00 B 5.184705528587072e21 4.39 ZiB 0 0.00 B 0 0.00 B -1.4093490824269386e22 11.94 ZiB 0 0.00 B 0 0.00 B +1.4093490824269389e22 11.94 ZiB 0 0.00 B 0 0.00 B 3.831008000716577e22 32.45 ZiB 0 0.00 B 0 0.00 B -1.0413759433029087e23 88.21 ZiB 0 0.00 B 0 0.00 B +1.0413759433029089e23 88.21 ZiB 0 0.00 B 0 0.00 B 2.830753303274694e23 239.77 ZiB 0 0.00 B 0 0.00 B 7.694785265142018e23 651.77 ZiB 0 0.00 B 0 0.00 B 2.091659496012996e24 1.73 YiB 0 0.00 B 0 0.00 B @@ -60,10 +60,10 @@ 4.2012104037905144e25 34.75 YiB 0 0.00 B 0 0.00 B 1.1420073898156842e26 94.46 YiB 0 0.00 B 0 0.00 B 3.10429793570192e26 256.78 YiB 0 0.00 B 0 0.00 B -8.438356668741455e26 698.00 YiB 0 0.00 B 0 0.00 B +8.438356668741454e26 698.00 YiB 0 0.00 B 0 0.00 B 2.29378315946961e27 1897.37 YiB 0 0.00 B 0 0.00 B 6.235149080811617e27 5157.59 YiB 0 0.00 B 0 0.00 B -1.6948892444103336e28 14019.80 YiB 0 0.00 B 0 0.00 B +1.6948892444103338e28 14019.80 YiB 0 0.00 B 0 0.00 B 4.607186634331292e28 38109.75 YiB 0 0.00 B 0 0.00 B 1.2523631708422137e29 103593.05 YiB 0 0.00 B 0 0.00 B 3.404276049931741e29 281595.11 YiB 0 0.00 B 0 0.00 B diff --git a/dbms/tests/queries/0_stateless/00232_format_readable_size.sql b/dbms/tests/queries/0_stateless/00232_format_readable_size.sql index 7ef54856514..e2639e8fe1d 100644 --- a/dbms/tests/queries/0_stateless/00232_format_readable_size.sql +++ b/dbms/tests/queries/0_stateless/00232_format_readable_size.sql @@ -1 +1 @@ -SELECT exp(number) AS x, formatReadableSize(x), toUInt64(x) AS y, formatReadableSize(y), toInt32(y) AS z, formatReadableSize(z) FROM system.numbers LIMIT 70; +SELECT round(exp(number), 6) AS x, formatReadableSize(x), toUInt64(x) AS y, formatReadableSize(y), toInt32(y) AS z, formatReadableSize(z) FROM system.numbers LIMIT 70; diff --git a/dbms/tests/queries/0_stateless/00256_reverse.sql b/dbms/tests/queries/0_stateless/00256_reverse.sql index bf7ad973cb6..21e75b921da 100644 --- a/dbms/tests/queries/0_stateless/00256_reverse.sql +++ b/dbms/tests/queries/0_stateless/00256_reverse.sql @@ -1,9 +1,9 @@ SELECT reverse('Hello'); SELECT reverse(materialize('Hello')); -SELECT reverse(toString(exp10(number))) FROM system.numbers LIMIT 10; +SELECT reverse(toString(round(exp10(number)))) FROM system.numbers LIMIT 10; SELECT reverse(['Hello', 'World']); SELECT reverse(materialize(['Hello', 'World'])); SELECT reverse(range(number)) FROM system.numbers LIMIT 10; -SELECT reverse(arrayMap(x -> toString(exp10(x)), range(number))) FROM system.numbers LIMIT 10; -SELECT reverse(toFixedString(toString(exp10(number)), 10)) FROM system.numbers LIMIT 10; +SELECT reverse(arrayMap(x -> toString(round(exp10(x))), range(number))) FROM system.numbers LIMIT 10; +SELECT reverse(toFixedString(toString(round(exp10(number))), 10)) FROM system.numbers LIMIT 10;