From 63f7fabb59f47211a86c970a4f6faba4536961bf Mon Sep 17 00:00:00 2001 From: jinhelin Date: Mon, 13 Mar 2023 19:40:40 +0800 Subject: [PATCH 01/18] Add capacity metrics for FileCache (#7057) ref pingcap/tiflash#6827 --- dbms/src/Server/Server.cpp | 11 +-- dbms/src/Storages/S3/FileCache.cpp | 19 +++-- dbms/src/Storages/S3/FileCache.h | 9 ++- .../src/Storages/S3/tests/gtest_filecache.cpp | 81 ++++++++++++++----- 4 files changed, 87 insertions(+), 33 deletions(-) diff --git a/dbms/src/Server/Server.cpp b/dbms/src/Server/Server.cpp index 8ce87bd40a5..0873934f5a2 100644 --- a/dbms/src/Server/Server.cpp +++ b/dbms/src/Server/Server.cpp @@ -1067,11 +1067,7 @@ int Server::main(const std::vector & /*args*/) } S3::ClientFactory::instance().init(storage_config.s3_config); } - if (const auto & config = storage_config.remote_cache_config; config.isCacheEnabled()) - { - config.initCacheDir(); - FileCache::initialize(config.getDTFileCacheDir(), config.getDTFileCapacity(), config.dtfile_level, config.dtfile_cache_min_age_seconds); - } + global_context->getSharedContextDisagg()->initRemoteDataStore(global_context->getFileProvider(), storage_config.s3_config.isS3Enabled()); global_context->initializePathCapacityMetric( // @@ -1089,6 +1085,11 @@ int Server::main(const std::vector & /*args*/) storage_config.kvstore_data_path, // global_context->getPathCapacity(), global_context->getFileProvider()); + if (const auto & config = storage_config.remote_cache_config; config.isCacheEnabled()) + { + config.initCacheDir(); + FileCache::initialize(global_context->getPathCapacity(), config); + } /// Determining PageStorage run mode based on current files on disk and storage config. /// Do it as early as possible after loading storage config. diff --git a/dbms/src/Storages/S3/FileCache.cpp b/dbms/src/Storages/S3/FileCache.cpp index 59eac2db4a3..532e9bbed42 100644 --- a/dbms/src/Storages/S3/FileCache.cpp +++ b/dbms/src/Storages/S3/FileCache.cpp @@ -50,12 +50,13 @@ namespace DB using FileType = FileSegment::FileType; -FileCache::FileCache(const String & cache_dir_, UInt64 cache_capacity_, UInt64 cache_level_, UInt64 cache_min_age_seconds_) - : cache_dir(cache_dir_) - , cache_capacity(cache_capacity_) - , cache_level(cache_level_) +FileCache::FileCache(PathCapacityMetricsPtr capacity_metrics_, const StorageRemoteCacheConfig & config_) + : capacity_metrics(capacity_metrics_) + , cache_dir(config_.getDTFileCacheDir()) + , cache_capacity(config_.getDTFileCapacity()) + , cache_level(config_.dtfile_level) , cache_used(0) - , cache_min_age_seconds(cache_min_age_seconds_) + , cache_min_age_seconds(config_.dtfile_cache_min_age_seconds) , log(Logger::get("FileCache")) { prepareDir(cache_dir); @@ -128,12 +129,19 @@ void FileCache::removeDiskFile(const String & local_fname) { try { + auto fsize = std::filesystem::file_size(local_fname); for (std::filesystem::path p(local_fname); p.is_absolute() && std::filesystem::exists(p); p = p.parent_path()) { auto s = p.string(); if (s != cache_dir && (s == local_fname || std::filesystem::is_empty(p))) { std::filesystem::remove(p); // If p is a directory, remove success only when it is empty. + // Temporary files are not reported size to metrics until they are renamed. + // So we don't need to free its size here. + if (s == local_fname && !isTemporaryFilename(local_fname)) + { + capacity_metrics->freeUsedSize(local_fname, fsize); + } } else { @@ -406,6 +414,7 @@ void FileCache::downloadImpl(const String & s3_key, FileSegmentPtr & file_seg) } std::filesystem::rename(temp_fname, local_fname); auto fsize = std::filesystem::file_size(local_fname); + capacity_metrics->addUsedSize(local_fname, fsize); RUNTIME_CHECK_MSG(fsize == static_cast(content_length), "local_fname={}, file_size={}, content_length={}", local_fname, fsize, content_length); file_seg->setStatus(FileSegment::Status::Complete); LOG_DEBUG(log, "Download s3_key={} to local={} size={} cost={}ms", s3_key, local_fname, content_length, sw.elapsedMilliseconds()); diff --git a/dbms/src/Storages/S3/FileCache.h b/dbms/src/Storages/S3/FileCache.h index 44780b62aa5..c5d48132fd9 100644 --- a/dbms/src/Storages/S3/FileCache.h +++ b/dbms/src/Storages/S3/FileCache.h @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -189,9 +191,9 @@ class LRUFileTable class FileCache { public: - static void initialize(const String & cache_dir_, UInt64 cache_capacity_, UInt64 cache_level_, UInt64 cache_min_age_seconds_) + static void initialize(PathCapacityMetricsPtr capacity_metrics_, const StorageRemoteCacheConfig & config_) { - global_file_cache_instance = std::make_unique(cache_dir_, cache_capacity_, cache_level_, cache_min_age_seconds_); + global_file_cache_instance = std::make_unique(capacity_metrics_, config_); global_file_cache_initialized.store(true, std::memory_order_release); } @@ -207,7 +209,7 @@ class FileCache global_file_cache_instance = nullptr; } - FileCache(const String & cache_dir_, UInt64 cache_capacity_, UInt64 cache_level_, UInt64 cache_min_age_seconds_); + FileCache(PathCapacityMetricsPtr capacity_metrics_, const StorageRemoteCacheConfig & config_); RandomAccessFilePtr getRandomAccessFile(const S3::S3FilenameView & s3_fname); @@ -282,6 +284,7 @@ class FileCache std::vector getAll(); std::mutex mtx; + PathCapacityMetricsPtr capacity_metrics; String cache_dir; UInt64 cache_capacity; UInt64 cache_level; diff --git a/dbms/src/Storages/S3/tests/gtest_filecache.cpp b/dbms/src/Storages/S3/tests/gtest_filecache.cpp index c9da8670b1b..8d70d247f3b 100644 --- a/dbms/src/Storages/S3/tests/gtest_filecache.cpp +++ b/dbms/src/Storages/S3/tests/gtest_filecache.cpp @@ -15,7 +15,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -58,6 +61,7 @@ class FileCacheTest : public ::testing::Test std::random_device dev; rng = std::mt19937{dev()}; next_id = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + capacity_metrics = TiFlashTestEnv::getContext()->getPathCapacity(); } protected: @@ -202,11 +206,33 @@ class FileCacheTest : public ::testing::Test LOG_DEBUG(log, "Download summary: succ={} fail={} cost={}s", file_cache.bg_download_succ_count.load(std::memory_order_relaxed), file_cache.bg_download_fail_count.load(std::memory_order_relaxed), sw.elapsedSeconds()); } + static void calculateCacheCapacity(StorageRemoteCacheConfig & config, UInt64 dt_size) + { + config.capacity = dt_size / (1.0 - config.delta_rate); + bool forward = false; + bool backward = false; + while (config.getDTFileCapacity() != dt_size) + { + if (config.getDTFileCapacity() > dt_size) + { + backward = true; + config.capacity--; + } + else + { + forward = true; + config.capacity++; + } + ASSERT_FALSE(forward && backward) << fmt::format("delta_rate {} dt_size {}", config.delta_rate, dt_size); + } + } + String tmp_dir; UInt64 cache_capacity = 100 * 1024 * 1024; UInt64 cache_level = 5; UInt64 cache_min_age_seconds = 30 * 60; LoggerPtr log; + PathCapacityMetricsPtr capacity_metrics; }; TEST_F(FileCacheTest, Main) @@ -218,10 +244,13 @@ try LOG_DEBUG(log, "genObjects: count={} total_size={} cost={}s", objects.size(), total_size, sw.elapsedSeconds()); auto cache_dir = fmt::format("{}/file_cache_all", tmp_dir); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .dtfile_level = 100}; + calculateCacheCapacity(cache_config, total_size); + LOG_DEBUG(log, "total_size={} dt_cache_capacity={}", total_size, cache_config.getDTFileCapacity()); { LOG_DEBUG(log, "Cache all data"); - FileCache file_cache(cache_dir, /*cache_capacity*/ total_size, /*cache_level*/ 100, cache_min_age_seconds); + FileCache file_cache(capacity_metrics, cache_config); for (const auto & obj : objects) { auto s3_fname = ::DB::S3::S3FilenameView::fromKey(obj.key); @@ -245,7 +274,7 @@ try { LOG_DEBUG(log, "Cache restore"); - FileCache file_cache(cache_dir, /*cache_capacity*/ total_size, /*cache_level*/ 100, cache_min_age_seconds); + FileCache file_cache(capacity_metrics, cache_config); ASSERT_EQ(file_cache.cache_used, file_cache.cache_capacity); for (const auto & obj : objects) { @@ -262,7 +291,7 @@ try ASSERT_EQ(meta_objects.size(), 2 * 2 * 2); { LOG_DEBUG(log, "Evict success"); - FileCache file_cache(cache_dir, /*cache_capacity*/ total_size, /*cache_level*/ 100, cache_min_age_seconds); + FileCache file_cache(capacity_metrics, cache_config); ASSERT_LE(file_cache.cache_used, file_cache.cache_capacity); for (const auto & obj : meta_objects) { @@ -284,7 +313,7 @@ try ASSERT_EQ(meta_objects2.size(), 2 * 2 * 2); { LOG_DEBUG(log, "Evict failed"); - FileCache file_cache(cache_dir, /*cache_capacity*/ total_size, /*cache_level*/ 100, cache_min_age_seconds); + FileCache file_cache(capacity_metrics, cache_config); ASSERT_LE(file_cache.cache_used, file_cache.cache_capacity); UInt64 free_size = file_cache.cache_capacity - file_cache.cache_used; auto file_seg = file_cache.getAll(); // Prevent file_segment from evicted. @@ -319,7 +348,8 @@ CATCH TEST_F(FileCacheTest, FileSystem) { auto cache_dir = fmt::format("{}/filesystem", tmp_dir); - FileCache file_cache(cache_dir, cache_capacity, cache_level, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level}; + FileCache file_cache(capacity_metrics, cache_config); DMFileOID dmfile_oid = {.store_id = 1, .table_id = 2, .file_id = 3}; // s1/data/t_2/dmf_3 @@ -327,7 +357,7 @@ TEST_F(FileCacheTest, FileSystem) ASSERT_EQ(s3_fname, "s1/data/t_2/dmf_3"); auto remote_fname1 = fmt::format("{}/1.dat", s3_fname); auto local_fname1 = file_cache.toLocalFilename(remote_fname1); - ASSERT_EQ(local_fname1, fmt::format("{}/{}", cache_dir, remote_fname1)); + ASSERT_EQ(local_fname1, fmt::format("{}/{}", cache_config.getDTFileCacheDir(), remote_fname1)); auto tmp_remote_fname1 = file_cache.toS3Key(local_fname1); ASSERT_EQ(tmp_remote_fname1, remote_fname1); @@ -369,7 +399,7 @@ TEST_F(FileCacheTest, FileSystem) ASSERT_TRUE(std::filesystem::exists(store)) << store.generic_string(); auto cache_root = store.parent_path(); ASSERT_TRUE(std::filesystem::exists(cache_root)) << cache_root.generic_string(); - ASSERT_EQ(cache_root.generic_string(), cache_dir); + ASSERT_EQ(cache_root.generic_string(), cache_config.getDTFileCacheDir()); file_cache.removeDiskFile(local_fname2); ASSERT_FALSE(std::filesystem::exists(local_file2)) << local_file2.generic_string(); @@ -412,7 +442,8 @@ try { UInt64 cache_level_ = 0; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_FALSE(file_cache.canCache(FileType::Meta)); ASSERT_FALSE(file_cache.canCache(FileType::Index)); @@ -426,7 +457,8 @@ try { UInt64 cache_level_ = 1; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_TRUE(file_cache.canCache(FileType::Meta)); ASSERT_FALSE(file_cache.canCache(FileType::Index)); @@ -440,7 +472,8 @@ try { UInt64 cache_level_ = 2; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_TRUE(file_cache.canCache(FileType::Meta)); ASSERT_TRUE(file_cache.canCache(FileType::Index)); @@ -454,7 +487,8 @@ try { UInt64 cache_level_ = 3; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_TRUE(file_cache.canCache(FileType::Meta)); ASSERT_TRUE(file_cache.canCache(FileType::Index)); @@ -468,7 +502,8 @@ try { UInt64 cache_level_ = 4; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_TRUE(file_cache.canCache(FileType::Meta)); ASSERT_TRUE(file_cache.canCache(FileType::Index)); @@ -482,7 +517,8 @@ try { UInt64 cache_level_ = 5; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_TRUE(file_cache.canCache(FileType::Meta)); ASSERT_TRUE(file_cache.canCache(FileType::Index)); @@ -496,7 +532,8 @@ try { UInt64 cache_level_ = 6; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_TRUE(file_cache.canCache(FileType::Meta)); ASSERT_TRUE(file_cache.canCache(FileType::Index)); @@ -510,7 +547,8 @@ try { UInt64 cache_level_ = 7; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_TRUE(file_cache.canCache(FileType::Meta)); ASSERT_TRUE(file_cache.canCache(FileType::Index)); @@ -524,7 +562,8 @@ try { UInt64 cache_level_ = 8; auto cache_dir = fmt::format("{}/filetype{}", tmp_dir, cache_level_); - FileCache file_cache(cache_dir, cache_capacity, cache_level_, cache_min_age_seconds); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level_}; + FileCache file_cache(capacity_metrics, cache_config); ASSERT_FALSE(file_cache.canCache(FileType::Unknow)); ASSERT_TRUE(file_cache.canCache(FileType::Meta)); ASSERT_TRUE(file_cache.canCache(FileType::Index)); @@ -541,8 +580,10 @@ CATCH TEST_F(FileCacheTest, Space) { auto cache_dir = fmt::format("{}/space", tmp_dir); - FileCache file_cache(cache_dir, cache_capacity, cache_level, cache_min_age_seconds); - ASSERT_TRUE(file_cache.reserveSpace(FileType::Meta, cache_capacity - 1024, /*try_evict*/ false)); + StorageRemoteCacheConfig cache_config{.dir = cache_dir, .capacity = cache_capacity, .dtfile_level = cache_level}; + FileCache file_cache(capacity_metrics, cache_config); + auto dt_cache_capacity = cache_config.getDTFileCapacity(); + ASSERT_TRUE(file_cache.reserveSpace(FileType::Meta, dt_cache_capacity - 1024, /*try_evict*/ false)); ASSERT_TRUE(file_cache.reserveSpace(FileType::Meta, 512, /*try_evict*/ false)); ASSERT_TRUE(file_cache.reserveSpace(FileType::Meta, 256, /*try_evict*/ false)); ASSERT_TRUE(file_cache.reserveSpace(FileType::Meta, 256, /*try_evict*/ false)); @@ -551,8 +592,8 @@ TEST_F(FileCacheTest, Space) ASSERT_TRUE(file_cache.finalizeReservedSize(FileType::Meta, /*reserved_size*/ 512, /*content_length*/ 511)); ASSERT_TRUE(file_cache.reserveSpace(FileType::Meta, 1, /*try_evict*/ false)); ASSERT_FALSE(file_cache.reserveSpace(FileType::Meta, 1, /*try_evict*/ false)); - file_cache.releaseSpace(cache_capacity); - ASSERT_TRUE(file_cache.reserveSpace(FileType::Meta, cache_capacity, /*try_evict*/ false)); + file_cache.releaseSpace(dt_cache_capacity); + ASSERT_TRUE(file_cache.reserveSpace(FileType::Meta, dt_cache_capacity, /*try_evict*/ false)); ASSERT_FALSE(file_cache.reserveSpace(FileType::Meta, 1, /*try_evict*/ false)); } From 73430eaea56d7c354916b67baeb00efd03105542 Mon Sep 17 00:00:00 2001 From: lidezhu <47731263+lidezhu@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:24:17 +0800 Subject: [PATCH 02/18] fix get remote DTFile path (#7061) * fix get remote DTFile path * address comment --- .../DeltaMerge/ColumnFile/ColumnFileBig.cpp | 16 +++++++++++++++- .../DeltaMerge/Delta/DeltaValueSpace.cpp | 9 ++++++++- .../Storages/DeltaMerge/DeltaMergeStore.cpp | 19 +------------------ .../src/Storages/DeltaMerge/DeltaMergeStore.h | 1 - dbms/src/Storages/DeltaMerge/Segment.cpp | 7 ++++++- .../Storages/DeltaMerge/StableValueSpace.cpp | 18 ++++++++++++------ 6 files changed, 42 insertions(+), 28 deletions(-) diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.cpp b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.cpp index ee17ce32114..c3394816765 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.cpp +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.cpp @@ -13,12 +13,14 @@ // limitations under the License. #include +#include #include #include #include #include #include #include +#include #include namespace DB @@ -86,7 +88,19 @@ ColumnFilePersistedPtr ColumnFileBig::deserializeMetadata(const DMContext & cont readIntBinary(valid_bytes, buf); auto file_id = context.storage_pool->dataReader()->getNormalPageId(file_page_id); - auto file_parent_path = context.path_pool->getStableDiskDelegator().getDTFilePath(file_id); + String file_parent_path; + if (context.db_context.getSharedContextDisagg()->remote_data_store) + { + auto wn_ps = context.db_context.getWriteNodePageStorage(); + auto full_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Data, context.storage_pool->getNamespaceId()), file_page_id); + auto remote_data_location = wn_ps->getCheckpointLocation(full_page_id); + const auto & lock_key_view = S3::S3FilenameView::fromKey(*(remote_data_location->data_file_id)); + file_parent_path = S3::S3Filename::fromTableID(lock_key_view.store_id, context.storage_pool->getNamespaceId()).toFullKeyWithPrefix(); + } + else + { + file_parent_path = context.path_pool->getStableDiskDelegator().getDTFilePath(file_id); + } auto dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, file_page_id, file_parent_path, DMFile::ReadMetaMode::all()); diff --git a/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.cpp b/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.cpp index 67f03182a56..cfc7eb1ded7 100644 --- a/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.cpp +++ b/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.cpp @@ -17,10 +17,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -129,7 +131,12 @@ std::vector CloneColumnFilesHelper::clone( // to the file id. wbs.data.putRefPage(new_page_id, f->getDataPageId()); auto file_id = f->getFile()->fileId(); - auto file_parent_path = delegator.getDTFilePath(file_id); + auto old_dmfile = f->getFile(); + auto file_parent_path = old_dmfile->parentPath(); + if (!context.db_context.getSharedContextDisagg()->remote_data_store) + { + RUNTIME_CHECK(file_parent_path == delegator.getDTFilePath(file_id)); + } auto new_file = DMFile::restore(context.db_context.getFileProvider(), file_id, /* page_id= */ new_page_id, file_parent_path, DMFile::ReadMetaMode::all()); auto new_column_file = f->cloneWith(context, new_file, target_range); diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp index 8d196438b10..617b359b5db 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp @@ -1611,19 +1611,6 @@ SortDescription DeltaMergeStore::getPrimarySortDescription() const return desc; } -void DeltaMergeStore::restoreStableFilesFromS3() -{ - auto file_provider = global_context.getFileProvider(); - auto store_id = global_context.getTMTContext().getKVStore()->getStoreID(); - auto stable_path = S3::S3Filename::fromTableID(store_id, physical_table_id).toFullKeyWithPrefix(); - - auto file_ids = DMFile::listAllInPath(file_provider, stable_path, DMFile::ListOptions{.only_list_can_gc = false}); - LOG_DEBUG(log, "s3_stable_path {} => file_ids {}", stable_path, file_ids); - auto path_delegate = path_pool->getStableDiskDelegator(); - path_delegate.addS3DTFiles(stable_path, std::move(file_ids)); - // TODO: remove local dmfile? -} - void DeltaMergeStore::restoreStableFilesFromLocal() { DMFile::ListOptions options; @@ -1647,11 +1634,7 @@ void DeltaMergeStore::restoreStableFiles() { LOG_DEBUG(log, "Loading dt files"); - if (global_context.getSharedContextDisagg()->remote_data_store) - { - restoreStableFilesFromS3(); - } - else + if (!global_context.getSharedContextDisagg()->remote_data_store) { restoreStableFilesFromLocal(); } diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h index 7d2b84047e5..fc371c44936 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h @@ -614,7 +614,6 @@ class DeltaMergeStore : private boost::noncopyable bool handleBackgroundTask(bool heavy); void restoreStableFiles(); - void restoreStableFilesFromS3(); void restoreStableFilesFromLocal(); SegmentReadTasks getReadTasksByRanges(DMContext & dm_context, diff --git a/dbms/src/Storages/DeltaMerge/Segment.cpp b/dbms/src/Storages/DeltaMerge/Segment.cpp index 0a8d329bccb..4f236fd293c 100644 --- a/dbms/src/Storages/DeltaMerge/Segment.cpp +++ b/dbms/src/Storages/DeltaMerge/Segment.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1387,7 +1388,11 @@ Segment::prepareSplitLogical( // { auto ori_page_id = dmfile->pageId(); auto file_id = dmfile->fileId(); - auto file_parent_path = delegate.getDTFilePath(file_id); + auto file_parent_path = dmfile->parentPath(); + if (!dm_context.db_context.getSharedContextDisagg()->remote_data_store) + { + RUNTIME_CHECK(file_parent_path == delegate.getDTFilePath(file_id)); + } auto my_dmfile_page_id = storage_pool->newDataPageIdForDTFile(delegate, __PRETTY_FUNCTION__); auto other_dmfile_page_id = storage_pool->newDataPageIdForDTFile(delegate, __PRETTY_FUNCTION__); diff --git a/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp b/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp index 5a5b43115ac..94b2020eef1 100644 --- a/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp +++ b/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace DB { @@ -109,20 +110,25 @@ StableValueSpacePtr StableValueSpace::restore(DMContext & context, PageIdU64 id) readIntBinary(page_id, buf); auto file_id = context.storage_pool->dataReader()->getNormalPageId(page_id); - auto path_delegate = context.path_pool->getStableDiskDelegator(); - auto file_parent_path = restore_from_s3 ? path_delegate.getS3DTFile(file_id) : path_delegate.getDTFilePath(file_id); - - auto dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, page_id, file_parent_path, DMFile::ReadMetaMode::all()); if (restore_from_s3) { - path_delegate.addS3DTFileSize(file_id, dmfile->getBytesOnDisk()); + auto wn_ps = context.db_context.getWriteNodePageStorage(); + auto full_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Data, context.storage_pool->getNamespaceId()), page_id); + auto remote_data_location = wn_ps->getCheckpointLocation(full_page_id); + const auto & lock_key_view = S3::S3FilenameView::fromKey(*(remote_data_location->data_file_id)); + auto file_parent_path = S3::S3Filename::fromTableID(lock_key_view.store_id, context.storage_pool->getNamespaceId()).toFullKeyWithPrefix(); + auto dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, page_id, file_parent_path, DMFile::ReadMetaMode::all()); + stable->files.push_back(dmfile); } else { + auto path_delegate = context.path_pool->getStableDiskDelegator(); + auto file_parent_path = path_delegate.getDTFilePath(file_id); + auto dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, page_id, file_parent_path, DMFile::ReadMetaMode::all()); auto res = path_delegate.updateDTFileSize(file_id, dmfile->getBytesOnDisk()); RUNTIME_CHECK_MSG(res, "update dt file size failed, path={}", dmfile->path()); + stable->files.push_back(dmfile); } - stable->files.push_back(dmfile); } stable->valid_rows = valid_rows; From 913005dbe323ac5f002031137aed21043504fc1c Mon Sep 17 00:00:00 2001 From: xufei Date: Tue, 14 Mar 2023 10:52:38 +0800 Subject: [PATCH 03/18] disable join from tiflash client (#7064) close pingcap/tiflash#7054 --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 78 ++------------------ 1 file changed, 6 insertions(+), 72 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 87cb96c9792..87b5d6d2481 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -2144,84 +2144,18 @@ void ExpressionAnalyzer::addJoinAction(ExpressionActionsPtr & actions, bool only actions->add(ExpressionAction::ordinaryJoin(subquery_for_set.second.join, columns_added_by_join)); } -bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_types) +bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain &, bool) { assertSelect(); if (!select_query->join()) return false; - initChain(chain, source_columns); - ExpressionActionsChain::Step & step = chain.steps.back(); - - const auto & join_element = static_cast(*select_query->join()); - const auto & join_params = static_cast(*join_element.table_join); - const auto & table_to_join = static_cast(*join_element.table_expression); - - if (join_params.using_expression_list) - getRootActions(join_params.using_expression_list, only_types, false, step.actions); - - /// Two JOINs are not supported with the same subquery, but different USINGs. - auto join_hash = join_element.getTreeHash(); - - SubqueryForSet & subquery_for_set = subqueries_for_sets[toString(join_hash.first) + "_" + toString(join_hash.second)]; - - /// Special case - if table name is specified on the right of JOIN, then the table has the type Join (the previously prepared mapping). - /// TODO This syntax does not support specifying a database name. - if (table_to_join.database_and_table_name) - { - auto database_table = getDatabaseAndTableNameFromIdentifier(static_cast(*table_to_join.database_and_table_name)); - StoragePtr table = context.tryGetTable(database_table.first, database_table.second); - } - - if (!subquery_for_set.join) - { - SpillConfig build_spill_config(context.getTemporaryPath(), fmt::format("hash_join_0_build"), settings.max_cached_data_bytes_in_spiller, settings.max_spilled_rows_per_file, settings.max_spilled_bytes_per_file, context.getFileProvider()); - SpillConfig probe_spill_config(context.getTemporaryPath(), fmt::format("hash_join_0_probe"), settings.max_cached_data_bytes_in_spiller, settings.max_spilled_rows_per_file, settings.max_spilled_bytes_per_file, context.getFileProvider()); - JoinPtr join = std::make_shared( - join_key_names_left, - join_key_names_right, - join_params.kind, - join_params.strictness, - "" /*req_id=*/, - false /*enable_fine_grained_shuffle_*/, - 0 /*fine_grained_shuffle_count_*/, - settings.max_bytes_before_external_join, - build_spill_config, - probe_spill_config, - settings.join_restore_concurrency); - - Names required_joined_columns(join_key_names_right.begin(), join_key_names_right.end()); - for (const auto & name_type : columns_added_by_join) - required_joined_columns.push_back(name_type.name); - - /** For GLOBAL JOINs (in the case, for example, of the push method for executing GLOBAL subqueries), the following occurs - * - in the addExternalStorage function, the JOIN (SELECT ...) subquery is replaced with JOIN _data1, - * in the subquery_for_set object this subquery is exposed as source and the temporary table _data1 as the `table`. - * - this function shows the expression JOIN _data1. - */ - if (!subquery_for_set.source) - { - ASTPtr table; - if (table_to_join.database_and_table_name) - table = table_to_join.database_and_table_name; - else - table = table_to_join.subquery; - - auto interpreter = interpretSubquery(table, context, subquery_depth, required_joined_columns); - subquery_for_set.source = std::make_shared( - interpreter->getSampleBlock(), - [interpreter]() mutable { return interpreter->execute().in; }); - } - - /// TODO You do not need to set this up when JOIN is only needed on remote servers. - subquery_for_set.join = join; - subquery_for_set.join->initBuild(subquery_for_set.source->getHeader()); - } - - addJoinAction(step.actions, false); - - return true; + /// after https://github.com/pingcap/tiflash/pull/6650, join from TiFlash client + /// is no longer supported because the "waiting build finish" step has been moved + /// from Join::joinBlock() to HashJoinProbeInputStream::readImpl, so before support + /// HashJoinProbeInputStream in `ExpressionAnalyzer::appendJoin`, join is disabled. + throw Exception("Join is not supported"); } From f2111c4ec0f245c2273979214899fcbcf67e1702 Mon Sep 17 00:00:00 2001 From: xufei Date: Tue, 14 Mar 2023 11:28:39 +0800 Subject: [PATCH 04/18] Add design doc for spill to disk (#7065) close pingcap/tiflash#7055 --- ...23-03-13-tiflash-supports-spill-to-disk.md | 53 ++++++++++++++++++ ...-supports-spill-to-disk-agg_with_spill.png | Bin 0 -> 431118 bytes ...rts-spill-to-disk-hash_join_with_spill.png | Bin 0 -> 496887 bytes ...supports-spill-to-disk-sort_with_spill.png | Bin 0 -> 223722 bytes 4 files changed, 53 insertions(+) create mode 100644 docs/design/2023-03-13-tiflash-supports-spill-to-disk.md create mode 100644 docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-agg_with_spill.png create mode 100644 docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-hash_join_with_spill.png create mode 100644 docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-sort_with_spill.png diff --git a/docs/design/2023-03-13-tiflash-supports-spill-to-disk.md b/docs/design/2023-03-13-tiflash-supports-spill-to-disk.md new file mode 100644 index 00000000000..df5099b3d0e --- /dev/null +++ b/docs/design/2023-03-13-tiflash-supports-spill-to-disk.md @@ -0,0 +1,53 @@ +# TiFlash support spill to disk design doc + +* Author(s): [mengxin9014](https://github.com/mengxin9014), [windtalker](https://github.com/windtalker) +* Tracking Issue: + +## Table of Contents + +* [Motivation or Background](#motivation-or-background) +* [Detailed Design](#detailed-design) + * [Hash Join](#hash-join) + * [Hash Aggregation](#hash-agg) + * [Sort/TopN](#sort) +* [Impacts & Risks](#impacts-risks) + +## Motivation or Background +At present, TiFlash does not support the operation of spilling to disk. All computing operations are based on memory. However, in actual application scenarios, many users do not have enough available memory resources. As a result, many queries containing memory intensive operators (such as hash join, hash agg, etc.) cannot be executed in TiFlash at all. So it is imperative to support the operation of spilling to disk in TiFlash. + +## Detailed Design +In this design, we support 3 operators spilling to disk. + +### Hash Join +The hash join spilling algorithm is complex. We dispatch the build and probe data to n partitions by the join key, and the build and probe data in the same partition is the same unit. This way we can divide a large join into n smaller joins that have nothing to do with each other. +- #### Build Stage + When building a hash table for input data, if the memory usage exceeds the limit, the partition that needs to be spilled is selected by the related algorithm and all data in the partition is spilled to disk. For partitions that do not require spill, hash tables can be built normally. +- #### Probe Stage + For a partition that has been spilled to disk on the build side, data on the probe is also spilled. For a partition that has not been spilled to disk, the probe is executed normally. +- #### Restore Stage + Read the partition build and probe data spilled to disk and join them again. Note that some partitions in restore join operation may be spilled to disk again due to the memory usage exceeds limit. +- #### Overview + ![join_spill_overview](./images/2023-03-13-tiflash-supports-spill-to-disk-hash_join_with_spill.png) + +### Hash Aggregation +Each thread does operation of local aggregation with its own input data. If the memory exceeds the limit, each partition in the Hash table will be converted into an independent block and spilled to disk. +- If there is no data spilled to disk, merging the local aggregation based on the original algorithm. +- If some data is spilled to disk, spill all the in memory data to spill at the end, and doing memory efficient merge aggregation based on the spilled data +- #### Overview + ![agg_spill_overview](./images/2023-03-13-tiflash-supports-spill-to-disk-agg_with_spill.png) + +### Sort/TopN +- #### PartialSortingBlockInputStream + Not accumulating the memory, so we don't consider temporarily support spill operations +- #### MergeSortingBlockInputStream + 1. Constantly reading blocks and putting them into memory, if the memory usage exceeds limit, all existing blocks in memory are sorted globally and the sorted blocks are spilled to disk. + 2. Iterate through the first step until all the blocks have been read. + 3. Sort all blocks that are still in memory. + 4. Perform merge sort between the blocks in memory and the restore blocks that spilled to disk. +- #### Overview + ![agg_spill_overview](./images/2023-03-13-tiflash-supports-spill-to-disk-sort_with_spill.png) + +## Impacts & Risks +- For all operators, when the memory usage exceeds the limit, data will be spilled and restored, so the performance will be lower than that without spilling to disk. +- For hash join, even if spilling to disk does not occur after the memory limit is configured, the performance will be slightly lower than that without memory limit configured because the build side data always need to be partitioned. +- For hash join, the operation of spilling to disk is limited to three rounds at most. If the third round hash join still exceeds the memory limit, the memory limit will be ignored, and there is a risk of memory quota exceeded. diff --git a/docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-agg_with_spill.png b/docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-agg_with_spill.png new file mode 100644 index 0000000000000000000000000000000000000000..cd43a7604837d4c647624dcbe32dd92e6bf8c3bb GIT binary patch literal 431118 zcmeFZby!vF*DfpwN^As`P@1hEA)wNYAO@WaShN^4(j_gTsDL7%G)ONNAl<2=D4o&> z(k0z|V*>8&dEfKB=lrhg`}6yU&7LmSoX_)&xW_&2F`p_c-XI~OCOUHD2+6IR*Hn)j zA&NP2MXZnfzG}LzMelakeqWF76 zl|+g<)VwzMOzR^nDXF{cmldcIZ6;#_&iZk+-n>Q<`n6d`I+HE@bE0k9le7=d`$~#K zDXIf*?W&1k4*9i&VTl! z{$zLH5Zf97E&-$0k^kg}BnvK{5|7G{GymEBkS9FnT(9t--3)oM;Fm|L+n&D>B=`?k zNG9n83;d7Pw*O(t>&OCc|6u&j7wD7Hcl1Bq&m*{J3CTnoo;>ya&kvCx#+LLyJU&?B zo%50lyysX>Nd2caL&oS_FZTZ*;D0lz|Bnuk@T6AGou`(4MVC*O!_W5}8QMH2-IGH8 zZ!AhZ8JwiPeGGm0;b2y8m!+}LZUcNt0gGw$TD}+VcUz5VI z!{zO3*OjTayLVJ01gvAe7}5Ivx5fSUyGst>6U2-~zac&}JxN+T@@4g4_4uZQ>ZT5i zX5_9i8Eaw{TT0X`M;Gqy^e%0jg5Yzt`6vHRLCV`1JmE!`b1TiE>k&vwR<|a}g-4(m zR(A1}IW<0LRWZyg&&6gtXkJyveoB|H?8*D$e77@u#dr1p!V$<(UPGovJH^6>0q@aG zNlZlGS)NZU3K6eWFy#EpJ`V>5d(8Sdh_GR(#rLvi+79<}v2NF+xyR!IEYu9pq2DbG z7_RlcQ}v(IoDZ7g^GnKQqkiYHvsp}*zE{zZd?HZh|Lj#aW8knxUkHg^KlrTo-?&7x zBxkRDz*?cvX)5m?n|`(3Q8CP#C>V?To9q})e=X5FSI;c%+~mG{Z1z0`mO3<|&e?2n z@>l=Q_mYgehy!7X;kR9A;ovWCuFV^m4dq$&mv9BANZ=`)c8k1LGJ?j}WK!RGd)fFg zVtn6r`b0SRoI42ZuJ@G1}PM1pE<@Va{?;71( zo@^`LJ8i4ftN`}F_yyNh@?AzpHN}8vM4&#GV|r=Hmp;o49s6I{o!*wHSrH$^+G z(4XNmdrfSpcJNmO7_SP+7$Ljl4c}-Y(TO0 zNC9j5hQ=1N1B;g>YaUN$l73tit+6ch%m+Mc`K_Y2`i^N^vI1?%HHJS@#OG2lqO#L= zzq2C2GcT6f{Q5MOPvr@rf#g!mhE!oH33PsB$`9&@fgz8!G| zjQI6BPbFEXLBX@OUQ-Ny)HN7xxQlg96R5AQzO@v ztc=VPc6Z?j4OD2APgaLTFMvDb3E=HccDH=0vbqHDfj(Zd>*?5rJ+ z%0D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

cvo4o;txUfp{jUF&S7WVXqx&Tk(W zry3QWDb^T=q;D&R;Pjl=Iv24MKg(YZL!lzq*Iio=XKO}VB}0x56gu* z;7#HDE}>I&!yG%eE}`8`B3*d1qQU_UGSd#w

@HVQT{Oew`dZL+mB4jZE-bgJ_1Nqv~=#>@_(>=(E0sLVy^6HEX2*nhsT~mmNha;89;FWGA%!vAxqCMVOuWHzGQN8JFj(MTxIR zHamV+`89tVkDm7L4O*cJ{m~l&Aa*7>6Cpom#qOH(*K*4j$(Y2!p<>!6>uXEYJR9vI z%{nDHzZl;id3LKNW~BZ={uSy3aFl#>_h9?w_hC=1LD$&*mkgN{!(2f7f#WYaZs?6- zrG@9GA@55Ea^Rf`#f_6KN%cTZjgZk;vAOXV`SBpbaG;=?Oy`&J0ziF=l$QB?4U|v; z2wq;A8?snmS($v1*%^bqY_s(q@{qcAX+g0@@{uBI%DC2e--T86K5($)|8Q?`yfAk0 zy$76T+fy#Tz8gjJm@v}I5ry!f;(sPSeYZV#b}YOP!J2)AlyH&ZWbCa=q9E*KjP_|= z;+WGVQ|mP^Q6cBVx)bIylEN4&B@DJR;MM1)spgfzoA@73jz7(l@G2l?McC8cv-cD!5<7EwnIPmG-nHBTr1JCcEF1#l^*TnOgXY@gF~OFfVezO#%#g1V43t-|9DQ$g4J1?P-pQYPWa1 zeM=7OfCdmd5*cqppYZwhr4Ryr`!;I_e=w3~GF|=I%ejknPhlL92PLR(PaXx!7l3^{ z^qvgNbBK7U+z$^YzEcl*!q*i3WU@}X-=S?(Q^e^(I*gVcUmZGky|sDY{Vq=IKo@m_ zZ7;p9S&ue@kVZ9W+X+b`@Tq%=qug)Qpmkho_@V<)kNMN1$up1B`R!37)O{tC5~b z;BqKokjo?>2RLRBP9O)h3RzG9tjz}OgGT1Kb@b7lg~*m3vKJ{=^o*f_LQ+4bc5!y7_Sx$EmuFH5ar*w{*t*_3F5a?SIh#|e(pi}B*<|P0uc-@Jf=A! zcRtB1td*^ApOZkk+1+Ku9Bf6;Dp{Sw~AHoj)-Ad$l<%=eD7V^}XO!+s1~q$fYf zbcuI-VbgUX4!M>zLxgjgdi=kaNSpNl35C{5_rFsJzbF5_8n7!L0oQU+NulW-S(?hp z%j1X_^t%PA#3WJ!iPRNdKjp{=z)#z0E)+Gh^Inm`2k<$2t0Ne3F$I*@gu zNZIA`zdy&C06a#H-a-On)a$Dw$<@{VykVbhOvI@{m2y~S({v~o0P55H)^~QEnROSZ z=@Btq+Uf4BBlpx3uJuv66ta_#QfN(B%HyOeH)nG9uKti1U;kq@?ldUb;yu5M>KobR zy1Mu!3b~uAE`KG| zq?Sz&L+2q!La6{v0NsTP7p5P9!%!n&r7p|UIO~o?GxA^1AU&!x_ZHo%0N==beto|S z&KJ`cP!*ri@piO3qv2#4iRpt0#z2CmIXn#(ECwRa?UE~*MbBYNxqhv<;U)xE-ybh} zM-vf|;WE4{lJ_}dY`fS~ZC0n!vcMNCrs5ugBj1i;#7N6$0>dk%E`y6@jaFT{Fqkt; zj=&Zgn0-R-cG)qH9UUB4MIs<5^f;KS@@EK0{6|t)BBe=;8%#L0b0VQyWgh6niN$Ox zuR{OL>RbhGz*L|UEMVTv3tUlf^M_sZLy#PxNBj_)gK!bh8@AZ~y;Hjk1^SB4z3rTB( zmBvyU2~Qr8vCDd9+2Q==!l;Cg+Lr70JAO-)D*aq7lVAGgY)EsB?0AOB;kVT*jdmKP z^MwZ@snY57A69v&$&kq7hBe|DD%Ufn%m*{ra#_j!t zRoiy}#d?6*485})TIGRixaeF9_T5D%eWa$&t(@>E!M4ZlqfCL<$at!=(0RMmu@+XvY_A{ybdnV%SkZgj6s=M?EtkcQUP*Q%b(cJ9Z*GaWvi_p z7s?=`j&%2KqCM8l8Prt@*48Pj-fY!FZRO*yAc7;#Fpih$8iWGBbRG)J&OF;X+n0K` z>^l8dzWtr4)O8P!=}-%}XY{Ul6c&-<1y?$USl&*)3wj=Zv_8F0T#8ZZD5bR8@cHf` znL%;bTIj&$ciFeFF^w7+fUe|l#)}n6bDnJtZl^7E;CvZ(PmN#R>YSiv1HlueXM{rS z$;70i_yZ`&xaBTz!@3NnNquqLS7CI0nq31^JIc;2Dw+f;2kzDc2slR&T?DZIZv7A2 zhb^+O29|IF4xjlwlCTmnyQZNmV>6nOKSNK>El7(0c>L#fE~_@F>+WbER1+}S_B(jj zJ9Fj3$L@xQ<77?&1?81A?E8fBic4eYIL1%m=*o_lb83e7YMor0zeMIfOR%_I%id zO-kfRsVaNLZ|CMd%W8Pt72QJvt09Bu=3q?b9Y2R&OA~8Do~rD!g>0l5m;&k@0sm6D9G|@F>Lrxr(lM@3ox~lM!hPz{scy3Velr z>b%KwnC^;R1!iYw`^*B#PT`o0zo{QM#hag-`G^zm*2vf{!yn(Ri5^%ybjM`2JFcWn zIKALTngaDj3JSU4GzCuez|h+htE@pw+#G7tnaOcoaiRu}RLa9kUkA$WK<&}c&N)yf z^JiC2y1EV#!0 z#AmETQ${}X2Vm~Q4Dh2Oe5b^tSg`IyCY!g=>z87j1g>UKLE@|87T|9G0G3B7~oi__V8qP9U`D{~2GjH|n; z88D%cZh%5ORb&i9lwj3Eh76b&AA*Jk`ZL6fTGoNA$@X`Kn4{+3hb&}R_H1=Ugl8+) zPk!Z^pLV-P)NCI+rbteHp)Q^Nya(cBh0!U%ZmU$#x0EVHHHtq;?KWMOzuk#+tXl!i z@^7WifwF0Dj&@;Z^YNQU_=yIe9Y4_k@2q=ZKtn7Uu%h+9B(ATlAO}cYOtR^pH9*Z? zIE~CCF=qd}?Woo)WaTK~K2w4|5zD_tHmDW&DR*!-$B7xZsum~JKuBv0Z zA$MksB&_}T@gq_-xtx<^6JFkD9M1=or-z4kfqN)|xrSyr49~JayVltq$8N}&f91Zv zChSc@k2@!Hc8duon#y0bHj z<$KIdIUGBN^-#q>z%)J0Z&_6PJ)r7fO4+GcnU!LjQT7&4%%5$qQ<7KJHD!#{V$WY| z?s-pK4)5{oXRmsZAXe@3;PaRMd~z^Am^qs;O`1+8EnO;jnGA~L$nr_L0TA6HZ{Xz^ z*oPzm``=lpJt!5QwV zeT{?n^dMEUhc)sj`cf|RDaY(SM6JnVlvS=wAo{ZXzU`o^ipoG!HRKBceHTHKV311( zg92Dv>-eE4<~0bq#@uP$e%g1b)t`$qKz7^e?(s%EgkE2>vtJ!gtVTXZGgZDIKYIza z71U5AtMkjt8crgdVw%Ah=o!0lLftrt^DV>28cveAkK`YX;+pA+di&*gsznuJ{v8G5 zmXquQ-XmRF2cSDK&Lh((@V=Q@efzi=J>Q=*7ZfO!Y<|vrz0&+VQm-=2!G(>p=8^2<& zC(a2qpJ1!Yt2Zh6@6an>L`b2~e^(32s~(16N{DGi_+SI`=s1ZuzNf6CexIQLQ`t6bM6Ef;!K`Y|3LKa1JS(M$@y)k3D^DJX?cI) zYeg!5mPXnz?&V^tf3SpZ6((ZeZZl&k=d^?;p&F^Wmj>?Ly54j(@?G@R`af1GL{+>Z zhUNO%C#t17gycp?Bh}c8VHbm^U9+%C8Y)rzFPBju9bQQs{8%Hi!( z%%p_;)ThHv+R|@0gR)3J%P?6k1L$RhRXn!h>eiGJ)I&b*F$3`iOGA-7SFhZTgw83R z_Q`iqRuSJ8rETRxIDonMhhPV8>v^1BP@?N4Im|-z39p>`9ea&UiicubW77!O-@+!> ztIzCD?Tw0TX!vew7RB&M)z0L5be6?;k4s$*a<=rR+j>g)O4>9jxgR2Dt@(Q>jPMay zUM>^iio*{b-@g9P0da;$(*Aet`mcWjf_4oz*$Ekc8mQnx2EB>6;@T5Hjmy0J>}~HD z`DpheiZq6!!lb#UyHTbx)_4m6lO-9WR3_@-{V_Q0RFChUb#86! z19v*<7n0tBVB7IPgya`8uBcHbw~jaJHU0&`(yI(8`URj6!FYz9g}VVz@&;t#kLJf7 z$`BrcsgkYFae8i=Zv#fRv^cI|81_tbGzadwI8?RXH{j8vEL300h85fJ_VNn0_lw_; zPy6uB#kG8Kb-H^jQAzAJ{b0;=>|G%W&Gz|mw^rz1ZOCDb6AZX&#)=BVA8^63^~_0N z+J*+9TR#X8y|bDM(WvMfmy721XubV#F}ZFgzDU*W@t`;f+0 zIv0Xv;T=dNyxiKXC)I3{TXXGSc`oV%FX0IYPj_TghuyIfz+c)xmG;P3#bdgt)w}Y=O|3*R*V-?qO;?aw$xzHWuduUs`Z;v z@mG=#*r+IfraGfhmj*Tt3eYII{2WzSnkG_%Q@ggv39xrIo9XK5-~)I@a{hOde88s2 z``%<-j-vH9z73A_>goi1YdioA9#3nla|teT@`%iB{VC zl;`P5UE|^>LAnwK2J7B2i|mtIqz1UEPVK*8aQ=)Uo5GpxJ>38ARK5MYY5I=~@V^u0 zK<3V1mO}pt0R3f?%W4c+52aU|9X{3Gh5pNy@3q^cCWCMcl@CyoaR(oZd`q34f~k9C zW+whu)cBSUrs1<1q-^}v3M6Qqv$^2oR$g`u8r29tKY-ArcV$nAaAjqh16FC^Z* zd&`s~gE{6RdGBkofhdvb03{Xe^YWy%gQdyCg;bkq*2lMMYoO5H2HM0#aStj;d(I2H z;ugO1yWU3x&zD+!hyTaaD&&X+DZEfJ+^fU4S^R6j5Ue}acZYt`!T|If21tJj%&l6b zf@9PG!23^#Wt<7gD7V*e{X2Gj>ys@-Nhpugf;TCMLN37av9sW+R?&Jsw(Q3B>$NZv zc!vazl=dEk`u-JdF)l*A9?O;^{fmV1ORXt_ncxf8chaD^b^Uum2iC)W26Rj{U;x)*OW_kbhD4 z*Vqx(U%37;)l@;eq42d%)~)CY8VH`u?D|^q-zkJ5w_w!z_LNTzSrg2zt)xp zAbvdCq2B+*x`1!xli9p`nvAjZ0IPK9k1y^BJ&>0?jB_p1A$y?J`ozP3rS%Zqa^J>b-H2XuPrwGNL(#xra6WMpKZ7smNDzvtWr5YRej7)Ror z9R+sP%MnKzuXef7N2;C%&+;w4b6*P& zy@#(_d3Vs~&xWwSFvO{BfXOZ^E_$Nf(fidKm~&8`EAzX1@>>H~O*|Rh3CTNfK~0?< zXtS5@ja`9hY5I}{P_MuoTIC{oxcWS-$!mZUHk|uh=EgPMlbfsZ1g4Jq`ug4A8ay2* zy|dExqd6+99_98m<-ae?B&f8u3tHg%{(cEZu7(f)bF&=dp z?T?x(pvMn_OhFVaNT{#I7Y`c?a4T8Q7e_ce> z-~Q)#;8dK)`TG9nk_T_2DtTYAV`eeV?6oBc*oD0+Hj3GF@c~Fp_08x{1mRJB%VAk) z`~?cmJh115?T3W=l^r!fhH3M{F4A89FaI;)K-vUZAEA zu5l2D(ZXzdCnDk#Uv&WFlY(2#S5XuQ5BD`;Xp+ygG!XE+%$g}6Rp3dt`5aq6_b@I9 zR-2ovGklPdatl0gpgh3u^Rx`UFB^YSvHy6ikV!y_4iwBrU~FQ~Aj@O;n$>BbbSu3F zG;v>xk0DAH|06Jg-3w}l0|yVjLep{=7_AM%osTuS*&6?4`vfHU1%ZJ%07!}!#9Y9i zVe29@F7)y|-n`Pfg&w4vYJVXJ3%xr`hL!+NqHw{g9z-O#yk0T7-x_WhTXB2s*g!4>$qtSq(sg@}ixeXziT@?D-z zk4PU)cASC@BD~UU0RejVY4&P2<*joe&L^m$-UXlHWJO{YYg9#r2+$ZP*xQIfG zfdMz1A~AdbzBn8ea^jK?qq%_mNufY0$B@BDjXR*4bC&+{b}LS@cmUaZ0A!ZJ`5p4i zr2SThVI6>)aPamBf!XGQ9DeJuW~s=C+dJY3# z5y^@HE@54L{UgX4TfPPI`y>Fb#*vT#otB#aTa5!KZvs0gYd=&~NyX?eRQ2W9lX@|z zft>q+s!7IcUU3H?{3Ix7e;}ok)#TwP$RP$aLa>%blx*u`nT%0{3j9l6hIfVD{9}EKW zIAIo>+KMiIT+CV6gD=0(GA4{(=1fT7ByCQn(w^JcKetdFO$Qwm7={?W#@S`^rXQ(ekK;KXZ2lHOu-un6xTPt({J z?jY|AQnsSMffdr#9y5$6?rv$ON6QcDZc~Rco*HjU6tK~eQ@8{e-*mvLQ=TCy0c9XfGb0?Qr@+Pr6yI6OGAbQD=WzTJ=~?EJw>o!?Wp>9 z=HoYlTzNzk-d@Jh{%$^C`r51_^A%mg2A?-BSlBVCN3d1$}NmT(3-H+m9ER^SOx z?Jy@%C@q>10k@nE{{d^>IO`L~ww-n!aIrc|7K7s`@D%ML0WmrThKMM+kvM6b`Rl4A z<<_`4EE5EDmrTd+9@&VX;=fkP>4nl-%CSpa(BvX=haaGO%xbmNHtiKB`i$afXlU7kOIHH%M=Ger0-$Nmv^0Wo<>%@X zo}&BePc4NQDVm6ux9Lw-bXHea)!BkL=23x@*~Kqa;UEcF?xCa9n4IZ1Fq6od7z(D) zdh#`mz2gz^@fzZvkX-?|NJwR`z8kA9gRmeyvewfZ`@73nQa%BiT6El5CjbLZ8+h<= z=XODFuW~9%dw>{wybs!k)CPl`cdU)Cx&dxqyb_Xy; zO5dCdyNHS_t;;}o*|4p0_YQ|MLu4t zZ>`k1SlNKnbwni4Zf5!({gAI!QL9Bl_GwO4d61 zBVu&O_tlhRUeOQR*~KWTjKizT^6D2uUq)&hf!>BEe<5}4#g}=YJORfTT+8ssRe*9u z?@I+qo3durK%eX`0=gjGU1^-IYZgAyIr-+VVeo9gxEsT+kE}iZb|i!f&FhX7ervc( zlMpv;{d7gNeDX23y#H5N`VeM9h4kS#ES(uIdT<^%s(^?#z3bpj|4*zJlI}~l{fxIB zZOYvm*tp=X$riu=wYaF~Y^V~YYEaH|QEW3Y4Ygb7J)qTK`U-viWX1Z^XEZ^(3< zxLN`Y`ha?B@MJs=oW**8Sa6dFf5hchdmA|tpr0`;c6iqJ_1RW)mP)03MF;lnMb9g9 zh)An--!6>qeeMBHP{3wqgYsQ3|2%%W zdZbrAy24_Cv^};P(1qQ-9_*Z)iq+g@M&F3CwvcEiz46Ct4cuy1$Ji5mz=#MI`KM2) zK&(O01TY}kVjfZdS-}%PG(nkMzC26)MDw}2)bWU`UrBY38`ZUe{9yi9qkKSs@~v?o z);wEj)fM)m%)Z(hts->|nmzDccWMJ@-tq*Mz zx2O+4J#YJ%kOi3OnhJvhAZ`O!b1)SHRTC%~K=@-&u4mD=nN5$fHqgACnY??S0IN zE3)ZG%noq0T{&qAA#-2@yp zvRi}RhRtM&2y`+)d1_(NUnt}K9%2Rf34so0r@w!v!G|H*P*LT=)favgy@R=sDF;5g zi8@VJC$~NVZ9<#dDbaQLS5;ogt4HuY= zdSKS0#&bW_*C0G^Eiy9CZ42K;kD2K!Itwe}1bsc9vC?wK2#-B^eRxi-CWo(BufY2&h0=NO*#SY%b1Ovn4Oh*Hw9<55UpxNZn2E>2tKuLV-&sdEfA_C?v}M0AtIq$EMQ|zOwi_C23`O56#t@I{{N{< z8w zV>xlQ`aS_1;}zhhW7p;+YF=pyPG!y-NGp~N_-*D_q=z>*^cibBe|;<| zmXEcg#ELI7WXsQl+w!a}<+HZ-G4PH4^g?#U%q-_Z?vINn8KyI__?H{bT0KyA$X8@) z3{0RZ63=lt;Z%=Av3cmVm^8s1@+3SYgy6XfloKbv)tYQ)i_BdBe(4ZDrnbyE&sAmZ zvS+wId2$EIV8j6CbSu%2_x`_kj_PSh4cq}bl|CL`u!@7$@LFe55Ysi**HWFHPYyKNkR8^IE$RX$%ZMkc5wPG;)y!Wxbj z%&L67v&`Nw0$h>Kh~E7B^qsTJj{#o8IbxmOJ$B5Q;MCLu(`^y7DAx`5`1@;?K;;2V zO27CFV|KMD1Yeuh?AFY3DFS^7>KFx0kI_l0+2)I6-<*+sA~Y&JJx+e{Zf;_W3K(3W#{T1p11{; z9e1ky`U%15;P4q39v&XtmuGd`hc9ru7Qs*be_I2Z%MP+e1j4_OWoV5mY0IB^qH zvvz++Q@C2@J^v5BY0BWcSjSQTQ9|I(FmudnU-cCu#8N;eXO9PJaLX{()&1vM{DUQfHC_PMRI1B$^+vPZ58gj3(-1<0+))RCIdF%OJa5P|z?1_bkyX_eYLbXElNE}apvZkd^cMduj2ft=4vKp}u4!(dJv13VjPSOD40@D%)D zeBb0}w8>Tb+3$uweBC?Vkox<(fT-B@u-%2T_bI9C^9VTNJ;^Pxz(exv2(=H7Yg&Ak z_XA-e?y(TL)|E=weCf>~ly)AL1@=>gF1-JK`-)reIGlqTZ~yBB;QN6jb*L#&ErNkz zhgR0$A8{Ej1w+6TA@}W4Y0zi1J76S*dNVqRw*TH3~x$cc=?9tb<;@Jl&!kyF0$FLrr8XePp3fp|Nav~- z2WNzs0tNX!3-gE+BD}PqwQ3gSinsP2P<)B0sl#FMlL4Aoa<7DH{=bF6*BOB%E-k!3 zenP0G$bU^DMm@+_#t@BdKVy+Q|{B#xw@JFBxxdB=|!2 z4p?6VKr7dOYZ*MrCsFvP;%Cy8Vo!N%Goq$5nD~8pIUJa;2(XMzNEn=$NCBuB9wA}W zoJ-d%au@C^og|xqp)P}I%HpUpvX~gdiHf3ro;|e=9x&7_?v!)6;I;;CqiqgmrMUHK*X#*}J#|9lL|i85z%Q8lX0}!Ybkf-^agu z%2%(8XadcZ4z_aP+3x_8APW+}AP`>g&;%4FKH&1aTTD996GwjsKZ19_Ukrk^oj^M9 z^fIA%$fYK)?e76lJq-{KjM25Y>D>|L1`mS8#fK^=Awg}ld|Y_b-SYNA!or8Tp2X_j zVS{wL*R_4Ha?%;vffqRGr`6o?>5*}Z2WrBQoqpAQ=U3Wl4RGB}WerSZ_u1L#Lc zM*MpHe%jbwWELv(@;i0QgwzKXSkVTEK7p95E)6p{Kx!L(gmQb1UzVN zMY_$mQji9ONWzMZs!4!k*@47@!H%TRx>K|KGK5zp5Ht;)j7+|Y81Ub7Z`&zxz>X8_ z@iHV5?-Xj|#TEYKdMrY>@Q(`s(S}_{LMO?5H*gS)EpRypiYyL7TZOYy=YpnLCDOft zz_%5S%As8l9i=VJ0=^|U99^)aOTqT$EmwqAU^`Zx0f>*ZNs}thf>2ZMH3n=7SS}^| z>nBS6l?*f*R8*c*Uj?&;%%O#zu_rfqCW+lp<*m z`PeLjk)V*MD76I+DI@~F8fXOBF64huI9@IAQn;Yabq%u{-}TlSm{}EN$+xyo(n5Sx z6YywToo!#HrAc}O4>Iw;8Oibr4+4KpySUn#8Wal) zrl8%Vww?K#)1e#xGQ`GUj5 zkXqM|fU7(O43YceReV6Bv5s5xfq-kEG|*wdwBR6?FIf@(XJ0396a0K_ z5%Z}7YqYN3Z)cH!*Q3Q4j!=GstVhM7CVx+xSdI2Oc?pa}&a;?m0@fJdVEMG#DQn!W zks&qJ_%*p(hKZ!u&c1Gkf#C)}9Pe&hb2!-sp3r8+&c8^JUF;Ho(XOH+8efxv>JE0aFMxHMg7x1^^Zvq|WGPx+ws3?>Ltav&i!b_$9o0LoWN8sw*%>TAv5T zt~{K61QLiza2DWch-4h(1$+RO@4_9$_m8p&Ie%8f^_HIuG+D2x4!T&~cDDXlt>BVL zjjn#x`ew!M86xzU=E|$*9Z_0?THyPH_$US91J0$~XBO+k>z~)9(ci;YvpqkYM>u}8 zH`LSi@c|2;scH0`93v-V&pnxjUWu!3E-=~EG(+4MEIW_Kpy1F`k0Xwx5t&}uE7|(o>i($R5k-q%#G79p}0e@ z`}&rLjO~%x#-L^o+sI$xKDcv>z04G;<*q~Hc;c%k_23KN-StowYyM$9vvuZjn-wk% zvvt1q-=oTddSk+tLr--?ez-WCdQVZJUTNHn&n559Z%OixBr3G&& z2;F>&+|NF|cLa*BnA^sg;jS-xpO5dqMxA_^Up5g@Vgp?JBIaz>U0}4*M?SuIy>Ogf z0HE0H2hG*+VNB607;BUDcnHL<4)}O{RThwaqNyA3sQ?a=11x3e+s4*!Z`koIeG9-L z#jlQN9`46hAC(qeRIq!r8Wv5;Iw*b1Y9RAC5KqyBKa^wqB0skJ{+dqF7a<|~*kG)F zi{8kJo}Lh|Ul;At#almoeYd&Pb4jM&`)Bin#R-6VOrG3XXWaFy}j#imCKXS!oyk+XCj z4-fGMjKK<(jrH}zHUhm5vr^p6HD$<)P)L^$M-+iD7;%i49UfYqey)@f zN!8bv>Lm?Zp*_h*+(D!QY*@C^qjZdxjM2L0_%ir7}3* zC;OhISG+r4Z$I5gK1xhn-adbSsX!Nyg-HV?mAQ^clU zJ{-NWN95qqj(+Zu+O}qEklXxhR{K{Ex0eUGsv^CW=F?W7y(OZgRG2R4c}0Gn>Gaah zvPexAIMC7ElSh8;zhC6?F9AtB09UAT=jB_>acpXF9R{j5z=N+ElC1dLDP1OSIbD>OVETl4*O z#E(W6Fuc$x3rkT6GBDPLr=gaj}|vJRz7sf=eq;gGd7 zubmRE!&<(P-8b5dg&r%4kHFIDU+4}T0ZZlhS3H@pXtui=3|wa*+O#sq1jJ8bVxsQ+ z@(?pBo2u6d0}alD@C(WD>x!1n&RQ$P~mQ01=m3-5R~D(Y=flq)L-hjx`4aap;d z5lS&-cWqHiOw^&6BEFrG*>mZ z>q9@hTV>jacfLJYKFT+rZ9a_iPrrz;_veByy!zg5@f$_D4wbTatG=Ah%b9o38#x$T zS{>d>pIfCN9u9B1ok%n?&+#d#AY*U7yV-1B$vF4LCrbBkQwt07(*>h68syR^&)uCx z3^uUg&^@!v`o9vw$cU_%hYDW-L$X_=5DrKoP(CAxBizSV;Yxk*O#>bBm)nuq0y^*)@)^ZXPHt>dHV(3^hYR-}R&?5zV99qKHp++z4sv9NmV!+E zY_-*s>&PFcT~12oC9wTRaMhU`p=Cjm+!fV!p@Au@tPBLk8~6j2${ZqWeIYq&vzu;( zKQ)NU7gOPau6$-FNlssTV-}?{`y&K@ZOwl53$a?IHM7eLnNOa-HW;3`tZH%xP3xAj z#e5BJ$*|U$cVt5sy77Kir^w!JNxPC};wpixfcr=W1n7C)P)liwC^fDO*UwQW4DOEK zuQ9E8s%W=DHPx6u4K(~jQ!VY*KXN04Cww3*$sqI-Q8q$BA%B5Wrr z%(@|zivRq1k=2V@akil?14yR}bi*$dRj_eWsm+ zmbP>}2lN7Ri9+qow8mBV051e%*w{fRK<-{w;(O zC6HnLoc-@1QB8`3l^_Etgq1MAP6Fq1un)|U$s^es2l^Sn6PQl&%|~!wRYH72ZiHXp z2!f*-1??&}7-O@hdp+SmwOp0b)7LN10bnT*h^9s7F}Hlo@Nw1uh_cW0v#R-{j$il0 z;VizklsB-nY#KB0`~s#hr08G}_LDbE??Z$3>yUq#*lKk@yfsZ zEVV@p$~IXL4-7_-k|3)Uz-)DvtsUgJz%B|V*E>Y4&2vRhIAWphUGxK@%Zb~dg($F{ zw}+rn;k6#jXUghK65xQW8pObjnO?uat9r@$&eIIyxPRwfJ6Wtip00$%MyePUL!Mgw z$UOJZ5Rwjab7>r~4*|M+}8RQ(MANziidX2fCNMEb^DRjIZd zKxeLkuR}pfOk1cT&GVL)7G#e*-`)1F0X1Xhwd!Xox$^=1SzwEL^KKE~nFVq037o;1 zxjji@8*XEn6gmj9wNf!<*w}pxl_3-BaIO>GhIO0Ut(7jT8|~lz%ogYy zwpMDfhTPxo0!*@f%)A@JkdQFj$>DluSFGF5xzIiL-iKeK`9fbY-?$p?v9E@s&e+l- zQBzUT-eZ)5`x*w);6fdOB+S4(%=a%);qS@PJUC6x|HQqZX>MZnb7{gJP#Wfc2fLuhH$@R#Ph*H0c!w;1S}i>j+<_r_wOBve0br1InZhR80Z z4DjEwFV*GwU4cT`=V~&`G`MA?^$s;kIzIkc(!;D*vrz$|fE#;z?VutowKXz5?G*oi z7B7(a=(fCpWN9`*nQD7xIyn$FQclcPNL*1q!x@J0@p%)>r$fCiuyL16@)dJlagWY7^cg-uy zaL;*7(YGdR6=F~u`}@Jz-{;p?!Y**k$W$1DRs}Iu0p2J!aZE_`E+l(MfrB<_tnJ<}SJGcbdEcDo0eY-8mpktm*@v8Y={Hlfcr zYWzLP*EO|v9-MfK5;9^0OdV68vEn*JlDGzU*zTujV|#yrTa*ddl?B z9r;wa!xWWmtq9m2R?W}+2GE-;0SAv2&552Kl>)TKOfZ)ha{B(1eGvd{ormG?0}Eit z`hJte=I>iqb_N~AdkOkkNFjV#7$2VB-{1i{JH!%sWpy>aRnX_1ep9#~^D|!@qAzvs zZyd?rzyTi-K>&L_KD$XV&_HqYjgEj{C!$URtS(?Q^+IWsH%h!c+I6Xt80( zrswovWi|drK~<$vU5zKjD>|_dfp(D_m~-hu#QIBv?sk&IU6Zs|WPZAZPSlbzhYb}) z%ixob4CHz47rK0z7POO&G#y+Xp)*!Yp_uU4JMOK&sXpvLk-Nc9jKvk7N2%m?5keu2 zV$K4de0S@S{u`9je7Ak6mb|w>d-QgIZn{KtdU8~t>i3VGqb12C`Em^&7i{uV@~(tn zi?ieQM$z<1ENB;z~~xvJ9=kG<-I!$k|LvXw$?9AEhS z?pyXUU2M^+M*9VA8MOQJ>KL(5)J|^2FC6HSB(L`Ty)S?Nu7HLPvVk_3(ReL;XdsZ4 z4ghf(Wa=Rzibk(>!Xu&gn?r59r!WD-5=Nk;F*N*K6PF2cr!y%IK0(2EGDCv^bw3F0d-e+vGYH00nK8+_v9D(H2wDf|HZ+JNCU9G-d2M~Q zQ%DwA###vZvMsm2M(4~JPrk1~Osq7OLnAC774$F$B{EN}HJ<$fc1NU+5YFVxGbF~% zU5W-VL{t0U%y7zPoUUH*OTsn~m@c=zu<{{c=yIO+B{Hf|U6_Y*5-D!Gd2)=je;&yD zM%t?wc|P4c=*d9d4H=hEcyUOTxp%))NxQK>QBIFx+*~`{cEjt^tKxM85?$U!fgN^! z6sO8BuOR69Mj*8H;Z36cFQW`_`YJ5XVSLS$ogT}`neaZ>Jq0SNs&OH#g^Y%i$lRqXKuXAC8RZiytSQ^-S{`kDV*KJge3gb2; zw>u9gw^d-JrfakQo1N~V{=hs?QEFd`&aQniPSpC}{pNj$PL`Imw`sQb_hun~zw;IY z+HQZ?eH7vC_Lr)U#Z7`cKLxjuub0$&_?^7s=ny~+vt>HTi?FP6uV3)a#8an)+?0LV z{qKXdm|#W@f!VWgzk~#)eqHV-ppevDH+2F(LMYY<2%oD*>%;;dM~c2hYh=5GkB4^y zWUGUR1u!Cj|F};kd))p8P)dh;5NQI8^Qrlj&pb6X1M>U~-?doo{BYA!Sy&1a^T)iL zDD`b|V3V6oK~&9vhr+Oy91xlYLEW|})DB69ma2JYB4N+&GKZ;^hoE4#t8*Z9it;f_~sExhVf2r#Y>3z?eIvk7l%=sZ5`zAkKQRA^#SeObBF zy`-ta%40rW)4%@b-g`JAzI|2eX=a{1oXD4{)G54wZut;$v_=iz4ssYPQ=}yTw;!CX z@;0sFaD?4#UI1ivo9Xdd!VV(aw@&KPrH%>aESbNR9?Ldt_B09lPOa z5h&LaiLbxF{-7d$d$J+oC-BcfN)pX*zl(<)^EiB-t@3f=$=a&dxZ0A9}!4nzx=NuGO+w9C4AMx6D)| zbim?wtNZqb{qN&Hy`$Z@=PY}?)K$1=jy_+t+_=A}$*eLGfUT{3No42tC&$QWr@*$3 z@f*%T@%U$DA9=35>79|hckNm}{BF;V?}vR^8%v{F$q@^5KJ;dO=pGi9i!B2PgQ54# zqFdp}hamsIcSfPXm7(|>dOSG0T6t-UDhX6g^+>` z19`5n)AsU3&r7Z^jUHJb-%QGyD0+VeEJ$TQhlUUnU_mwu(AZLu1RvP7&aV{XIB0*O3vVnX!FWsaRC?_UbDb33MwG&F>abD!S2X#sZ3Vr{E~XNX5O`6bR{ zeqnJ=2nl=Q7&cLMz1Al!{hWW*7!*<}Fg;c;>c~p}z~}dfiCdkAfOKySp_OFD-d_HRA?Dhpcp{Eg`M8AmIeu> zhe&1#o{N$HCMiY)xg@5e$(1{W8sUy5sGV4Dz=97bD|ut~wN+JYSc6b37{NO|Au@P3 z)>n}jfC|!v!|&AdzD#NgB+z=b0S>|E^V@6wOvk@tzzGGNxa1w6L=-YrAKnFz9RzJ~ zku@m>y(m90mF?7+-;hHYA!V3?7-`s16+Or~+YAAWpF!MMJgkwQeHogg_#cA>v2T~) zQDgwpzMLXMdCP#V>)MnijY9$1^X7?5%rXiV4}aaRM|IW+T7>Owj{9S^RytYkdKR(lC6`t34t4GZ*YS5qJ)wQ?l(Q?kQC2VG^UhVv5mF$jLq;B`2t*8WK49~U6d%E5l>xmp7AK?!$F7#{n{FV%e31j@6)YBpG5B1uOJ z*}s17XWgRN9O!T)Vet09uaR3>S!vLr#|RHX9!Niir<&K}=ldJPxA5s`?W$4IqKr=} z@9#Gw=qGgk)+_P3s+%+4Rd;=ApD|CDJ2K0Bp)^rQb|J2BAi(!pw|b#Tj(cjOayKx~l!9jlrjPYMDY=UNB(*N}`%XuX{yZK(`t7-TP}TAg zFqo?G;upi^Utq8xgNEg;YE+J6-&DlkpRE!^cLURjr+tDB zKMa$9=MSiPpwt&*g}9%Vdfzlad51_TgHL;alTIL;2CaI-!qPJD z8uVqY5QQ3db_r2Be`k!OznsY6ilAG8z9A|T6B99DdZ6%A6$=Z?ImVFN#dYNiF$ezO zmPVqHP|)d(*Gxjp^61rm!v;jd(9_NB4v^QnhfD$rfUXZ9I_5;9)=`taBs_bopHfjF ziTf)+38(^N{=M~$0HRc6Ey%8;*$OuErIX9lHcYqNmfqPj(6%vtAq!S_I6A&*l&^zl zcYHiJfa2wPYkLXx#NXjs&{@;+p(0b=+>clzRaad&(~f`t#7gho8q#GGvbj~)+i{^q zcqrdb8j~cg-C6hP;*X1hRO`QgZLUmRXD;P})Kox8?icgK>~B4DnYmr>S=5n}iyfzs7`WI7q97wcRXpAB#OP2Fd|Wp;zC{odzsuB z;};rv_2>Fa!Nyr}6r*z#!_k&2W?JmU(50PR%1W&lO7O9<^)*p=uq^0`p9~HqQaqPkP!a(?mQ);k3xN%L1A?D?yw0OJ zTmxv*M@L!HLH+P(`BnVaf~vGD@c&f&eJe=Pgd8&8dRv;CGa;_xfVIs#ZY<`dC&@8< ze0F-HpGhIZ-jZvEkhd~0(g{#X@yUfuz^OiKWym$dg^4to*%*GnyUB#Tp*07x$o1G! zaAu9>K3CHQY?_<-HyH#fz|0BYq+tt#!l#PG8-uR>Ob4%wf8Oq~dTo9k26hIMZ{hiD zDco9e%eV3!K6x(A2YygZx*zPLLgwN#%qeD2qb+(1Lt`|F-|tV2bNO42ng>+b@vh@U z({b4O{L^|R7jb#??hx(8Kw7=Z=NIQHlR$YA@0gcnmJ0`o+&t|a+|UPuf3q1~3}Fl+Y8-RcHU$)rGx-ABryrC-MO zyggl(Ons4E+^HfAz0nMG=4395{XVuueY0lgKkB_a6J|GxUc_%TlS-${n{4@ox9ZW4 zJJGWYrJXa8oG~!&#r@vyB`oDwDB7?YiLQ5d`eNSmAo>@n!JKtCId-Fm4uR9bjux4I zo!&1=Zc@kyi1D0~YWrnOAJyd)N&s77nBPcYpAC>hIS*~mzx^*GBOLWHmxyw2{O_n| zB1-l(3ZW3p2k4F#*vrANM*$|~#_^%k+wb4Q12I&5;Vp+VIEVXgc-D2GIF!LMlmFou z8Q5sHfBJDPmgOd{*6AA5kBJnv0yk~Hp`_!ZzlDP$s2S`c;_rMI9i;-PkbEnpbRv^o z_c`QYn_|QWI)ACq==pqm8OZzVJa&~9l3VB29rNxp+=f-Z11d;4rTn^j@y5p%w&HWb0Y|FKcx}mB?%y>@22_oy;Ubz9cMH>r6Mx5`sfC9pgNDeK?!r+!Z_=p zhxtN=)mKo!)pFDaug1fy)U#%#Jel0Yu2z``-#^hkxL})K*Jg3eIFiOULiJf9{=ur? zcq;GpTD9somJD3I&IpjkY#}yF!XXy1{H&mW?N0zs=fxWjXy0hMmxNt?&0%xNViSs8dN?B8IvSCl#7zv8!nmk7O`DE5Ni!?&GGj1r-}aB z8pLpaq36$1=X2uuo|I762?{~mDW&c2N=X@_)Zn zk^$w<^*(+sehLc03;bLh&EZC|K_xp7h8#db2wo89kkB3AX(39KH?PvqJ@YLfMGWRI z3fdN@MAv2V1Py}z9=1l!#rkjJ@>BlJ1_^R^AY_@6|2`3-{s)5%MBs^2KUX9Jk`!K8 zil=@xHoPb~tPHS(5IT=Z10q(XU(0ddnrjBvshdc|MdM@RJk`1Oo7JN#HL;zZK4uYZ zxaxL~mV=^aJ9PAC#`drA5`{b+OnAZI^LSqKzDZ4mbu*3Q78C8O+Y$Ni>?+OfzU_*v zPQxeKES#kV=!urDr*K&jFt=+gvM#F{iF1?n) z=bLLyBvkNQMtb9>|QnCElxI5=+PY)pzc zrUbkaViD0U#m`$Bir3R^^YnlKT9Kgrdmlg3hQn%-jhHKQz?tiRPtXO{*@L$97aTg8 zGmeMCk<_LX+*1Z$-;M>uCyy2?gLFGn@}ihN`pt8L-}%B0R0V8o@Atk9?D z@KD}8DM+)}FCP@X(mch!+sO63}@t!4b*t28}B{BTw++zuu)8`{3XJaf}tZ zG!aw*i?jQK`7zc`Ts`?fu!Sw+@?eB6f>V$vsG)7J$CL7IWuJt zQUwZTUNTh*xocE;nik|t;@6`S)zcOTLd(xwV;ZN>iFm9d-EZG+y z5`$M+)9JNhP@7@j%r#~1=UdlvNmrGHQ<#;+`pn3fKOEP4b$nTD2rp3sUk$3|@k06^ zR;4J`woU%V6y@2F(%HARu74ZI%kO3l&th5Y_G4?BadTx3)q=@Ox`1lP&wJ1(#p5ji zsAVS3+Omk+USRZ26Dz+`CuxRB%VkpP&1t#6)_Gx}F6PVG*~WVWUS>iJiR14GQBqOV zfaFad#xO3Kc3c#=>9#iBW?Qgb=Q)r&z1baa?Zu+5?)CbycX9P8W=B}6Yd$S4q+L?D z{dkk00_Yy!ouqNqV|Peq%>OZzBmaHTpCJWUXJg0Zc5$->lgIPjj^?ZG88&J|Vx?tBGrwA@=aiWE# z(nEvjUT-y-nK?i9m0sEkv)Aqjxh$rG{u+mL}>AOl86LKhBVS zbL@rL5qw3--n4JW56QCj+T<3ZL>YN3u3lQUq81gMw>>!e?aeF^PWArX1HWRMkdWm# zHk+{g)ro<;bqC^dn@!c^$=N$0Vs}f4P1M#`P0jp~WgbA8Z8(}KY>cg~n|q5|b?!TC zlW}bVI@Q!mi^EFO1sPHHTdydz+zcH5JkEA?8n7A|U{+=qyc_zcv~;~bfd;}+dz_bB zhFi}f6b2y@tkua9%&~}pcPlL=8 zLw_ur;0urx10>qEByz`@0Fpi%)Sqm{&ar$AX=T>K!{>K(9b&mDN50TsAxTWW=DmJg zDBO^J#E_2}gcQpADBa}C6LR_tX3l8Lw3Q?Vc zM*G%k73>y@X|&tWc0nHJ2IBvel$4NgVD>2B9E05f5=?|RcLC88l2?^*tYxA-z!-Tj z#Hp`Y;lmw+(Ma2d`O3HzZ%<{T1WA27Fjp+Mo zE$M*NnKG&hOTx^_h9Pd&mR>;r16Q~VQ3LWawP?#Dv(rz`l^c_k6w{Zye((Ib`gT1= zVC4FfCsV(E?PG%pcWonfZ}w_^#gE9#nc=-d>bjVl5wZ0=;3_rd?Zeq$UBz}i1$*h4 z=;XoSH0Z7A9;K;#{N2xPOhZ}n@ZoOSA6wE(FA}5^Y<`rJIp!nR70L zKu=0k=8)BMuI-`2dZXUO7FKzIoP773(k2qz`T^ebud&4*#r+ z(U^cZwP|Gzz&w#zo~G8H&=y+x>}0Hs_ALOoV^BMiZ2KQ|4;~Rb7J6;W%5^Ee$$oB!$A?z}oliCwNUBZXh82qVM?=Lcbl!k<^qrhMv!|OnT~ANjr6zlf z+rSG)JBxV-6qnW-?terfVQFaT2qtI5;~N|dvu!)?p5UF1M2K4&xb21jJFn2k@y!Av zkKvX3x={5q%y1OesED1HSM0}d$A| znVZSgcV*2Bj18-KSZ-k_>JgjWwOOdkCRJGB3y0!Ynrh-x5-^WaOLS@tZUI<>`JSuo z7v5na2laTPx!s@TL}=MR)g`ZEtZyRFXjNa%2T$&{iwrg2GG*O}TBo&pOe~`4)I}7e zLi>AlO2RsIUsWt4E4a7dQRN_Y%9gLz+MuLaM+W+=?G4-07skTg3$JE=|jKZcxs z-c#QuU`zG^Y>9F1T)_j_XZV5k;SR7!mVQE#t|>4`x@G_Ny+JIW!DNpaok)(!=VyG3dc$Ko`Q3K+AjtXrPTldSFAON$|jVqhXaLPR?g=(IkV$ock~Du zh`)^u58LM(QS}g9r2mj;lAAxZWA?rt&_Ey~wAn~X))C-pss*pZ9HV=Qh?e_Nwmk{g>=0+p$pDm^4T^LSen@fN_5B2)8 zycV#@#VCU9Mr#fx!G>Df_8AG578Uy}H_Q`UHGxanzR(8R3h_HqPiFD?rWPRwM8K`g zrQmtTa{X>r<^}*}VtJ2|%KZP^IwOQBIpv>`4R&{ROj~#s?OgAHP)25%=`;7i z9g`juE#Ry91Vq6iSeGEQY%-fexAeq9XTc(+JV=i6d%2e|jIN)BKP>}7u(M+&FbQzA zg7O2o2k5BVp3eKFjt?sNeD4ex9UQ5p;r|h^(H1_ccqo{7q*{Ld2DUn0Pg=>iqgne` zFbS^n!r`#7$^Mi;F!QL;CdBOiL8T25gSCgQu6bv&t{p>lNZZ+W4_iOfy2eyL&=b#8WOJZH^bYe!L3sj+Zi*y+yVq;4Sn1$2=CMcE%`*00s)rb~`V6WN?crM1sl|f&G zOtCd$^50-r_9d&?RAVVCYZY~09b>`<*<5lI3 z;wKxTllsl1A~pU?_Q6G3+DIsuW-vP0JYd4mT(pc%q>hk3pYh`59O zR&OljhmUsSufDDd$(0NFarK}L2TnlE`Iw6t#A)3&vbV1$kbyZv2kgX$R3E`N&8Mxh*KDV)Fj96T(PxgBY(rmMv5-bgodoSlG4lWX{PyQ_rH$@3$MXv@ zzBr_Cz1T~HW!V~RMz~?n?hPn1Tl&|pyv9HxT>*1XiF6sa`TDlxr~yQ`ZpR0FMn*=6 zk8_sGMHT(KcHxaUk{sKNt%l#^bkOSSP}H=|FRqNfLDI5oe*A_Z zV6h547@kfhLBITbwyN4%ju^yx7y&G3B)lkLe-%(v#6c_Jh0Sr>Tw$#hqUKIM_G5I@ zsl%tv3+(zfW(6ahcaXkCi|nz7afa|eSSrFF=&}l;QX>)^fHIB{1Br<1#?KtV%A}*a zt*1w=`idl=oH)}F0{ksyuREezS)A^r4%CU-(x6|n)t)sLc_ftv%z(5HehI2m?<1(I z`ioy!&l-c!<3o@sYKU6e&EW6UWR1FT_0u3~0|?D-`^#9$WN9M8!qY&yeGUpw5L%=e z1pEFxZFSDzP=+AyAbOX@|LYx0N9<2|fk%bpj2dqsj5MblNNekj>U0ke z4;I_AJxCMoM~Q*Fo%3=D;9|xs74IYJvLfaGW4J9QCZ?>sT;nQmx)@N}W&{y0Kbjpn ze$mZ;>6G*sk7DNfBkDQMN}H^yl~Ix2d8rR9Q=(w8K2q%0@bD{Fvcb}=^e@|OqmV*O zOk4UaZ-d`CDx+ZKR8)fxd>Rd}?R#2^U+LYue`31-p-(65UI;h=0^pqj+5)omw4#%| z_fKE}KNz{}9Z+fB@6X18@v@YL?7ixHaOzIvHlBI!9PYtfrf0@Nf0vTD?!JT+SewZK zBWh!9LUi7Ry)^H?5B6&#g^Z0rk|)4u)Z;>-w5)W5A0N97ksCfaFCDt@;RSr3ava1~ z5w@xFNVuu4Kky*))tKNTqqjAXM8^P-L$Cgch%vpJil6>q^ogkC@k^!dXdXJHl`)H_ z^L(s~O!gVKxPU%-<2MdzbfqFGmb{6+}rX6~+z6&?Ut!2mx1*6j!uQaG9Z_y|W*1~MHf&v3?_HZ&ij;o-UG zc2l3^-*^Sc9|xM%w>*cNF)owP{LA zo+boPn7c6j6eQET{?id$MU}a(-+lzEB5*=4EJXMuuMmQe33%`zl+DZKlqZ`&66Gn7 zk9X_qOHVHUJUq;R%B6G+j6)lcbX^x`6%4d)V+x(%5MHptus~sxnm#WjhWWb+pt`Z? zoIgi+R&Oi@oJBhH+0Y`AGvZ#o3h9%Mp^_a<+74)tZlX4>Ma{M0=-hy|Iyy_0Ix9a| zky6mFtzq(MZDEw9>r5LC*fQ!9%q$${dNI8aJ-rUcl2D}&txuk#(>l$2869CifaC@- z<^?V$IQHb5G)lOvjaz9t^XilE%A;>(l!q9@4-;(MrzQodN`BxFfaLhmgd=R_zh6O& zr<%j-GWjGRBiAaOh0SLN@Z?PG?4p2bkx%{h@_4S3nAu)E z`C5s=9?-VHAlK*aJB2-WiiTqnJ6dt+niOG;r6#o0eNSr2knMDz(o5-fJNM1)CJYu1 zY3{$k@REy^nc7=b05+8-7NG$P25FH2Bl+9%H#bJX#=ZOZ9+*^&mEZW(HJN#CtK7Tl z_A#e(88fc>d~OxYDTOy0V0R71!=E$>C71u{zg>3S|)Ne>a4U6i<557(8iZF{K8l}m}NhC%MQj`PCIwB#!MN$@48u4eJ!P+-lT9vwmZ>V;6Zi;Ii3)!+qxl9y*$IG^~r{kHednZxN;YrWCg4%1j+CuyyUUXx-& zidX9sTHn5sbA`<$3oeT#p5=;?l2O3s9xROr`FwNkuc)j{44Xx7^HebMC6NOwDxPDv zaO(HUsM}8Cp8{d3@d=G5f*s56do{6a0`j&*WgoxOlkQaIbi5kgcB+igmmV#S`S<=I zlBav#ZuBO~hPQ^eSVLlc|yLE`W#bAO;V7#F^k0PYV0%u5^6lJM(g&!(0Cz z!o6@$x0*vNsq!!r=B;|%DLxmDH$U1Puj6r4bF-n&n>w-aw}D~OK%z>~1NLnt z3v>!F9H*9)1fGd(fj^d(FtzO~4!`9~qNtsZFJy$%8VInP4wr^14XZ2cqF^DkTqDq- zPwxjqnti>KrA{?7jygQ?QJ{ayuL09ubtKst@)7i}{Oc|$knVEX?e)d~b(dw>=rjEl zNX2lkJYmCZgR zA0lW5eEC+B5RGU#NL~P347>o@SX%(WpMlNCHsrUBwpoj4@!XRZph%59KI3de1Rdn8m^NFB|^Bt>$Z56_5M;!R! zue=A+NSFP$TRj8bXE#x0(5qg)2+$$8DMUK5NIv=z?ePFCcMM#$Q73C#W9-hKzW^WL z*bF(oL`y=FncJmm34-zgi%@Oq?W5@%M#aX4s~|GNFn`!DvtR@pJ$qmi=z*TZ``9h} zQuKVv38eR2#F+*C5dMI&`u0TEUcctrGTc8WSOIaWNhnbCg! z*paxb%_(r4QWq52T$&EbiTlL=H8}s@os;4eAn|O*H5HC}o4dO@YpT#$w82%{9MUz> zXCft6MK4g4V!Sc|`e1}IhQurZs|#47XOW;9(3$1l^B7M)y)>LjzIF0zU&u~;aBk5Klw9Lm2bx|Gb8!$v<`(P(kiph0rkHI33!Yo zh-c|TX~Z!I=Hk2k*@~1PIL%d0PfN0Lup=oGLPs5uZ@R*H2C=|-GP&X&J2%&?5$o_7 z@)Lf<2|Tz&f<$V9kL6&50SSsI8H6iG;B%_+OGV}KM$J*mKleJXdR3L@eL8-cA~imubC>37M4e2y!uo^vVMMO8kA$6C zoVM=)y`Wfkf~UUD-V?MYi5$UoH-gb0ISq!VGvh~M<229T`?S&Cs~&G-W*PjNRoy^( z@yB@eRU``PmmvULjN}@E;s4-NCssK3tLaRK|Bn*-o)WU5LlUn^-d*6-Lv$M2wyKbG zeRUvApB#sh)z5aK=JMt{xdTwW*#PsCQA~^m&@-9omcWRs4);#PsH`RynFiyG!2xJkLxlKA2Vd)2P=?wQX-r$V2q(d2b@UfiA(k73cTpnODV!mpI@0s zdM7AumZOeh$U9Kn0|5{FGCM^dP_CF&oKf3stIFsi3E>d=boBwHk;o(7Q4dbx&F7_+ z$o$GRmfH91MVU)0$p)1GuHVpBqS`sNp)C<3$ORC^t`7Mzj&c!%{r@7(=Gw85n3X-`?EXk_Ioe zL97mh)d%h62Au0GJ|xJ9_P2yc@t}j&Fgm$PEnTAId#HV}R-W3y-d8(@-YxY|3RWsyoT(I`h`0EnT6OW?HIXU=Jf2^t%t`Bi zhZ4PCHc522K15V>7c9aJMY5=n7!t5gW9K_5w1+sHpcwn+y`O45Qe+jQ1KE`+LJrb6 zw`AH{{%Znw)zA?SO?W4=o;iUYtAuC1zM?8qsdIf3@Shen?#RD%b6Rvl&~Eu8+R&(5 zD8LX>X4Y{&>-+9$ZJqxCSe>+5dOLJ>72NqKF=x&k;vR&0Y(QCztkQv-(aw`K{T~eNMgbLK8(YA+$Iu}+AES9ZqmC{Gw!BLk%8)j zm-=a6!5Xep^lpGGb|-%G=jS8Qv!3;4^3D>`PJR&iyd`$$5LkMqe0v^R*j@sk_8N-%CT;OI1IpPpa77!nA;-Ei&yj{YhMQZRBltWSy~ zeKObvw1yBf#$l^Td_+1PCP_cX`R-`|P4wQ}BS4}^jMT%)Ej11Jdi?OjT$9 zyK|X1h#($NJYBUs5+s%a+M+)2RmZ@HLWz)xhvgddvX=WT`eGLMvhgwBLE{Yqff2>ilA7e@6}Saof{~v zhHesddI>)3@3 znxXYga8taCu<6RdB-|8&O;`*V24K7bCIcKx!LhNiV=dj?N|k-iE-vj*;fB89w$n&3 z%Cn2nLsz!v=;`k|yAy=!8O!9^)_cxQA0H|`TGGqH#O+N@rulktA}J#y zW6Ar;_;Zv-q4wp@Pj>(7D7NY0#BisPzx9t4gj9M(5M=qtL(<%!@qnYo_~axlgjOLG zV`vySpW%eF_{E_=lvM5Rcl+Fd!-pQEf)@qg;TCG@SwH84kZFY?1< z3P{;&M?MM-YdyW^M-vSIfVxpieK8l&eh!7&mm34=CLqBpKLbDsIS{LfI4=dj0KR-h zT&E*sd-0?Uib{U3}acy=r2z6DW(O;(0Ic;yn1+joP7dl zZJ&P$xxbz+%$1gU{QnU49`IE6@BesC#~o=HAuU^FRk9j#gv^7CVpvbCXtjvDfvHN-J#Fp@%=x3kH=?p-*>mpdB0z;>v~?#=kvNQ&u?cJ zrEW72ue7mro5QK)%FY$b7pYvgbDKN7?dMREILwcKcSyrzUEEU?U;jnK(3VQ?u2A4Tp%`rPMjL`y(HyH1>^Onb&1Kg_*Q$*x=`9-oq7#mO-8Wb2A_bNebL^#PtkqM zBpSt~6{!e@%7;HhW~M`<|ArCumpGg-o8oDLZp0*A6QS4bH}NB$`||1fjO1idQXaxT z_X@k;jEpq2C6r<@IM7m7jA4L^Q+%~YpD9Z5Z9mG~g>HKeE<+nm+Ao8e$Ti72b=<<4 zLC?fAyjJYg1q5WizDR$FZN^ zZr+#M@lq_Lol07#VF%sy;?{0mW?z4QmaHV1!vE@$gzJ%MzUnF+tv$1_%ETBc002WB zvn$DLEiWG*DYZVbeHrv|z3inIsMW=yD!`9z#o%&_e*3CWRva=jkrC|w5I-_s_V*Lb zpm&qe4y8`KsA4+x?qg(y{WT-CU?a^NaaR&6KMU^Pd%k3!_SYZEHbYzw4Zf%Cdvrw! zOM?yco_oE_(R;Kec(LF?qXHRYjh@AGQ{L^x-je2f51nc-+M(Thw7_D=!Ry=08s_$i z$j@bGSNpTY(q`V$hXir|{!b(uN@V&Q+8X-bXyh9^aYo{RY=NpL#9sp4q#?E*`(*!x zCup+^Zqq*!LYu=-0!ban2-4Sd$>d_5VKb{t|LY|Pe*%fM1C?E-&;ex|G{KOikYs#; zN)zTbN!t{gvTr5NH3Chr^N+0w(84kpGESc&Vxx=JN7vi?E!N>=yx=q%Xy|#S4z^A( zTPNTgv4`aZYGtokbLP><}`112`F?s@J=la)Nf>S4q4g~FaMR}r>hs&hlKwY?j5S@H z1TWmnOdVRZ;jlF6XL8$k@s9YLQwt7ko}9h`V*CH%Mzkq^x|(k8e!};tqXBKvrk;jR zY#PXWy~pJRzK9s%;a=WW?9PrNo;0g-Ck1iz(U)463CN0G)0p(Hg&0#Sb1>;$?e_`~ z2_2XWDxxAPpa&x@(+e@tbSj7OL1SvbnJ+ zQR2|-ZE;lT;}r;>#PD!Q#+nafmbWT2XPC?as!V=zL$j1(A@=70%@C0dTU_?$_(71q zWRv1syN1GjwgCYF6~D!z)2m70W4De9XbMx2i17sh^nQRGO7wp8~wvW!-0&pM865lOapj`gYFRW4CH`t4JL?nNTOrBM9wI(Ok> zwZ^)-xNvfDk-0J$jynsRDJy~PjD^>_=}a9EZfYqAtG!>j&n;583lhJMjFsPZTTZ;7 zXVQs4WJV~S3;wAd_#20Y1~Ow~W1YHQV*oLjl#C`71n!3zY8AFu{hBU?Zwu|qzc-86 zfBg6%W&RSg9n&MCFa+DbC~?~5Eq$f}pb5iyXMmggx2}$h^y$31g;|o4oMiC|6r2#H zecPWpot z<5HgXGU;gQ96F6EhH69$)V+{M*rP|^hsj{W5Z5M&z!oN@6FRJ`;p6@@p!Q38)zA)C7Nb{!@VE{XKif$nH`zsaG z6{R4BY!)HAexLQl`;G{Z`M{v=`H)NG;zcakr$VMQEUZJUe*s!CJ3cDLT`+NESN7b8 z10ai|{dtq&5=N!vN&L1DFA4}FO|pL!ee-yK$(VUqdo)sd-X845p#OYzW$L8h2c@)C zU_ME@6PMZxO#LMFDrVs8sWjc#p)PG(zNEUkde7EXXYjFu;+a9UQl{xlqA~K742|C2 za?}bPHrmTiV!<96Y^gEX5hP|OL6&2mB?bx4FMvEd@UTE--6d;Xv6gRbM(DH+qf(sq za-}WL6pq9%_NdY7|Jl}V@OGx`?OJjE(l^z82oEuu=cJEQjn7noyEu=*@if^5K&2V- z=nFWDl4TcJ*Qn@X;gtHocdBrOD*&`{9kEDBhjBi1KeDRx<}NMF1LMRQdkDgZa6O`r zqcf1R7e>=ib&{h&2KQT(dFLNoAI{05tD!-~sNEZf2dq3^ub6B<)UNo-e)QM(9%XOr zA=Kagi!Y?6r_i8B|ExBm~0Lt!FIyWaL6CM}hH51g8Vi z7OUA8hBDc<%v++&v_1Bn6$*e^b=uGuiEDR{9Xp0`Oj*K(uP3de=$O{;Mt&os{8B{y z1Jcr#V-EOnkP(uJQ5t0K87%NEt*z1fQ}tufA)`)3yY5MV(abayHy1D#!7=dNlgox4 z`kbS?4yYw_$k}TBc?EW@)HlB4SON1AOCK>wjMg~|to}009F-fmJKeiMJC0ON=j56- zg?R9b$l3m&>URR^WybDBd&MX08kij6l5weGqYg&jeH$CQ+tINUqSJ{xcT}MSk*P^o zc{&@8`}?@z=VbRvOeecB>d42AtSbg+?U^GWmmYH$HPzfBH3)@=;J>nEfBqQ5BgU%a zX5ty2;8`eV&qmt+uhf9d2nIBF9^DVRM)ncf&F|xU&nZ{ppJW%gwFM}z4obSEabpE- zc;BXXeSN2q0ff*fx-yLFDg3ADfLmJu7x3yLZ#VtP01F6V=RmnLJ`&^9h+<0xGio&1 z-yr9lKs;}JegT&-LDe6V~0gMM`h}x$B!QywH;VGb?DcM-*A6#j1|i>cI?=(-`zdns2@hM5Ghf_Kng^^ zca5ysGyK}ETMm!LYKdEgxQFCc!*umA8iN_Zkk@x*%U9CR#Y)^0jpV+OqJvFM8 z6sBu9Nf#6uJV`w;q;|O|i|F9sz~xVUjhx9IxxgPgUF{(C>QY5it%v?Sh*V)_{S-vS zie{53*AE#&>t!<$*te*eAvo=4}z;SMWsP?VnZ z(@I~&nT+siuv|NRCL`DQPx_@(5u$(2B$&22KkrA?MbSV3^Xli?6*s65o&(Sen!)k! zpNPrrab||uCObaPpRywl-_JprXsdzNVZr(1PzaH}fOiS(G1L2P<`C z%;UJs(G0(# z?tAwlLH0;#e|Tzi)^SzMdc0WC#mED@XsFw_Z~x@NZcD2@|d6EK%m< z;FC70!d@uJt1~C9ws3nA7>xfw}(e<3j-h~>a!_q?npJps>GW&q7p-4MMz6+&0Dl9@kux9&XuCwcrXzP-7= z{rpmM;A`*J#=C>?vXL3}YR??+d3+118z<6Z>%?!oOr7 zC1mI1Ok5}{VcyF8uuQd_#WCbk1o-=dro{rqi#3Y3ZZ77EiWm!=^a25NE|KdZFUk);tE-X|hsa?Vd~61n~q9 z&gNk0oY^eqJQlYPrXIz}{D|HIn0Sn-|7XPmpdVYK$w(Lr(+=kguU+=%$L-(6LSNme zQ4hwkO;%$Hy9$%x9r) zw&(^`#Q5$GKgQub^zC(zK{ajiIIj_AUH)s#+1f~#ym!1H+9Ngxg&`R4pJ3wUl`|S( zT=uG7Kx>A>oiv``hl9LDnyUQdvWvt|nprjPP(s!;8fa@_*aSC*` zWr`+OPta;-qgCu)sJ_D2AIq_%Tn=Ng9buF;6SPKGY;9afvhaU@{tOCg1%VuZ<6AzX zZa#US-9~;Kh2Lo4CQ8s3uObnVUY)`N6#9gHN3El`Cj#o>u(dKiBT?=krh7>nD_M6o zHX5gBzhueXGn=jGPDPUD84W33XopSX%kRy>+ogW(`G}YLVXgc4whk^xUIi!Lqr}`Y zd-A}s3DI7y+{ZR~{ARFRSdeaUGwJ8hlT}TNe&XCbM;TD}FhbU*@8Xx;#%$DZX2Fx^ z^TROS(B8~Y0nKreuy=;S$f1ope4@{E$*jpA{mq;u=W0Wmq2LeCoPtf5{$^R|7JGEK z(R{=LPV3#kZ=uQub}rzeRXk%w{@K-`^K*IpueM9NmsSYFw3pu>4y$a*_oo7zC?8iQ zgjZoqsjTDkl#AE|Rn#N4P=Ugx%nC>=-g>0M?{0?dh*MqCNtDu-p<+76`6l1jr!6ep zhDUb&dF6QTUMUs0PpQabjCH#~TZRg$QOLDyzvI_s^^J>7=#wFfYfvI@K;H8f6k`$y zycuSEPhym=o5_6#Z!3nHymsmh3X5Qu?=kDI2QkEWgDql0%I1@^jR6SjG!$}zz6}(1 z=@KH-e&ZD?PO_mLW*0mMvmCr|P0~i65q(O1_I14L5x>naFo=`dSV{T(*%=fAe}tdM zXl~A4bo=mPxMs7+>J#u_wY-A@Lb6`XlA>FjYLP@T!~sh8I(#e zs{~CbgV=HjdCxMmpmXCGbn>?t&Tmq!ciy#mzMI`ZOf0Q!HwpgRb)QOTy6~Ek{q||}S`&D&0W;u(H^bJza1Pr-25!{`s z@Zn42nFVc~m|l$igH53gSR__6V^#xe7Fr+j{8pJ|HvEV^yH}J+3*kVvzhAr%V9gM! z?h3!3pS748CMt;xrGeVS6K2Ydtna6u1*ZiL!%V6B$0l$042s)wPSs;aZ({^KeCnoo zls;$?WES`H+`Wc{F&s0u2#HbAa3jvaFMA2jalJdo#x?e>em{Eg*zlJxVep!qs$8u+ zYwB6dXR#3ibK-obtN+<&5FV|A5@|wR@ zHe=m(Y&%B}{9|t8nTyB#PHwLeGq_@b(qWfh(}Yx>Zt`J`&v!I~xlevv;eT?s>IHsc z2y$pVKsVih3S?|US}c@f6erJoNA6J=JEa1ceK`0#)v1f&Q=?N$-x@wipy*RCuz z-4Nx#ohecLKK_EBs+*4D5r99>%-`4?H|qHpLz|QkW_z_nMs==1Ub{Zx%A85<7vbi|UULYrhXS+q%vHac~)7y$TmG z1<^TCPS)V`~ zQcN%6>9NCT_iOlWCKc27+Dhlj)E7H$#jLDP;Ct&e`K)J9WJMEXPJaC-yr8B&MjzQJ z0+u5yk4vEBN}ehUuu-lFCFD5a%C5xK&bJ>xp=sGxx^T_TmUGsj`8F@jcFy_pv${FK zrk7%WpABZTxz2wtB9IdbQu@$~a^Dh_k!MO>+8}k*$QR|o9)=*SZ+o#N$3{RtF%QJL z+>s%BrI@N8b4O7H520574)}D!2ib|dV;yBv3S;b*kGa_&ID;AcuB)sy9`RdFgM_D>?7 zg*JW7%|#(puV`~=%sa&(ww3$t@DUUUH#C`iJ~x!u`t7+edCI*?nW9JBDwr&xt86!|v@Xa- zUzOG`6nGcnH}Gf(-Jp2qIv{sPBqUZX2Fl8J`nUDg2#BM+jJeWcKmMdiS~{D9-bZjR z>v?v&Cq^;UbFj5e-(Hc2!U~h&fdY0Zmd@hX7S-Rdm1Xa%?97+|7$c(8(jw4?I%izYhzJF!PItrF) zoyniOijf`ZyJ8to-;Yl=ZJe6t7BwdKRKMY5JIj=~>=gQ*)BqCKl8wO_4vS&mM)gR( z|2n=OQ=lVJJi+WemU4W^ZiqwUN)&cI>&LD)1DUY*o}_JgDTF+A1bZH%g z{sqoQax&9+d9T~vF_;xr_-U7U4R38`qE($~n7&7Siplu8UbdWX8I3v$b*4)6C5@Fv zT1oF=3w?`A#KMG6@U^~tW6#gR_;4)I4aK=#$77h!eUl-ElRb3-XcZ;+&coN5V_t|% zg3|5F69(?fzc5vAi$ZqZtmxLh0{s0&Fr_}Rvv{_2d$70$f;rf*(&Xyd?CoW(zbyBC z?4x($FSS9;lW_3grD)$m`ipa?|I07}&@8?!RlpTs*tI^oR*6e`1>}taGNE|Mjs8?hZY+? zQN1M|rV3Ee6dZOnK0S|YER!jj;$VmmXQO7{Qx%Ch*% zW&Oi@3MRiY(|k5;%jTrw1lbS@preDEBnE#~QlkhPwbYVuM4_sF$AT9tT{D|MTX0h; z)?{d6U7s*!H{NW@n~JX8*C-fx9|F_Kqdyr@4$bP$GTCQp^Ng=Z+?2s29zYIk+_rCL z^EydP5h(zi1uJBCRt6pHZ;}yM@1E{H(Ap^Vu12g(oz~SHy*iVZuJGb3A`XkhwT`2C zsb$HTju_qUat9L^+Asnub;ghW8kK=Pue9Z#K_U*JjSWi6W7FCxz5fiO0p8}in2*B61Xw0nb3=dmTas^5q1bCV1(_~UW z2)Y2*r*R8!rdqG)OLxdTBaXSJZ}jD1v3F-WI`2FTUn>p+a?U)y2s9_W7~O#zkmG!s zF<(%@=@Qza)>u?ORGa?3NJJhe(>*$xPhFf2fYd~0^4u2S=u|+Rro)F|DIVENVcEB! z_Kh>WwCOr_uY_Rt;3L!>0}r<1THLRxsab3px%Ln0@=7O5<5PiY6ieX9r~+T8k#)z} zoO%v&QOn@w=oWR9)BWt*N)FS3MfNtH24=Hcs-HKOEb)qqt>{DrmTSuZzX#?fp_;=s zr>H}{W4FyP<};R;4hhdmHEjtm{lb!ULl+#!t~+GvqzQAO-|VLDOGG&CoTSY7oM)gx z&=keboz}DDf8ILAu*4PDp83~kI`|zo?9Q#(6b63z@qE>vLeNACBVwZ6GX+C<*u0V} zJiC0C%UI>zaH_x!lRr)v9LDwSGFVd@h9xyeL^%%qhtFoP%;&59ILk_*uCCmoZ6@xE zHP}QcQWWEsKSJ@H0=M$A?1~1?{kAM+$M(SxQF(r;HAXw^&`I~UsYf|D8oNMr)WRQ+ z?nO-mO5Yb(%?bv)?g-kI7td(eT4$OS<8&}Xw9b@gqwV|wUE^E!I&HIgCB;yQ%{!nv z?m}1HRbMk7^u=-_NVp=}IR;%g$ukwv@g!)yvqQWV75}=jbQ1f}gaW8}1D6?Vot~!z z=TAJ(oMScc8P85wo?>u<>CEoXRt7Zl7z%SLitHp;hkTp3f-m(>o7e2D+@Hg;cF|;H z5n`i4+7`i0h=2^;S_jfh1k7Uy3~yLRd~aY4dV{PJ;AScnQWg!Q&G1iHPcHcxDWaBfDhr&FvvG}}fT4`v(_)Hu6vD;OwI>@Cg{Go^14 zpE^T^e6^KA^ys>i4pwX2dTSG#6pK(o9E7HTCvl!+bx2c#Rdb%sWhvxQ_WXFo{%Pb^ z$fD8+Ci#_xD0r*j+v;$WozpVTDu0u_>N`%akmQ^{;+Ad5igvnhqNQ06Liojx7QbGf zR`MJAYDCP>;MKQM=GioqxxA1=Bj4F)8!*G{nxg506O+h|fRBHrX|Eht&phNc`K4#D zG;;;h2*!LAT(4em&9~J zu?pSX9>+f^+;j>uR@Ae8ZB0PDs18tY_52CCqje`D@w=9<`8lJYS#mN(0H>}Auf}w& z@1T^#4}WMOwScp2xkH@@Mzcpd&k5P;m0f|##~#cV181BL|Fkr$RR^n;fOn0NkhAt= zs+w&2);+V$HjJKcJcx5iY3Y6Cpp}&IF&+fM<--2D*$wrz7y{s)aYFH zd%sXu2njn#n|>VTyl{br3m*ISFZaj1ySwo9h*1wmnA?1*9BRTxtZ|!s zoy<(o$?eeSpQoA1n3ZXic-(Bx(3dY9Lx-k+R7E)Jp6V-(90%nONT3{S+F}ugfsu|o zIhrw9YR{P_`KTb|n`TZ@5q{{pV+%ok_rPOF^ZT0RtagObgwm;~u_a&w*$=E!FyuEe zUijq`B73eAeokhamY}bgRTZ9&$JQRuc$7JsU1?aZw_hTr??-b-5)Kr}x7Lq33S6xh zmruO0_KcbTT5}SM;l%oT@(X?b+A-iIG4({4G3*$%-r=^)Jjcq6)V@j~$y?4jDMg}8 zc)cfgM-f|T471>DV@f~9P&|UDH6VoeSe1rGfG})QDQ)vVGR3oXKcGPG;kQYD_ia2~ z?ZiLNOFZ{EzPObtzQmFAa%PqS>2Z!xpcP&OxNoE7>AnHEn2J^7NzLO_%AjOI2Mw}! zcQ(1ZnD=%+3i&rwKR+`=;ygO(+PLW+^`nUswbdJ1w^nX#l!p*AxL*G95i;Kq zBJ;7EvtPE--vXUQfUGHc`fVZG)HlVY2)Kd>AiVck)YR>zZnmVUvNhYAzW!-6B+$8q5bqBnuo43%UJRI-yl?i7l?YX|~wunxs7*|e1l2X+xKzF&BFQq4Q z43lHFLw`5i7%v_z2{#xWXj=~2ARJQ+ft)Sv@fMSUwGfX2uF<;6eRrdr;$F3VqqR|H zS8{7pDTLX?4Xdj^GAOO=8vF};3t%F?jfcSe?7TBIImrwMIRf@u)54{7U>Q zjVq%ZG8>IlWRM5!&&cP+7(tvD!_!StUH-qAZxg|Mg9>{eOnp{!4hN~vaAR3%&UT%v zh%){AyO@0`ARV?3+(}tbFwcZal|4@hHPAI7lXw2|8;@iLNwe#C5SZwrw0N=t&#J%p| z8>3|cX`W{OsClh4O*-UXd_}}#IR#gp%gU`u0cP@znvaWvULfFgSzp&e83%+Ded+!C zm*3(JnQoN%Q+w2-6>0i?qGX?oJU>)0h3q&#NwT=kylN&O|3V&ZsK#a99wkvX_B>m3 z{h-~g&Xr{C$Rm)-EYQF5Xg@9-ev{R5&s=u84;J+=$bQV7-|wqk*G2klp!3#u=UuIMQ7%n8j% z&U_Enfihm}zJoMqR9y*s4LmK$*eD14^ z>({S8jZvzJVT+Xd`*{D1$MG)Zoqialx}>|wIN!;vBr&0J>Fdg1Q7#b;&N8mVMnQJ! zMzd~oU~q%_^ub0NuiDV%@-M9rT+gBA-Yc#jxjJsW@4J(exui6VDIw{YYLXL@#=9U8 zrQG+Sw_!LB!37rQp~yHi7DC&*Q~&u0H;CIiG`O0ibvA-`Kq%$ikWlceiLX0gl)d+^ zKQh@mspvkRm#{1u1kK;{jW+b|ne&;D;oL-YpjAO!lc_U}AN97ciR*}RumWWq%qJ5) znm877^Yx*b<8fr*2+~p~UlI4@86=+(wL99G_h*xSt?k}THm_6 zZ|?3KhMG`!2F1!>BTRyj%>+C;Hl=U9$9-cKDj=klk%o-5t0uEUcNz8Tq9i1@Tc9mB zoR^UF9qsUJ(%b0xW~)XUtKvd4CM|~n`@Ew%*M4)PF@MVI<{^r%tz|G zw_o!zwh2gN?<`I?+mJzYlY-%awr1YICy~={nUf|I2`E2zkKMc}&PJ%)n_~5X%t&Ai zV0&ky999>j@hNT2BKb$d|2zreWE1hnWqSfghdnOj^CV4<+n9|FMd^{`9c;3%b6bXB zJxK>l$gal5gu2J4M+dtKsr5J>ZPkF6%FXRHCWL?s+BncU$F?iTJkoBQ6RVbY zO7F*@yegQT#1HrHor5|%F9)D6WV%v88Nm-Y+jnx+dXuU9S!zQI)6ZW|46i9@lzsL3 z^)A;YAoaHc@=v?eSq;Ebd$96PvccdN*4!dU9dbB z&0_$SJVi5aTz)dUcc%_r_OPi!)KX*@3d z=%P#J4<3IWBNK(D6cc)H<9$Bjl?4Na!ulxseLCP3nQyREVP<*GK?C-EFO`gl%lVUXzTY?JSYJ=iUK@kFF-MS=Cnnxp5jLU_ zyo$~7dQI1CoU5)DYa8>^*Kg+6!j9n%$>_dURS55vNy!q?eS4L!2Qu2-P30RW4h45} z^x8xbhOaD_2{)Z;yX>F9$*d&Axs6O(4Z~Z~fn}B` zG{$hFItKzh)^)EJf2avbXNi)HLWWgX7CPUgK<5-L_Ouc>MGZ1KVyV3HPyY0ZWJ(w~ zhTjJi(MA8U=5?j7i`1>Toi$BeIaDyL!4Wfn1D{=aPvRK}BFEymib7*2O(S z(QLEt#&$W8ob8$6Yj6Vci{GQ3p*-CLV>Bw7iNS{1X@u7hkN((JI4G!VHQwNtW{fhbL1IxtMH@xasOvSH4UKz@h+VXA$bL%PG3y zk0s+P&kFo5P?Sz9th_+0;GtH>tFA%|_l=mtpd-SFv@ZR5V1w@s*EMerRSwzebg>D@ zl5TcWeDii1zsb*UuP+Q?MSvdIoe#P4Qf7_Xmk*y}?tf(S-hOvM85-vf+MuINmtqH(xLJfzP#F*xJAMm;Qw)D|VMry%Z7oP_{d&ZcYF4q=}#j-bHVWMFmjk9|0S=Eew9DIaBT zfbhsL%?O1|zXh(s9rbk#FRQ2&(4I|0)1Dztw(b5H8$yWJ4`P79xs0ypIX&q?(Q>yxoRjQUpaz3n|Sn3s7~LJyu(EBMG?r-}@28X!?CG*Pt99bjq* zRl$b&3uU({SH*59M1i6kX*F!guLg_HR)iql?n>At7UbAx^2&SYT@<-rGXLz}Q<2Pa zx3Q?G|(*QS@brz=p{u**%X;UJHd{zrKxY z6nr>r^3tHrJsGF#D~n)eD7ojpP!tY`5KPKPMHVEk9=G1(ab`Ris%>x*y*qq}y^6(| z{~S1R3>tTqd4WnkX9%>;4E0B7G&GYp+oiQL6LdxO;$P~j`&QyEtgRzWvBK+kt9dmj zr~qz?u9J*YbZXGX#ENAaT0N_$zvTZ0||MQVu6hrws7@7h{2|lXgZ>3`_}k41R64;st)Q#1KEXDoa%8m!PBRKzGXC zslxGc^QgzG4{^(D(Fg%i?(Evnrh75K%Ag8Ru7^G%vnOSOKL^TQl#4fs12yMCW{O_` zQ)nx)UERIS`OO`qvHd zFN!15bHu70WKcKi)2u7g5J=>28uRpk<=*Y5df-(+;IprH40~V=iBRrKcN+7i003-F zg-wh2TD}AJy+vv$xWhQ-tMYSsbi|6Sce9q19k>Ox=Q7M+!4kZC!SW)|@397*Sa$Km zy1!pLGbqICaocnRtjJ>hdiApB}d-rb*uf`&Y`x?fvA{y>XZk{K)h{2d%8iS)Xz`m+TBkBV#G(^>vT zT$sdg4()YKnREMlWZ!|6AF>=WtA?yHEW=FM2e~W?T%t@fO?4zq)9vEd_I7#H z- zEt60SvF`u;@{?jJ@r|UELJib~_-l_ltt{NlpeVVu-w-o7hq*JB_ZQ`)G$yFc%-WfY zp{#|`^G{5H<5EpKNDt4^CmnN*ajlv40A!?aT!Em&j{7%W&B;M2<>kp@6OtBdKqx)p zpal7MT6RmLZob^NiRj4NepiZ)l4-4_B6p$v5Fk)5+( z@+W;#^hauVAyR~(_M!na&Pp_mhoU3l5g4R_HS}+FUEiTmczOC0YcT$q7`)MkpZS61 z6;SccBcsd)kJWM>eTRQcJSElkCN}Q9s_tu&Bto3-82Dd@lFCIEZ7c4rS z+im($qBg^1xd1d(nf9i6QeYZx$zW{JM@8NTXC@CKdF5(i&>1+@4lbO|^P_yVhYu}^ zcCkVTSqJZ4ezX*_CCLds=YB`GxMUs^blr7gF>t8xS6a*JxO3`k{8WQiyv6 zUZfX7`P{FMvvPbG-H;8CN61LQ4S2IJ4TMAl?AlM@ zcM%7%EvsagQ%yu5<2vBaO^wqzO2rjWG#X!We41v(uLgNhpZVDO?3ucgLfwW5D83mi_Q)bl2i;Ix z5mi87wcQK@wxW~FPG-a5Agla$$dE}@4bTq@Mh~J8cvCW1e(21R)!Nff@1|HTQ~|43 zkrI`21vj;a-p>=sWNbM{?D|*wG1_YzOf&N+-p^8kFBgB4$8gyQcii@^&SrwGpFh1+ z&pP-)TX7uju9;%r90MaDW@w{RYhZ$s!^}hp&Q|B=plKc(CR!(tqm-zkP(Ap7f_}^> zVgiZsiiSa$AnnC9L5Y7y@`@kepvKCNZxoz7mb3~{Dycw%uY%{~9bauzh(z%O6w1b( z$Mo-hVa+p3VU+iw;3dLaoT{HJ+T%i@ExLz0J`iz*;zAEa_sXE$tRmvQxcYM(~UrU;9!29*z#6kd65u{qI_fLU`>it&L0 zp3e9+DD6E^fE>R!={?%>K6qDi;VtI(Jw!uvC<;UiB@TK>8(!lp58NJ&yiq`5Vc+viUNUj-9A|C;cjZB#M5fswTjFM4Ihp1_2`3v(uM zGzsEfH$ks&|M_aI$JD9xXHueFGL?MtytUE&M(i38IPYj9-6n3XNM(hdCQdvx=v3N< zAhBcDZ_UD{ghBR{2G5>Wr%~@X+`1qU4V!L<#P8&_(d!0r$4bgO5eP_-L~uHOKh>Zc zbxVYM=1c8OIa`xYd4#b&R)%)Iw$2?iNK@2ZKZnMhaDrVYcI<1sR;7sIxZ85)w^O3|`YM>Q3R$mDe;V>#uM@5ON9)={)8Dn3idhTN#4x(J z5I(!yh_^6`Tm}xWTP4A|XseXj9_MLEO=CKJW20^hB12VejeL7Wk z&GwEP2g_13`tYJ>ewBnor01VbIee{FmKRs)=fjI~d!F{f`ZhaEEaJ`=y}LYJ>fJ#9 z@Ix=ya2KPJQ{YW~j``(T1@yntGm|+=80E6-Dr={zW==1<9ncm-0G7kz5n*pIc4E*R z4}SZ!Bb#%-B}>lJtYB7Rkw+t&E;!R`#N3N8>UYcvxl7|-Rh5XP-ouI zO|#l@6Lr&2Z=EPc!JbfwfGM&jX5-q;LP4zPV_ntyV7og1@cUs?T&mr8Qu{X6Lp|J$ zu6u}}5YVjO8fyh`@EbtA5XH!saF}eY%xBZ(F(~;k^EH^46|^Ma9Gw$hdzQ@eALVZ; z@x1<~I<~D`>+9No2Ii#19A^JtrpbpeO`XkgQPYp3RE@@?pD!NASOJG){IP!TaTbUl-|J&nIpg;tQU~Q(R#fHVDrX+R7zb zkG11|H{j{M5MkInMdBK3^dq7EH2>aMX7gizyIC$RA8!1rnYM*K#7+_!??3vMx!o}l-O7cT3I_B_~tZPQ=xbY z;VI<4IgW7AmiHuFYB`#SvpQBcj;{I(pS<{=>MN-=4(ap-sp!b^&w-l&ERT^8T@$(S z@9g8N)gY?CV=!rA@Dh>+n&71y3dr0c(vUV*_D=Qd57KSO4aPAGtcp>-`0a^rD8FP5 zDx;&RzA;jC_j%^E9{~f}qvH03*d#f%^f9;Jl znv|l$eIa`1ViXJz9c}U&V+-z!a_(1Pac%R04D}t?CKVl8P4nb%wv$|!!VKdQu03Ud z0q)@>!&dWL+Zd=AmxDXIh}*0UWh@2lzz4CmK6sf*asHO3lODJZKTT-Y6WtHQGuY>$ zZ4ZjGWQBpZZ)$KdNydK7HSF65ICBr#oK;8%k%xV$fE`>a0|xLM{eC_-;be&ZRmI6|p*f71Zp z7rT(@i=nn^wM)xtc&KBRTD1AEvdYsY^%B~5IBi^jVKzo7I7guQkvd+rPJ|*WNxID; zqMbqdg}5-W&=Kd*b!!*k(i=R@eOGia`x*)lJ`8NsNkzS91^6gxqGaybceGN;yl?pY zqNShL|HM1}C9G2j62w5e4ztq4(>s6R^f#pivBAZ;6~(3~fD}=*f{#^TK$=2{rJhjt zY%*~&?{VoEsl!51t9(bzBy)hqgS{>)&N)!~r%wDJuQFx=H)LCy0F~}xL)jStTfHt& zw>@ynhy{tafazk@M+Vy}U+*nP<0b$j^rVS3T@bW&AS-?tdym`#S?r_V2Of~2KMKJL zJON!M2Fh#M-~%exr&UH6Ibd1ro&lqRAyl2$AGibH446*0UWEiH(R|K9l=Y=HCoS#R0^bg^05F&aj=}|;%ouOVaz$*XJ8(x(H&}=%tnQMcwW6k|O zWd+RxxNHRpHGaK&XAu8IW*SBTUq)1KJ+3;}=FR1eM-CQx?u5(X9P`*FJUYcFRljmb z#jT^vW2^oGJ1F=&2sR$=ulX>IjXQ-Blw$K<1)u5+dIka&>fyg`%DZdgmae64wxPAD zI$1wLIJC;Y2qa_Su|4PRA)sW)l{?ZeTx6Mkd`0J(AdH6ViFd}Mo@h4MNax0`0S2nj zf26;;rg#%4STpAKtm~G!54h>DwyuH@#IgD(m7QC=)a$c!)z=gAH-#XlK0%E^`4EOa zOlYq;NJ2zc_~EI-fER&uM}d?9-&{;o((oq{JK~pu%%f!QO zpWKdXf4yHJq0O&W4pOFGE(^6&$Oz^93p6sqz)F1q$j|p*!^D)e;48O!M|(!%&V9t#lHF}Oun_;TBr!nQ6XFW{Q{1xE()+KRadR*zIJU^ z%Oz}*L?e-%cNcxWzr5J0=ZhHIq-2>3SJD^pdKac!G`bkD1V=?{c={ePIs zHyd?lT`#}oq}qB+4hsSpbuYsVH(i7k_+X7FpMGYJKPs89@BZp&lXcCme>i>w}7sQgxQ3DsEpowDBo#6x~AU%ltu(( zHVQ)colp$iVM}di(C!qmGc>KDU6*za~c>E6EBz0XL*Mu>t;`VPG%sx zOIrb*;8I}Ng2no%4hkNJ&R@3i#>i1BB~kd(*Y_rR^J-(JoaBfrIaY?C*4_fHawF^4 zE?m?zT>Lv%1?JjFiz_9yVcy@kdYfneXZ%c{-|6>-zmD>NZ7)~}1&FT!Oq zHm;eIEUu{lI}$jB2(MsigGM&lgGPh=^4p(LLG6sQ)Kcr;f4J?LqmX+{@1WA z>hemHEkwu}b_VF-9F9z_${SCnr84_AlM74q8d z^%Lf7Z<6EwZMhrD&E2>5p+3pp`3cWB6)gKc727x_a|1g}`IUUT_ddR)gJCIR7(zwj zsVYuuK`)q6=UH%2C4C>ZCz#KGL;gyru`c z4^8BCKxyVR`ER~{|L4!2BsWcbx&493ESarboJ~L`aciNPy9iLyR>Ot?57T+1)EaMg z@Yr~i%GBY8({Ul1R`ciA$7Dl@%4K**e;d8Z@S}-vwo|+hG4}08h27}(wC`LC_&H1C z3e0j8!OfigQF#B+=^s6xuear9GGOn6J&~Z#EsORi64L~xBRg}%xnB%pv^G17Q2YzI zY8f5i?+!@Bl*egjvOgo|R>Pztum4ehA}>G4@86wm>f$fzw|?LH5E6t4T5E54q+kYT zYuo-Ct0->b3E{ptHE!`|prGm!8L173?-k>V-HpFatPtl{WT}73R%%UOJ2XZ;q^Dwl za22lcl}6uX8@=qR{HPS+l?ghv(Q`U5NsG9{W7i{gGaLi?E(m|u-7h=&9V-s8lH#w? z5GTorS4<0?LYOVVX=`g+=U3m0pbndMW^Ofmi!tb zK&>E(7K$o7$n&JYTUOttl`rCisJq#x=t`F+75b4=YJ0PKR`hzw=uLjVwn2JbVs{yC zdu1NFUbv+An5Q{tPGbTKT!a(i;`iQgDVaLzrN1&%-OgOD%s$1 zyMjbXvd}BTy6_qqg@+<;*RDEyCJdu(&n8f*ob3Ciyl(1hptkQFOu%KkdEf9)`4hxQ zL^FHlk`0ITiAD%BOhLaWeT7)5UN=T3?Pth0vPNGwmu?&lL{m%Kp*wL7nY{XXmsY&g zR|MI9u5E_X{fFSCUyNdaGT=%QbnYriD%x_QiMP}q8AHykU73hHGSyAb%rZHBqLrpy zY;cZX-q}WvH1jhzr+Z)mikOTMV&%aSrWbDMeb2;mJ|>&NEWKGb0f)WmvD+Unq;pTY z(nLOYCZkmc=56h{C%;T1FRzOgusu{ZH#b{JIrqL=PQQk}laRGl2G(a`HM8YjZty`< zu2ad3uDBhuE?fcQ7UZ1$u`iK5>iY7e2SHr-uBDO78?)WKS#nnM%sTThcm<8e__*`5Cl|tXxfOqM$lrMIZu2 z1f=jvE3oT?nSf1S*>&tkj>B>8mjVXiSONc1>;g)!QA{h{!ARl(Gd{d}g9*@@~%(eV;yXLs}BakNE5px}FP z9+!pmyifKneVR5-32}b-?TLWWcA8P%fN9MaJWfJAJ2AdJb1M|bAF*aUTiHjsYiD2m z-DL{ow@<+zV}61pE`wHk97-Rq8H-&0aI$+*8I3Ky2Z#I2vi@nuzzD-Q#Y11@{9($o zY!=jdl_6mzsCumZ$%07PsoMgWP)Z8CPX52&-+Z!rtW641)$e@TO@NK$~{OQEX`Av`lNEZ%WTMy9N9;N2tLo#6M4*vRi&kU6a51+zI1F4N$g1JdY>W*f8@T&P5Tju5jtl#r=;S3v%Zd9sG_wQ|O zbSLfou(s1K$imwm3cm}wg|`bjha2vjZ!;&ISBTgHK}z2gbFo>S&M^zTgc|M6sKOFn zLkzkRLyvv#a{Y7brUL=|8$Lw-iDPb@?x?Hy!U{Le3TPg=!R5%hzsE%F>xw|zhW6n)<1x`iNz!~fY8B8LWBL)L*^c^z=%Pcw;_w~;}k=7RFHB;w>=}D$YugRx?k*PXbn6o+f-Wb{;u%<=8(IKT^6@pz zAivqYKQNsB)QF`TnChHe_u=xBf-riVgQbwKHlPoih^!v++5~lAeDwMmw}+)3cTeX? zPBtreluk5-O;0Xj^GYW}o^#eeC5kTiq@03hJMQ(dHaQ-R`w9Y3j!J$Jz z-8{;Gkf2(S?GECn>hH3*U9(W6Gni z^9Sg|WqQ2+2JDi$xcU;{T?+?d_LU!KUilZb1qjHtnS4>sF!kw>;dPCM!?Bx;gn^Ui zM@1QU$0mwR)+i?%HIVsQC2c?#cym|Uifu(VNc{u3Mgoy&-ue22f6;J&>|~Jux`Lg9 zJr`NAdk{|w}!VdnpqtC>tGc8ATOvQ72cn16!J3KhS$q5r1t^e=o~A|2@>U2Su0 zaa$V!Z1o7w4W&3Stbq??_5Rr^XDxLI3HZ5UPPGm-c9H~LK=1Ya_49Unxvw=bcVwWT zu8j>473MrnA+aW zb+5H z3rnOFbwBXOd0MVEChEmt^pNQYnmADW7xw@XWSXeqE2nuC__0F3M&pONKm1aW?>43I z#{i*j=^h5|(mrX=0r#%RZ^OB@*N`om**%Me*Bcn+x2+JG_@vA5+J^(JB};c; zyH5oawKPBJp7zLVFf80L$VqZBn4WNvRu#wtk4|#DiViI`?u>f=tH^F&IC@wzo z!Fk+-T)>AjNh@vWdtNK!Y7UgGD7j@s0B2Gkg{jIbi*sPITauO;hjUlaiP?^WweyY9 zWX(OsJ`+R-o)X{ozd^^aUiu)O@WNl!Vdb^&XTW6`UxdC;d$-kv*D2g&h}Q@&QbeN% zai1MoHzNqPM{18kDh*THU_S`K*Of4cP%x7U*ra`qM^`260!Fy9Brb-~XPIf%P65+R zCY??z&a=*PTaB0Z*=SC8kw?$yhWW?&M?V&gbb!onmzFJ{l%d@RT!+tR166&BJ2Vx2 z5$N+-SrcpiO zz0;Qi_a@J&4?uDQQ65!A%4dIU=D>!AFh(FX?Nj2&pYVxsTV;A}`LbYTU5Kn4=blPk zU?$@jTW+(3sRXFd? zL})%sCFJgaW3It#QRG#n?KlYiBQjipi1F^(uz>1%kK4pPn3wwC7`iyI2!~A9`x-n1 zWmwC#s+B!lb&B#3nPcqK_Nn~L-I^6Q(IZuRca%YZ)8!`of3phN{G4$LzcT!HE^<6{ zjwK)Y+>T=+@7T&uU>^)=Q-R-q{eu7m-GNFJYegMeMhXXBieEktVaA+@CayNj z1G(K~Z!^hX6ZR1oH=!1$V6@AFAlY2pPu*)3pEmPL!0=l1tZ#Mi&9+u?n1eo!PRBOj zYkJn#%oKjX3|Za1@)^{=gYTRHvZI6K<#Hj8A0B7YG!3VW>bwk(-t6I6M@nMg5?4RK zn$ln4(yI>+D%PIWh!|tH+^WoAC_v7Dy+%#NCiy^2UAa(o%ONC= zZ2eJD@`Ia(oYbv%hoCJoTu=t<_pbJRHMYTiPxx5(yHRG#BRBeC7*uutGm7-V;J?}9=aSQp$n*mdM2mR+z7o`?W$7$NU?qBqUNny%;u#fS~u@oRfjeRK%2ttJ? z7g~&cvVC-;!pOWYHj3fRpHg>Ue7D56=KV{@s}^mha`FyQGMsSpHsRtqg|NRC&HB=p zU;xP>Mz0^c0#5H+oj+ynYLrHKu(#eI;*Z8I-yAxF-_*^1`y`!&`?&zF5KW>|#8f>aOnj0}2^P(VuPmjevn7MbDN98!HoX7G*+e>H>h zH=(n)Jac42Ox%}mUE_t%Oq0}Ojl8VaqBr^quP|Ho`TjL-%*HISMkzkosh;DwX3ShK z)#}??!_7Z3OTXdbp62eZ%{FaZBHESD4is6Wh)mnrGQWPOQt6jP`(MR7u%j!nmUf$9 zFWK$Dl_s%^TxfBKK^xIpnn=#Y_l=@~IE0m$YF3p9d&&0+*@2yr>z->NS!8A#BDm|? z?#??nYOe#E1P-utv<1e8K*7kDAip@Y9kqrn-a;IY#sq1aPknd6yQlGkKaF5YUitkC zP%J7a`M_8iSy?@*o_MlKkIL~ml_%a)JWJ{k@@&IF3`9w95m<`i-SXus363ko=e3%@ zcz8@DoFG}|(m+tRYSG<3I3ohUtRd=yiT9#GFm{V=-ZzVJLpoe=X_}FACBX|^&)i0383fEM zR37{I#NbStd8N$TnSv0zMF;wfPKV!7;Myy|Y<-I_Jp}jQmc_-n>PH zOg?YK3jt!NaQm3fUB2IonJUI`hAPkg{Ji!iPUM)WgQph%lq1Egn=yST$IE;(hA+>k z0&;0NwP?+}l_JZG=DwDnH*am~m8&+)Ud(MCm6om|qb?g8o8DZ{Psdb^#5ocbIKC%H z;33+DDq|&i8)Eb*l;UHr+YK$MLV4=iq>bMzx7;|o&vKF%)0B_(a#g{>5MZICk8@x2 zqUoxHtnp&W+dQcYyv-a+bd!KT1kA13ySR1#@PEF!q_8x8^?J_Y?#&pC+K;0P(Sd8W z;;L!<%?gzYyF&}A`|#jUcnVi-uOr$)D6W<{GABf}9H*N{_zqh{N z3`>$v0Z#%*1io=n#UmL-V@XX6pnffxv0rr|M z!8l*;lnvj16dnKID^Cx_NX}OJDys5trY&*ws zT0P|iF`(CC3>~Tv8EfCGiJ4hY^fj$0qNNqB2O07#qHU$?r32qj_)ONcp|+I*a&tE1 zzr-p0v&#wUw*-{2MPWoK9x3 z-lyDZ8h9oa$Z8K#X_+}?+`Ezjc!Q4Fs+E0zyTLi6Bo(S%S0u~}ci_R}Yuu)?76S98 zTH*lj`|;5{<2w>kpVDsAuUgcN73#?^>rVm_9PeCfvOmLxC?C6lPUFc9SPV=8tFc0%1U*;+$ zB_)h=+XQcwo-HQ7py$PvWIBn#?-|ezp5mxBWrL!v$7Fh9VZ||r;p%+s7~$ghyF{u5 zGNKPQuk&`=UrV0tD@runCBJGiLfq$qCT13(dpCv1JF3o=FGMX%2Lm|%i7m{ZL8c^Hvae5c=b{djuNy*=4h9P3vEnqTgNknM>6Wy9tp*c; z%uLj&$><_7T;3c~Wfe0I9Xdpq6Zu49C)UVUJr#WHT;byIY_d<=*9#oLLX6BGQCTis zvZrY@TTFm8!~+0Q(@Q9$Emg0XM?LWoKRjXJ6Hs)n6PEmX&Yx>A;IY??DVDsCLOTzc z@CwL0J3wm9{}jnSqRQQ)@U?8sI(^(OoLuE(Y`5x4v1xtzOe)0B0bO!9$L+6EWe^Nz zt7?t0CP=nZj5c}vD3}`ssML3TDK6nLhs;EE7IFci(ue%r8^U=bz~@=MU{`}A@>7~M zR(N{fy?Ym)2h#GH?`QMr#4%l55{bSEz4gpa53QlSsxB5O+@-=^j$G~|%39=UO=WOI z+y0ZpaViSah;)-}{Rilqz1B0Qbld@#af7GZb0;57Rbj+71JcWsXEG=qlv%}+jnLfe zH1b@rB$f%Z(+*ivdCwQC%%2ItCT$yU*&jmlH^xpgvXxaVKJYqo@&)i*OGvtLFB)ZU znp4CE2g0Z%qtC=gBQTwQVbm)z1WFQ1%A{{rW2}5=88Nkqn}%-Fa)v{eN$(O$7Ld+v z^EOwL+lCRG6Z=}={8vu?s@xGP*Q2RkiKr55o)W$KCv~h?Zea{#rLh4I!vC>*@p^;c z`}ph7hhGOz^2Tg3soY$#3y6d?8i+usTXGd+9MdLCFg(P{?|R&QkM&+4gw8~5-nT@A z*s#e^d=NlqhM&H}#@)5FFl@U@P9lhxDt`8#%+EMORehBWg=R=Y(|+Ns=O z3P{#7hqEN(6n{SFSr1kJ8DM4=cTyd683iXpAT9A~3UQbE`kX-*Hz$WFxBYsVsp^o` z9&nTR7S-{Hm+#0L$tx?p7tMtL%H|;4`l+FA>QWs1igb|wZ}z+)8*Z+ruCDH+6r#2? zMT>g z#24jmwE`#S`0Lxd^B2j%)Z_Hggp%E}UZ>ZB(_{dT*QRJe+quq_G9Un)LoU6YB(Ulq z_MC^H@ZP8MIeG^sHyV#&pAmTJ5Cl-Yy@r)M)T;|o9uVE{mb z=s6MQ$5BHl0_*mfy~$Scx&lcfgXe9JPzdUV4yt*f4~bZiFRb^!eKuk+AaQZq7~tNX zfBW{{AXLDoZW)dkMI%wVs_F-Suk9m;LbwkQa`7=w{-0f4hB$}uuNz3=xhN|rMrD_6Zzxp-~bsTrr|L+{HI;#dY> zIDqa*K9!p@U=>mBj<)t3#y%D0$UxB;zbvcG4&o0bgMSDIxiag`Qgt7PRqv!}Dk%9Lo`H2S;q&K;& z+c2?1(_j$9>jy{prQr?`^2s0>Zm292pL8W)CTKvL7Avg0;zehcaSdI`bhwk819nqc zyE|!|5IaV69(cX)R5l`|ya%mvCFta+%^gff9_@L(JRF6*$hdK`Sj8sXZ5^s;!I=$E z3wnql(fr^{GO1DP}DMmCc&c6Dki6s2I1d_vxw}O2k3jEx$)schwiK12TbvMN-_CK;GxVXU#YMG*+vo+u(9qp zuCJCSdf`}pQpc6X0Wrh|q^hVxTQ9cl&8SKTey0fSsvoege4zAG(I8-5q>P&53zxY9 zAICpp+&<%moFaO_B59-U{+>*bhR2*f^kwi0!B;IBcT}SEwD7yZIO!t62KMh|lm5H$ z>LpuTBG=1%{#3VDgNF`1HGwP3r5OnwWGH-<=(W>(3q2*~You_L?t6sO_x*^br6!}C zAbPwv%h*!vSpYQoqnyxY_|9^!HyC*vZfxY^M79^9W_sbVW;a;ygJ22YSn#W>%lp=? zTXM!1Gv=|GV6*G=Y96=MX#4tAI3dUnGoI<=G#2kNV?(=R$vmi67aQiW!QFcM%lRsU z5)K@uz57rVt*h}-;CSM_(K%{+$U@9KW;5t?n*Fmn(>{W_j9GG=N0y zc;3@<$gif9qW8dS-!?Wn^qQ@aV62cT#*Qw6C0U|RX;~xQpaQ;wKLDDgx*e@=>=_|i zU8m;OBvw6x8XN69ab~D93Duuv&Cw+a^BE)579aUJ2zU))C`p|G$ehV{MNA%RE*->< zQXz^vrj#T$>5~D&;{G8pG&}>QJD{wD7=AD*;Fb%e8_s5${mPGC{Sg zQo_Lu3ES&}R%%tTJ?c=V*lCts;un$edUn0y)_8#n>ieFHuJ~+xsUG;oCas?YdyIFS zWykr5d;Ny6uU?ou_(}M5!gFZE20+~(uV*Q~=*C+l$wK;&P84(fAkV;z^*kz9{Ro{C z?=d%MUzIXN4dnBuQ*rQ0&7<$n8=P@Vo7bTL4=gadAEm>ue@X{|pTB;c zfanha^I`TCI0j`=gOU1rK|wb++(Z@8a;N2N5@No@L~wqI&uS2LlAcMa4!*{YK9Lwt z&~BqU!$cwpVsP zzrLY)+6lnrKNoC}H-NmR1<2gmrdy zp0sDbte^KkFDa9&;AEuOp;ho#q>Tqa54?{bKTeE(#{La!3MIedq@s-hqO(Ic4NX2f zS4&IF)o*$JMKnACPNsz}lHybT#wKAchK1sOv$XHpnXkz`V(yF@D@^g_a0h&r&%G+X4l4p@S^BAZ0WYGQ^L85Iwu}B zD=luB2)i*EVjhA~mwt+C^r-`E0&X#DX~sg7p_Y2xv@i#ARq4As-Ts+iUlo!3`XY9O z*r26{unRAjkZKlmcGld_hwHel&{N`W}suy{--z#&c}* zSgPiY+?$WX4n2~F=$R-ya#s_n=}<`fX-c}e7_uQ{(BY>fT=*qZ1~#Ai8!_5Otb;KWUG0^@d_yi8;x zFq8MF5-)$53S~#ydIgzsQx%El8?Wc!u18^R4E`9(_G_0qpq$;>(O8>W1~kJUVv8gS zKQGa*?d^g1m-LZaCsZukofN6)c17xI9D|?=03#L7paZmLy+lHIe{oOEzB22SL6rbH zm-HaSBSlwc@QA+$&Xd_H$l_O4$fPx@7Slw!t(As%x0afeXwF+AJe7f?N;`c{h$)5H z-6?ZYbsL4!F61nBWD^_voX_E9gRf9}O&t<@TDe|I2-@b#ny#ZSkyAI?Rb<_{BVVox znGqy&@x^oAwanIIrWhfqtO3D(TVyBxIvNc|RLCwwM;~N? z!YBfd=ZwIKeJp99D1dZqxsDNaw{{yW((Y*_Wd_YGzO`)~IbsF8e!;YLo_yddo0NaH zcTdF*JGFfPbl4!A4tD^aV1Q*Bm|4VFI?QjvA2&}q1TC8mYOm3sT-7B%qTm-)*nY63 zMkBAkK{EkYLk^EODq%-B*CP<{1LrRni^8lxmW|&dpL7}9vVTPr$LCNDMm5qX)=tDI zmY)t4IAZ&vEdF+jZ53TC4B0J;ed78gHxbZz@FYo`Va}ZcZ6Tka6k*rT$iG{|9Y6Elz8ak{ndio z);axytrRL?cCd4@=8{2EVd2F*fJtQNmSW23ZO^<25eUQ_I;x|m72M>ZPCnKq>oyrL zlD5>pOt8pJ@x_gG>lh4%)p*Z}fmgXqp5nD&I)5Iklho=p9TB4B`n@(Wd`hvY*d#yk z!V@NkTt;Le5d~J5hT7jO1L~e0uN5nCA&x7rGnjdJMcW0)$>JCmJ?hA1Y2$^qzWfp2 zkDH%dQ>|8&nUn*I5Cz&;g6WL`Ml4fN;fRbG^Zv24(I8(Jty$P~Lg@#`%|jS|lC-Lt zY`zp0KHPlCeHzSJl2~&@y5ELW71?e3<6%9P z2W`rO6uGnkKVOO*V(8RfJQ_Kxbl{g0_L{_%wKl=-ORDvqy(<8zH0^onuUquZE6xTY z1|{5*^Yga9CCLdbv=u!PcQ3|mgSpD{;=w=^v8GSR0Xz_nVqkTuz2LITJNsx9>(hr1 zQ@3TcnZ;Cn9nvwT*fRm-ElMgv;dn*uT{t;WSPme1E(9`Dcqs%RPG?RRN%39IB{Uoq zlv|`Xp+rjVr9J@?OufZ*c0Bm9cA>0~uaO5TU>bFBe?|3Ij+GYN!Y)Hm*jLv{s^|^` zCU(OpSpse!hoTCtFi1dERGl6FN~zfa`q3zrwzXSa#S4@pY5OWIbb5+{RyTj!bB;$e zBT5u{;D%gBH(*W6hn-QhUeMoYJ8d5CZYcu|Bm!jeQW#Y6J<3=%VuU~vP zpbg;hY}#w35c35ZY@MbscaG_qr>8ec`A-{%oogKY=|g$;8ShsXg(`?wbJ8()(Z?8N z(@Um!ft(=Ar4d-7Eeh_43VYR|aW+2%1q4Kd45l6~ksF;d^zYHnp>;ePy)(3xLmZ1^ zd0Vq$9O_oX19hT!AMq63sMZ*^>}bj(FHj)BZ)KbN2nkg^Ox~3!x?_*SyhAI2d`(CB zbRv0siQi|w_;q(}0Q_xYN8@6iAw2`ASER$buA*-*63giPy$YivhvINHW*R!#ouA~u z`Z>v3uReI%2nYLli%JDfl9)~e6Ct&a^@vuO5OBK<&zt68MC9|(ree1#ZFkj0h>EWQ zL~t_Dv20U<`BpXm64=n^g^w*8cC_cujRiMCm1R=9uF)9-RZ<9u6)GV%1|}G*gnVkQ z-cuU@kypk!e*f*uxP+7^!oy9-hHzs;mDW$2b%YGun{U2?`e4y>6enF5kLBd^u{^_h z1%X}P?)s!dXThSoiLo*WRA$v24qo#WC2tBS6mr+ zXv9Eh5)+|SLZqW-7~|hj=xh-qc-Qc<_R$IKXaFn`wi$vKM_!*30071i9#ry)a?lS& zTpF+W>;331qsx~RQpd`#Ef!V4proQKy6AxP3i54luRg5k1x4Vk3F>>7(_&|k^StpD zZeHVKiGC!E)Hvnj4a-~0z`>e=5_xyP4CRr3PaS<;FDAn96k&hsfm{z?wryMmYyBZy z)(@B&Aa9vwM2HB2i$9vuLm#9Wc;x{oQ}mZFKVx^RyYBEv9hGokdM}m59QG|Pa5EUp zT6?oS?Pm$mXzhWB3~`N@hR5@0;j3wCjBdt6rMy$-4w*2KNpb zs%=_<4`+)J8j_0`%EFWK>$26)F3tHefH~CnnF|rUL^-apD;6C1T+Hch=8Y}ZQLCx=VoyYIb4-}E7?qsAW`s64cS%_S1&;yOOpBKzou z6Rr>XOCA=7ZhCW#w{=T97%D}hW2`gN>?|<5_v5*3NPhiQbps>ZM1S&QEKr*D_O%Y|2?%jti5N@+(#Raao zGXGYeU;rs0f;|Rw{G|A+H0J?gu8$b0tJMC;cVbn>^t^_@pOoz)z}i=XT97!X#FcR| z3AvYw$mY9#mGY0Hqr(a=nB}~BwZ;ubmdIlSTUma*hju|9^qda>6L0QoWGn&8SMKt% z#dW$2pC0MLr@l%OxroNQv=1CkzuKvXictL)|D$~24x53; zoc>S2EAP_T>hP_#^&G~r73VvU|3yZQ94WVE$SMTG z^<^Jc@Gha(FX#N3&(ej1pg@{tbVcVaRxcjzQb+nmdod+@+$#DpEAU6^o)l%dV z&x32CZd6OLul@-qj6pRIAq?uP5QCQu=Lk>{Oy=GASKbTBsTU7qKFz2=+7HQ0w&9|p zw4vnt^d40G-%FNGHWy!pQ!gsDOi81Gt8cZMneQ=-m)9aZwx+ea$lC%LFbZ$Y zmstuZU@0QXyEye{g6uUS#m}y;JMisjb0h}defuJ^07bQDtdx@j)xa16aA~ka+@rF~ z%XiZbdpqxSq(B6@-Jig9@C=>(h6u4e1dqt~lw($sWwXU4vuD}BFVc5O|L=)iA^A6a zfjxYmvFt8<^k^nWD49>F?zQ zKjCXRPY;=~7m+~TarpRH%S8r7q2z^#Ycdszk#i^_^RxX~D0wa2W;JdWY}j}f2MpH*@<%fHm zc4|Dy=zM(#!_+(sI-068*U%uII#Lk8(%__b?&lkWk z&!kgqh*MlB_|GY>1A+7`lFeuRlrk27JJ~_m=vXi^IDFwFoXZb zxE+*)L?3ZUL2c&;ikU;3VyB3#zj<$Q1G>|Je%DNa+$6TIUn48drbBYXgYjl$F`4hcB${k9Irgp6pQ zgg7IQKM=kDsouQX%5d>|6xn_1WxK))<~YVv0QR26HDV8nsQ!QAk{;7A`7}hD5R*%h zg3g<55n;C3-?~hBp_?mJs8sN$ly+jY#8OOxig12!d&Z|fz^MlSF^fByWPAB77=ooLHXiTnyT&4PV@35n-%?fYB+QLejc-2$PK z7M#kNEFFk;8&A^7wo@*XT$Sap?}M0{!kdJa6_EODy9G30VYJav?6JwISJldM9}_6D|8hUU+5=eUCZ4fDLrL}3?y3#FQcy@WH$+Ee#O6_;HTV0p&! zhQMNP^^((*oHI+ArdghIu~18HyZ*rQMHn(u&Y_&h8^yW}YR5hxwL6cKU=K57A56f} zpO&cY>eL;=cHyJUyTo^bgC(J$Ku`J{2SEiU=WAWf!;tr^&1*t@J{mb}&UQ66u#~mo zvG#dH6al`n2IG;L$Syl?#wuSrFZ>guN9y8;gvQ0i)jshFim|4y5&!e6YX8OLX&&*N zw&(%#YpS(KJ16>shsKqYCQXXa1SN4AW*|2&p<5FZs-!{<7VerKO^%HEdu-8WEsxE< zO0y=my~KgeJAtz{Xzy#u>Y&JUN)s|(#dr5~gk6?$b$i@kM*}Q3Q+CJuG4tDiX35NX zu_bsp3SBeqefYBX*zcW%;CP-TIS_5J!(4|nS5G!u?s~n3{4M)%8RL}cpAR)6EcpL= z?QX))VOQ-5tb;r3n8CxLoCkOwSAlXV4CrY+6EOx4nY7hPi91SPpWZ%3oIxW==olX- zA4(GDXP7}(VLL3)2Vyz??;I5;V8>Vi~4=ixI3yniVcWRJaqDSvRQX|`S z{W+zzjO8fmjlQ}(({S<`-p{|eI;Oben8f-xcC=gR%3DR$&ZWdQ{snOM@M~&P>ex%FMZ640# z!atlIgT9&qMteCkR z<3Vzmw8PLm&>G23EyCPk5u^mN6Ng>Qy3n_s(J%qyV(aj-X!b-TPyZX)od%0AlR94| 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

n>=h4{qCmN#VctTgAPJeiNV+tTL4_$ z%=Tx|=cVu15nVd`MGxk<{yB%PNPj}*jQ%)w^H3XJ+|{J;>!I^~W%^Q%F9T7p*dEfl zL3k<{V**{bY=`6@>3nFDl58edp<~SCNq<2dpwicrEfYfk=)UhOw_If1z%k~-wk|DL zrkU96z=aLiIeY1L=kevm^L}-4LZ_B;6XqnD(Y>CG^O}azC%2nBCx&3O@NAp_P!mU) zp&bv7EeTV6KtO)i=2!DpVOh|D8w!R$xBzz8zW{T;cEOmZe`lUBj^i$Zl%aQuE<~F9 z^k-iAPw}sX_iJ9^{%hwOMir~0^{&WWqDj&A>ColMrtF9g!ig~k*{^;S(#39nYojZb z@vQkZO8m{mcT_#|!yFt1$U0M0`oPqnsvkQqH7`A;ZCbd>=f|_5(EQRkWxosO!@TON zvK2OIrNU}#OYloNBx5@!6RHJ)+Q&@fj|Bz<7y^DDv*q0-f1Q{=ladC#zEhQG#hpdL zxsNpV5cj|2hi!BA9($kjNeL#Q8K^0qNu2+Op7n3lpt_n2BVRU5TD|Zm!Y28ZhY%B3 zp$Yl#NPob8iWw5l9pNXFwsL|>3jd3s1)C~$7+Y#kBurE|2%3Ir^PA78s!mJLjF*!{ zt;GI&x0Hf|{C9X&XYp?z-rY!}hx`_Gh5ESh#AC2|sHS3(ru?bmYYOF<QrJ+)s8R+l~a1G9^3|r3bq0FCzt(^50*raGssk(mr#b<<@T>de_qQA754Ex zm^Nc-$3BgsV*&`7_yztPi4mX_h*~w_JCZ|;3Gfgp0du=o4tFlFRj-;! zz}iqcW_{(wE;+8yReUisZkMWZ!r-aAWn+GZ#~6Hy>4eh66kGkDjCu~G)3b!n^EpG4 zNg?%#nmAvLHeXutWx@eX=Yi*3mR(&|nH8}Zq;IBI>%8BH`>tWyh$7d%{4KSN7_7UZ zRH>EFWBU>yPB5GdCCHfK+q7P7j=x_htB1S&{D0Et5wE4h(WU-@4t=Kw<|`okSS56H}{hX+&*-xl(j%I(ue-P6Ofb zInW(3-c1a^9l~Ui`;e5jFqe-|>G*f7()=J8&U*5ZG~%1mq1!h`*Nk9mw|%*GSn0yh zhx0kR$VLesLJk2k7s}+f2JUEw30C)0UEbLw&kTD8AFaZeWOx^)l= zOh@^g7iJhLC3kFJcL7C>ArJxWsIGol=;(+IEhv|3!mbnp+WP@vO+fOf_m`|W$$=V5 z#_^ycJw(F2zUk2? zEEU#rb1g|dQ1r(?wE5)llIvRVnaD$45#0%dpzwCcX%67o*SCk8Wm|)lMsD}wwQw5j z2-$jrFDrHs4Qj>GMF3+7tHq6KlzI-ec!bJ`W$Os~vrY_IQ*g647=*gNbU6lpEX?{{ zJiD`7NQan)`0+U0I%Uh)!@IxJj1hFFe{izqI9YH~57|OrM3eeLOvpOmm6*6c##;2d zO2s?f5P1~T*61Oe%k2=IYJ~_VPjI11UBi{aQK3^a{Q&>wL?b-zs2>6tQ-4?jundT) z6LUz+e=Z(%+RgE!gig)#gT%oI4Rt4(vq>M&no}?xO+45l1~@qkI?YAB6$);=y5cdn zb?1*$%)~g3vqriqFqHZ!FUYvzE0#;eCLghMo^joY;9Gx&Lm3whE}cU;{!gP#6mPJc8~?WW5tp2%z`U;Y(~_j<=CA0 z27i}1YL!3sh*kcE^QrJBZ18`0ihq$c;m22KYSMRMjc8Z$O3T*phZ98A3bVN|E>ZuH*95aknj7wd;=VC)z?jl3^5zz79Fq{lg285utn`^qW@>fX2pQI(xvrj2i zSjtfs52=H3JcTq>gqeeQlSPf(c=)04UqP>9bSS*Kp8c)+V5WGkl!=htWmHG@USVUN z#ZVn7w>au6jaGN1xqfD|O2@sG+1m6nXY}N5CZ;&SWUcVKXe-R?q%cQ+pz+Y?w;Okc zr{b{2mU7}mfZ)d%pnA#OFQ8as{9$r(mdny<{V1FGS7G%d$wtCzW2mG$VQu7CzsLVD zkz8Z#S`Q_^J$=tJSB&ciOVwxaHXSjX&G8-i>ZYQS8sfT2 zs0P^;Im)Oh3g%ZjEG!3|jRGQVzGxEtj&{>oI5@1D3Wpq$71ge@JgOx=6d}oy|Ye6#2r~jDD z7j%hXjwx~~^4OPciRh6MD{qV^{ipTzoY@M&VLo;ccME|VC4c7-oM%CvF>gN-8}Si` zrb+QK?A*pocZ%F7VJp%;Q>!G&wqauP_UYNhM*(`r?ec(b$Pp6oE%D2;-OdLNq$WiH z?)|}@0eDjZf@_cm^*jd|-M4{nMH;iW83KStqxV+onn@M02NGV8iCTROK*^&KAVHki zSq@1BTKTB_{x>@YffVJoSgYG09K=!nG@3ja$2<$WrIRozFrIKG0#WnHrZv0X+k(`) zk7_sg4^QsL1NTc1{R#=*ZMG9ovt77_m`Nz*bpx)!FlT+r|+U3ECUx&^P3E6)=56esMm?;Uc9 zkf`BX3Hsm4%P6=M^|#RJTgf=N4d}dd&nq0almL{JbvK3|UVfn9xlT;2B8vNN2MBD)3Q~6|E)D6N<4M z@NX<%2_7SL;k4n-=Im@ap(^LTYXbkmmQ!>GTF~oFdGyBM7YQGa<8d%5vbp{(X`D}C zh9CIM*+GkVt7zHkQfz3AEx|(w`ch81bvs3?1gYya<=+$`u5e03Kl%w6E8UX)mGDPV zGA4&)Su_<@H9@9>wsV4{--eseMYQKl6||*)g;>(qw7nkVMF61phCWjI@#;wpEGfzl z0c$BBICGHQ4~Jl^dd&(*Rvaq<1K-2f=^Pwa1B?{8x35%Es;iLJk}ser<-!}6&@yzQ zTKo^Tx|A!5q@obcpu;E}g zNT+LF5te0LpRo7%n47rt{u8ywD7$Z-N_51o7uqVgWFx;Ts1^CZCAf=>;OK^Q9ZmIp zhIanPdLK;1kmVlVf(uiZ2vNCf9N8nTIJ(`ra))|kuqMzF&=(XqJ1|;BZ+wB-=48s5 z^Hm!|Cm=pt^=cqpbqzqOUN9^`74a9iMhNYMVrd^qT_=kUnro>7gmak%m`-L1B`MyW zK7V7WqI0W|UPo5Fxw5>>>#G}zFx3B4AgsngNhA^AB4P3yDnxSZWLEX%Tk&iV@p1yF z0CeUWu>$V@1ubu}OskI9kR&>mE6aKwt2IHAC1-nVLCve@pu&Q&TtXJk61bk=pLA^< zpqN%ptI(ztNSrTP8{-7R)#u<6sb|NZB4uj?C@|56l? zVsr5-;)*gykuXvOu29TbsZ5nQvS>sZ4uma@Wue~Phy5xZY^h&PtlaS{WRjFWQ#0+x z4s*thzN4&K_$l>!e0qJow*M`y$`B3Sp`1MxnGOxArlL+9IPN6BxuQ4%kJe6#=lE1Ihqt2J z*scRx+M8LyD~^ekIVM<~kKDf0Ix4>SOvi;!-!@&><)ZHmJby!Q1znjy%Z!aZNN&lL z4sfDpUz#jIC|XxkZ+{;fQ%lw{_g`cnIuqB5?fz#^b>g5{yNbZTMj~E znsbn`a6PeYA!FO_W?KDCMVJ(UM`WtHdT-SZc#9rDi*k2@388Wg14zIG>+EJY z3g2YwlLlsi?P5>H3bUDEzeAq?gANws|K-Ap))gx0o( z7L-GJ5x`t}W4WzSw5s2Vs{&Jh9}#FF&K7{>-D3K5yPy(>%}c zsk$7UBHlJPy%A*VxIJWSJ)P&9dOYN^$+1rxD5Jm}#AmTE3s`i8QzP=a!0iZ1)*ihywQeF@};KBfYP zIO-zRG{9xoSk9PDz1O3wbfNIXSC>+2$y0In81o?o01(=PFdbVrmbvzZ&-izu!ti__ zFlS=uw9>;HzL2m8@j#c<{Bj@ezMF6s_8!^2z54{uVp%P4j2;#t9y^rMLUbm_EcnQn z^JFq-2{6geQj}N>$XdO5Y`lQxR|H*e16_$NJ83LaC7w7@(KkyOq?*Z;toU-Ws^uX8 zI+0ZwdSs1t28N`*x!d+sc@xLPp-8xz8+}!v6nYPIqv^A*`DHKHyhYl|YT-KLAZK>CSO$(|+ zG`j|v#r6yef0y_L29iHD%5jrhUo{o}L{93@X!4W6g>N8n0cs*g`6!n9Sw)?%wFbZ- z(aF}hl_cC<3aHZ<0V` zO5U^sCO|rj?fu{CqXPZoCfHO~8ORZ9G!ktj?~i^tn|MNuuZi>@RW?e9at?%YEUA56 zf%9hgE+lftra32>9C%Q)Yd_&#VU>bJ8Siul)am)UfaVKQ)R)(aHAFU zhxLboYbsZ*W}UeuRzQ2T5ipR=0dH(f+T_^io9MxcBGw`c)I~Hfsp}}ecI;>{E5buA z8RTl%V=PJK0rK%)?zz&Ia*%`ST)6l{M4>0AZ=hHIR}}V7@zD5PpfxAZ{scYOqh6Rr zi3RI?UA+O+r|ND_F>=Iu?HlE{ z)NRiA;gtZDPc7_?vq-S3Clfqm8kdMaS;G)9Yek*+^y;Naz3?1p|HKNhHU*;KTGYGL zo#m8iQ}ud6-UD8xrztqGNr*nl?MzCf20Kf|*$BG(TIe5W3&NW;ZurK##4MjcQlj1& zv(%cVg|ie> zTi(e}hd!O1&g-ScCcA(|0IEAQyXT&6ZEnCfK*2j)cYB@G@34N>90D1|7CCW_#`bds zY-Ahl^xK&pGju{ZecC->GMV$7);0kN&m_c(isod%cHMfcWo^^WziX>z*|N+MSl3vJ zfy>=lLM%0Ju>u|vx;iM=THO^xBX7J&<_NWIo`$hQ*%F(^RK?YY`|^i1pFiIC>^^Zk zcR-OixJQOQ*GS}Wk6Z-?1lj}i>>~%E5pJrFeAvM8;z-T?IJFQ(ND{aKu2@Ggq+pK- zK~SS)5rUZ{E5>UjM+ep8 zF^l)+K#s@5xSD#5P047bOc*K8(k$MEh){?3fu|bTL7Sp~=v4E2Q zuA@|pzJ)zok$vrB(J2K#9I71A6JX37-b;36LEHV#MXlzUC)BOrUV-bEox1+_TcIks zkw;~?bqPWKL9TrY(n?SA45C#9C~$z(^!2+w6kX^^UXtK+_WPz~TVX?C65+wS4^!60 zxVsp*yhQb>y|W{urBZe&V@cT+d&@x+&oZ~)bED&01f(9#3oRV+TS$kSf4e}Ze7^-D9{k^Z?RW1hMZZYR=CAvsGI!dBL)$S75zIgVG$byw*pbNuQOnd zspE`%l&|u_i7)0+L_KTEB*&5it^R(4_KugYf*J{PaSv{#~ejWA>$w|GZi@<5L8GZ~^{p)gG((5hFml zEE~m3dTQ!A(qf?OErft{KOugB%2y4lp~+Bam{??oc+UA)@fBo+JZT*BVHP4Sd#g5b zh-^bcKFLV|D~Pzqbb^QCQg87)$X=Ka>S_KQ<;Y)rd|y==es{__iX*F+`7nXM+3JR> zi28u?di9tR5{hUS)kU;KDrf^jb|31j$Z`^TGEHPhv3k>RBQsvHqwD-GYz3r>ydu{4 z+m{g!04J%o*u{UczIpnm;8N*bEb5;Kp^=Ihj&)^BY3vPqT zqm!6`Y=e)Y%$kJJkC$|F)~5ey{-4M!>A1-cbd;>_75vw&iKf8$xD~`X#CoK=ry^f7 zN`8P$@*CW=c@L1h`a1EvEdMLhhWDQebX(DdmYoO>OWGSDq=t{?Q3pq>+(-!sl}Ql7W81EM9-ro z?Aknn@}Mr9*rt>%%_>?ImYALJg=L{~QBg?uNJ9tok{^hW%Dx|^#=K36BMRYduK9DWC07C9++Pq`iZ{9f%F+Q#NjNOXox z$U@mH%57*uoEygWwdP!)6t#C?!;mu-#PIOV+Cd7OCsWlIy@X)zoZz-!mDl4xxOC~e z($j}%D)sQDunCDXv(`8%r%qHxBvwQ$0r%@3mbn^0I$`g*LKo=N=L#yLVnb#vuP%E^ z3gU`9k9zw1nBp09Q#$XZXVU|8L=@>?(@^RrD_WSVWnENoTc^~5UNpnC%ZQwf)2O8D zU93D73a`*BYns!_(})!X!c zV+8*G1{zI4ntqokS;7ImHmdMhUWx%;n7q3cQwS4J&-8UwS&YU$`|>x3jiSVkfW~lb35nDMsRA80STPC}W{@dMjksQ$V zdGUJTjqGnlpgsEk4c3FqHx1{$rHfmp2Nto!&eaI5AqG6e+l+`L%iqu#RkLN-Ll`1| z>sOjsy7${VrcERBPwT4WE|psARu3)Icti|eiPVVfeQhM0o5>$XiT2p6h3s2boR^b5 zgp!nS;oK%C+ka)tP9Gb~pU&_sa}i?9IMaH^`B8%X*MT~X+a*KoN{{}N>ggoa^M5(U zk?OnQ?G>{&uh(C|fbx;K*`{gH-H0h@b)4DMsnh405mN{v87{tPEJzojm(oKt=`I7v zRm+1t5*wKhZ^7$rz8EApWN|YBu@O>6eaU$VWw98_pW!E`3(K(of^QTo93KW8nJ3Sm z;1bFD0CCrmFX^n){$04X~H}2-Gqz z77DOFRPHS#h|cCY75yfer;?v{#JvXnE~}K89MO93>wx+eT}JNd&am|d&k#h6F;aS% z_Khb0=g9j0`Nb`8Exb#JHqK6|%dn)-5n z+E~T}!-4tmVOhR(OZj8>A1;DFk5i^lsqD=3iwz(&=Wfww?1I9^0R@lSqGA%EEEo&5 zgLXax9%_hsSvx8P`&!Jf!l*xT=RSjgtxGmJ_t}xXRxWu&zv9|h$mP%rnh0wU@kzs# zqQt?pLl)}=tNl|kM}wm}3HWCO%P7Gp;NdlXZ;BA>{j}KOoNE{bWy?8|PC2PPZQBjj zA|Tw~sutOcC=HxYQRdR5SLb;XSsak_1CYGRUf;pq+}}W?4-F#Dpu6-i;u8f$?ZmA9 zsG5;}nkpnOHzUA{=r=rw-PZCy?EIOZqQH88_!N`Cp|)&JGsl0jt&b2H{DFt{no&}! zXEBGdiVPG+k~@~QkH(m>>)I(-Yy4 zN5550GVp=+xW+GJ|6=k(7eP)LJ2 zGGoZ-Z`OJ1d;16>l9Djfkfj!Fy`>5nk|^zzk^Dg%{NS_T1FqP^6#fEAYeI1Z9HDZG z8s;mp;{t24CTcUR3Y6G@>7FM@+({U+L!!aT-RS~qi~RwO78+Y92uzo1EatQ%OsbX( zI!)NG**)<2gpSCIfrFMew$Zhfw@~TFwt-H(R`-+if1)_w*K}W%<%u=SWCs9XPvEd> za*N6!dRS>yfmSPW#7wot3Q@#eLM2~4mP!9Kq5d}gqH8^uGrXWQ7}cf z1j0_0k&YemVwk_S2cDPl9*bSCz!7_ddOdN=yvJurZ{hg#yHs?>fHgg(coyi&A~d@M z5E+{G(xtmU#+xN@$4;>3QE({tH&0@E$Avob`&!>1($#lGN4c4q9;WD`2#Yh_soY7H zX6S@Mx7%H@vJ04=QB=GL1B(1E;;e|0>+R$jN@gtUS!L-{K8&rh}8h5F9gB{g7%CtL}(jWb5#awr8a+N znY42!CK5(CCiOx0a=hQqE1)T}T_g~Y@Q)e2(@R|DjlHdEY$IS7(HIh&K$uC`;=H-Y zOSoZ*pcwjEnzJL63?;JTgKIaw{Ds2uNpRVzk&t7jwc-TR)mDr@Ruq!8_y89FUjTk@ z14|Y~oJLYf!y|kx+@I&2@WdD!vFeWYGt{}*C=clDB@XZMl39UrK4cXFQqhr+&B^0$ zla?|07m^&o47UK-oCLES;;>jAc-q3UNrSED#faCP>)k79xBYp=Y#AaqbC}0dz^0)Y zao`VY-;oj}7y5hSMBt-kT=no59U#WCz3dm`rhDJ^4|i3G=a|wqg#^ zH|0ciMc^9DO4dxT0hCC5jfj>W)G(jptmW?QOm|jeyqvO<_#cs*JtJ@GL}IpOvtn21?(;6#go9Bb$6|t8Z zuvf&NUChk6!$+3b?!%>`=r zY7ELeWGaky?&Z(4P7piY99`+|r&Lktfa?t}58SV7L2K3N1~{Hgg5hWyUZ8+&c}e|G zTF2GBvojjZ2jXU%*^P#VS~aJ>GzVmDo9fgUG+Wi!=Vu0vsjFWF0i3U1q?~PkT8nXN zZl4MEm@KHh(jklbHnFHZ{DS?)N?^~5|Jrnn;E@OCHs6K+M3utw_3BmjyW@9uMY0aG z<^&~ca@dMs5aCKhVb@bOCH`uV`4)5OuBdQ&u$QhTd#qmDvOF#*kruN(9<88bi83@q zZX34v45oSX(UhQ-PnmJkL+u9HgH~HemWea{i?@~5hbBi|P zxFwkB#V}WqhPp1xjHQ^P!CnDXa_%=8Ti30#`u!h-PUiL~wfRWydnRQVQ{RZ>t0q2U zkEw#}D>f=bq>arOMen>v?B*!eqXEtRoCP14i$))ioRZM%y=!?_H@0l|)KA+u54lh( zxt)Wz4t(JFbTrDBqLVO-S+Gi&6*_=w&{2G~Tg|J|nFZM4i%K~>M9R35MyE#1AtoPe z^z@$o;}`Nb`DNa*9^dSJwZ-u7Md}9=%tOuhi0K@B5v;^6?>9fSVrk6si_*Ks#7b4S zJzcgfF4j-)PiC4eu|Mkl|LtZJKNkjPyZoAZ1 zeW@9uM0$uQ`Y(<2C@KI3?pmTelqKh%AEzlXKoywdw+oKfXjP*;6>9$8nSQDdLZ$2! zP??rp)f3;?y<<)G<12W^R#cFq)-816NQwWHp&O_AAuhfomzcUZPOWc2xQ*Vdguitb zx;JtS`3yl%kbNfBW24;s81pKke~81-+!_;Hmxkr~0~NIltv*E<1`N79x&I-75=7Y| z%PhTiw%N`(pGb$%41Oxdor$-0M~3X{(!Mc8ZJW0aJ7D8)+q+}cd>@x5Wa&6h>}~i5 zQue#aoAx!Dcbc6;3NJ7Hu>r^oP>gS|+#l~_!z#Rrk@e6UP^z_!%dEl-iaa^wN+g974+SnmtfAsXg~RC_3?+`flDtvO2JSdxN&3Gx!7-! zAOF^ONe27h-h$vmo&m{G;d)PK4kxc$UQO9nyisB5Pml+XM{SPeXBp>J=YOH^s*dXAXMwW)KwG{;I4ERBNhF@*!zT*ygrXQFYyQqtq`T-T27tyQqc`uS| z($#Ky^pl92H_)9<;tA$6*0FcON2z@g(7&BZD^B%`G&(n7*TXJ5`@KH;N_Ge9?r4UwrRBw%j(ISFNttdDy1Ep*;s7>+cgr^sD) zWIf(Srw{yXnE#l1J&|96$Tf_M2=B%9Q;2>IsQq1@UDy_U2VpQWeO;_K$<=mMaqaVr zc=!);EzP&jr-XTIiyIyQZuG~uHwZJSAaQ(~r2_*jB8Qpw?bsh2Z}#8o&@0foMZegO zXzJmFZ%YWVBlH>Xi5nQ)gFM}KEww#Q92QpU*jet318m;y+_ljOGc-a=LB!oumMymS zflTUM=HEKCplfZ{rsrByZYe1@RmQB7nmA-VEEU`uwy_9z*j(Bo{krC*j_ z_O(-LA-Z%f`iwFa=-s-9NSTP=ww8FvqnF$1Qj)h|Ke@5s$vSn(*ws{YCCpkqYsb0) zU2b|v<;_^I?gv4@tRe2gm^VbR!7c#L@!|(*_ZbQu8uS3cx+lw?2p-||JmGtM0#8o* zu=qUA=Q+Mt^{mkL<_hjJl#`Ux)aRG|YVYxeGus0x*AW)}xwVny8AtfnKB(AKWL(#) ztHf3dqF5P6D#mn~WcPcz~l-(d@yjU7tmJ*c9t1hXE~ic`$NpXut4 zJwfw|dP8_X43D;3-4Be@^Swq~s~)37sym+N_dd$Z1B?Tn87&^UZ`^0_F0Y(Ze18P94^h#`U;zA?=CntFiUjrv?&S$|VDakcU_uKrRpaT@7$GNwEpz-bs_*=IH z91+o#muXDiGiGIw2xm@;c@hepdClw1bSTzE^_{Ie3BI;-=ho?8w|H)vJ&JtrA7ZQo`o ze+~Oua;YHpTx-3ydwb1C1I{dTN)XTLK$FUPevVIH&nlH0Bn9TSNY;^Gb5Qdc>-DA{=NYfzyjn{vxieC9trCK& zOg)R&Mik~DGweMxF*`Oy zRO})E`dKND;vMVQ^t^x|w9v-Hzc&E$QM>yf!P*PRk0(|6(<^#)71`N}?>4U-FzIf= z+*G^EQ$#03$P@FZ;0S!fc!t*iyFjBHK1W6%GpMUXP3G*nC&Ig=2QP8=0*ZAwx6rcc z66R(`xQg{X13B;XQS1)LflV%dVV1RJ_f7nQ-TNAV-qgIy_teQPvUCeA>}_Vq#NV*K zVfwY_$PI;Hvpcw)K-4dH+?SZ;jajHI7%<(7-s?R|#JWiFrBNQaRVO@DehZYUwgPxa zwL@1pcF;b~_N5$7Fp5WA5~C)-dj>FHcGcu2)Zm$*JJka1Y#06WvOx`saGulg(9^G% z^0wTR36qciL)dqRQ{Dgnmnb78qEbq7iX)_G*x8QFIgac~Wn}LaiqMou*?Sx-Wn`cWR8f;QqfSkB>b7LOtKpAv{oD5iW(W?Y4hi4dG|K5#xfb z#1jOdBfJRL%3eMhmI4Z05Z+F-Qu`6?D)U*dtwX$UdMwq^=P~dN1`v9eay4^0=IviAh{M9fpn@*jp6=*a>3t8W==8Ak>E+eUXXgXTM-WE<kK{0OR81GoU&W}+s0~&ggHwni|Vkem&nJJQf|V0!s(J=0&PcgoIk)=qwEfif-*{<>9}} z{Nsvi&?*-|;P}uV`rUv(Ir?Wo$?s@;0!cxoCX?QiDt)l&q^6W>6WyMHLcUY$FF5N0 zIn``wmFcnv~CbV^Sw4R07{=i=UY&*jZpCw7Pyhv zy+ezA<2kr$4EUdvkL*a?1KHBy#M*Iq$}|O5fnVp}M+oJmHgymLkdva$;K9G=d-cD( z>M4z7cMolitNC;+wE8PR46ZerLgmIZuEh=?xbt4%5?tCFU9Iw9S~>~Y>~XhNAT{A= zgWD|+v~q+hkb;mRaxM4Fat+IcH;eX|N2WyPMb*v$1{LA+u;9;+iGf4Vh$x)R!H2U% z)rR;5qIP~-$9-TGMXgKq+^6LAM@XE8Qak>%(`dAccx5t9bfOb2OhZr6in=R$MM-}+ zsfFo1_~1C`xg1_n?D`5pv8D6&;v-9(c7w!67;Owe)jx^}U81Qe>@r2Q9vT`#EIR1` z8E^Z9-M#g^ua$cq$f$Zr4HIp;UwZq)gjVaT3{-XWJb z=f{xR3UjX$WM~H&;H=EcS*^`GP(|@43Pt9ft1k#Xmfr~^2KyL$eb#r8tpaTwW43c& zMZ+BAUufi0RB;i3WD}=;e5$cB)u8K3* z@jm)>u7ZcPjPss=GWQXuRJ1yPHa|l{wvxQRz$WtCz2AWfKrC8}F<^-vCNfM+m}7*kp&$&nlbWuB&M1+Q`@=-%QP48ULHGtg*;8+@ONyepz$q5HM9r;*~K0 zBvV;Kj=s9m*_-q#Ip#VrPaQ>M2;EfRM+-YcMZZ5ORQBy#M?6}6 z?%vYk@=sjkh{3Xqq?07-_$ER(ob_y|cM2MT2Wkc)>uGZfFyhKZfww9uS-T%e+2%G| z&@@E>hm!s4-8apIL?8NKG8%y3pb+ENdK; zr{R4`_|1pQB}A=>fG<}|e5hNvy1tl8B5T50z!xd0H9LEjX7?;1SRTmL3VBN59%L!o zKpm6>T%a=8^*Ys-uicIoc<=5P5o`#BR@Vj^BgOpgP_r}`$fsD`X83!@Ru7n$6^&En z6a7M$r$qmVPy@9~YE>~%?N%TeeMCK*hw>k3oTBRZJ7?Z^o7=^+{i#!PK#=DHmu{%%LNK9tkdHGc;`UKSwhiNZ#6@YV-HS!heaY z!~6as6-6PL59R1U}UOgX+XK?qj-+E%r#(A_`+$E4?efA`m70R@D460>J{# zkvtOL1CxaIK&4=?jyw2o1GWUy&{dL=_(|m-p<^hpFtw1j<;0NXs+>D>KAFU=!~&@%~O( zu&#X-m!UM~J4+R%PeD6zRz3l0N}zB`q~vj~|4I&&W5n?QNr4m$2p?1o=4i(q26FlA1cDq3 zES(}c=BYnGGie5`mq<_4@1ZS(kQXH9ClEL1T8S4@0(Fot5YBHxqCp+@GzaMk6AOBd zEtf#Y%O>_C>V&D1@IrTURoLeL&fCOUyP#UAI_;XVZZ}9=iqiPJM04|;EE3j$maOM{ zDObjeS0TnEX*$9g%<3^+E5kN;Y0*)pT_fR=ag*O6U!kgxrxGt8jq5G?`ABCF_G6v_ zou~<@0^dhbwMmKs#$Cm{zIj-pTCafI!`teoBDPOdjnA#^Q;k-CN1DRVyA|Klu}Wz+L$U z7+6a{aeq>i+8c%A+@MaSfQ5hC#B(GRPwLvTeg9RL8m;+%>mDyv zC^%>dx7M3Xfl5l55AEW4Sog007GZF&9KpE@_8N!XGqK=>aBc_^i!}`^@bwP%@ym!F z+4>J#5uTiv7Gn+51Zig|Q_K&IA)dIJ8~Hf;hKyqi@`)r-5;p!8Z2YzCcN;w`1S2o# ze5xZ-^Fs=U3qCa7?6xU769$j&8xSVl^@tZtprEUA)uVcfnD2mf=1(HlJEWAz7FYKQOm%sHhA(9dl zw&wut*UQ;vc~E+2u%$30UPIJz-Je~4i*&VQ`aY@{)BcUx^CVtOtSODFh?Z-Hd zd}4A~U`To{xdnR6udvbCqi~!+_>5*&fa4BgpO}6^9J}FZG&v{%;IWDz-U65gSsn0H z=4N}N!~t2`2)mszNQ>H{ctW$e#Jv!8uZen=PwZ z#|s?^-*v}UPG=*x1L)9vB3{uV7Qt0svxJ2#gOg0wEz|aLvmLOG0k% zXbhnoDQtqWEmh1dkYi{9)|0zl1jr_GTG!J|5Gzw%=AmB5nDKoWXUj@MB z8N#I3R;ICW9y^qVhtZ_y8)Ht>oYJ2Z;`mkB!I89 zgXNvdd+IdIaJ^6E5Rl0+Xc6c+{|p`$=6*-_Kd;nNoSo()DDM|##s{hjY$ixG+$h3* zuAkzh!h|8hpX04=JboVUAAeu?m!E4fWWu84a++xrtLr466pJQ-4CkPPH|apS>%&t3 zZa)X{#5VU#T+)I;4=%YJ&r8*yphXB<@F&fRRFZnIRWtwdf&+p)>G_JK@QYHlhCNR5 z$-vYc7cmagYIb=?43-DX`C&U9K?=Nge36jK@C20ig}4OJkIO>}sn921g*8Ek5$EkR z1FnQq5g@7Us^^~$0*a1p1Jh_n7RgGxf}M#TBOzx*8nkx5hu^yZNhc$a>puq=j}GuH z>-F;Cd~7iKzX)a;QmE!=Uh*ZtI6mKAn3t_a}4@SyFw57B2FtwTU>dJf(oqW@It3tQbjNvM^} zkdS*SWA8rkRxG={tMu5zt5+6AHgL}-Yyao!FGb&Y8F5C1Vq9|QoSf-3iC`rH1;KXj zONrlm1rHy4k^^|ba7R15w!%7m7M?18fhulc2nJ5?F~Qg+DtJbyDG2=P`rvuT@Y{cq zo~6uY`UVu6CZQ!?ch+^06B1ZG;K-rO0{^t;o5|7e6zL5#+f;d^&Sf))GM&zT8ao=O zG2vRAkr|KmHGUuk^uvUaV(P>N`HY1j*NdaA#EKo)Kj%qt-daUOh7K=XacrQi=FbhXECeA~?7f8)85|Hm3QY5A)1I4qEuNx%KD>Mm zn8BA!!6~%>uiHF8ADdA7OG-oGt2lFud$1?T>_2^mDP#<#yUac7ixcrsO5-dUngg@H zN>tLcNr9Ip5~RaX&W*>fdB*+iOyn##TJC?XAVr&YlXQj#uC~>JM1x|mC$rN%(i7}i zJ7CsWoJLEv;74_^w`RCtfCm{&D`-u;QV<5ge^-c{=QUw}V5&Xy0egBEJw^Ne&X3r=D}MMf!ao6W&>IMd4e1dka0`yGU( zPg$-p^gi~?9az@SKf&J^Q(kWvtN|sXCBpWEl>L*vs7U)=ppP;KHg1XQk}dq26OaJO-CGv57E!po2*tAFvmWxoM^jBed#x5U$mFcQ zmTbUzM)c7=rK?9@>TjPAc;f4FRYq?Ss(ak?1Jr=R*_lHHSUL4`aW1~K?#u%x3&T=% z!JB~A7jXAvx5tjCfC&Dh(m*vDM(hugi<5(Y{@Co|wcJk?XL|;Eil-Q-T^FawO1DpZ z{c#WNJB{dXDb!c*N$M^xvn>)!ZS}PVbpgcb1?}0=xwQVN)~Q)HeJG|hf$KhH29h72 z2d_}lt^+Pm*JX6alXQnfPbz_7h^^+4B6d813v`0Pkwk5zeF>PTgBiNW%NdZdwf!Bf zZv?#-Djr<)7}eqFm?23_aBG^q*9XN<%6sg;!8H6fdi1ex^OqkzOfcw;kvv6YJm}et z=v_}KSry`yi}2k4UX|VyK*_kYU;NEpvl-7{UxEZ;w0*8hm4 z8U3E3(%r`;yz$=R*sN&1Xlkfo`)>NZ8c!P~-MO_YJ_Qv$3cUEbVX=(ln=*5vlb|}0 z`83s`sBO;UKpNXs^^q&}`CjviAFd%b0r#8UP@=B2Pa(z2!Q->`gv0WEAtd2}eFQ%F zL0y)v;sevg*P`l+1LUkWqwZ~bRV zPHB_|?{m*Ub;B|$4pQ0k5O(59)P$yeVlKh1pxLRABK9Eop} z#74A@#!AL}zAaA8ijL;o5k4Gb_OQlecx2Q3xB8I4mf{fxS8iC;9`3onXdM&2>pkDg zSvsfI{Dp%^@Ed8QUYqXNg4R4*i0wV%!O9?sa2ff*qNzE;tC6cK5?G|VN3airIhhXZ zeOBk_g#Wve%o^~L3?~k}y4=+3{R9D}GzDnI?HN_UGo%0m7W|b4+j1{bz)SGELEJNO2+Xw+_=?L zTOmf48n$^Lm&n)Pnh9wx7Ytms?mHOrm&l0PM|uDi9t|J9xQvXm-XR0H~we++li1hU8OOgW7Q99Doc5cNKn-in)YZ_iwKn=m<@Eyzo6-lt(qwh(NcW7uiX za5AecX>vEAr2f_2Mhnwss)T9?npB@ywRUN1nI^W##TDSBIp)Ttv-D6ME4~?p~@bv5Wi6Kq9!E-Zg z7Mr5LbK)+{b}{W)aYe;Pn4bE`D_oa`EY%Cd-|^*KWF+ zlVh;iY1iD6eN)J%+@;r2Upr;cOZ zr43;pTKU}-WQc`_7V3yU$5D}l7H2Wpt0h>#7~D7{M_02c94*PaW>LrZ#K_sVS0V&vhm8R&h*57>mBKb&B$*s7-auxu;4vDE#7N-&2N*k^^f6#y1r*c*FWm#iNE z!*nPr!4O0+#C!b!fR2U?}>tDqEHxr8O(k(5@rzf{OL~ zmqN3~j2r~Dy?nQaZTWu~fW-8bUp`@Y-tu|`O(Xfh8wg;+Wx7cHUMXtT1D1z|L zU_C{29g;C(4EvVs$)5&ZAZ;IYY?68m_+hmOFt#WGj=|#tLYw|_W{*vch>6@0h7A*gSQArSG~gr^%n;)=F6Gr*h(+ya z&gZJsl+PQZ!`a<>qZ+Fj@9n|(TCPvy!u;s>&{LKcNSYgw`~W0JI;qb9&XRJO>ND6) zKK@)wjOd@uIO?JGx=q)k`Y_|Hb7zzvsZ?RDuxDk0_@@zQ1;6#O4a~AGPL(Cq$dLOHM9~B{Ff-0R&iVud`;NlcVZ)Ep?^fzy>Fzw zTtYqx*xWYK5^~~qpKqsnz0z`QM%03rVebQ$KkX=aM#-$H4#=|14Iw(yyMTl3t3hTT zwQ;RA?9G)t2mt^EJ}ePJn9e@a)wct6=Shm7@#CAWd?L_^i<9Zo_d^+SL$moyR4tMm2X^V^ z-K#N)E(c*sL+No{%h8aXdlZNTO<95zDXSI^0|-(jzmLrD?YkTOCT-LuIDilcp%y4?l&19clNY zMGuJ7R6C)01;r2WD-5m!)>L={1HI~r>253MmD_*%2wbXa|N9SDdKFzSNRGfm8PMGV z60IFr{ncWFu9OUB=C+KMu+rR5N4<;ZD$=wDap*(W)OMd)`@%oTLPyjp_<8g3i>=_} ztZ^Od>oRmtXxPdCX9e>b)?5k%Hy3u^;u=KEdZd*}=6r_pfKWa8&^lnEs8;oDHHPt#9B5jPm9z>@_l#ubfad$`He zSfjVd;1mA9?3l_$=c(aYq>kdM>b+Ky#GZwOXZ%88e8+OJv6C8F=(i;^-FqFOeViDC z%P)7HX5YP)c%Q`)ElrETINjb0xN9DykCRNk?;kH8WcUb=8Ii#+D)|U!xK*P)``YZ9 z-ZX;ZnYRWeN416jvKZOct>_oAzNZ*>%q2x_PQ|5_z6K`B&Yy?k=T;Is-FA3jZ(i$N zzO(cLYs`{)5MoqcObk4y+j4F5avT$XMuyy3MJB&qEa`%KaTy8(l}X`kYhRA;ozupu z-^rg-;3fk8{|rpRUMz_S6I2g%@OO=x)r1vyI9m{tHIorb5-@OxUdm{rXgV@wNIe^BU zDgvTy6DqcEOI}i3dEZETonub|3|Oz+y$Hplg{%H5&KYYU?$I_dG6D6mHk9^AlrY&^x=I(UOa_4jCU<`);`k(*`?3q$UB4g z=z&p$FyW^LHvH|U;>+yIU#R>#)Nxr>yY{Rojf1g!WP*<%RB(=gC3Xi8B7HI4Bh$4sGsLC^$;?b8eI_z4D=jvOwOBV)?Wkqc*-K<58X3 zWCGd>iovQm!*Qm`BnRcSi2DFhIO4xk%`O9Wuo1LR*y-5Ix(q-fo-)85Tp-v@YHNs{v)qgkC`{|BZcV91Yjqf14ri9HOG}!KDKxo zHAr}ub8B;K2CIWvk-uOgG>jw%1XL4)TWQR*QimK@D*!)tsDcp4&bUu4L1W~65CkWU z8R1Dwu|vxx3M&?!j$6%AM^;K}eI&Dtgx1=;P{RO9lq9He^!Pl1W08C zG*p`4y>Uak`|rys5;x4LgPK1y_xmc;!CFENC}`(Wm)q-*_5{XdKuBnC&%E`wHwkzE zf%bB|XybCz5BLsvvu8m*$!CHZ=PH8IcIzZ@u6%Dl!bUKl=hk$CY4I1>#?WHHcCDcr zu@Ys?+KmH8b^2v0%;O#|Uxax7GNj52JRVI*J;<_ePCpC$GPrt1%fr9RuTb7@WSD9%N zp8t09eX>oE6`BK z;zh^JWBOi+D=Cik5d~7jMQIx`5TV%F@j>#^)wMt-MZ@704<{<)K2)5?;E+;ZS*-)g zGd&kXRN?q;c?#tDHVXl~$lbPT@^{(dM8*V6Au&p;mtun#`*PF-7X~4T2IYyr0U%%l;qR)^e{)9wwO23~Q5%?f zEl;3Rc?vYLgjh!9)w|@xs0EcVTIjHthJE!>ksA8U{de}R#_D&JUeGe=06C>40b-{K zG>uh$7FMgD%1_nHkf4$hus`P1ZHwivLbnAK7cZ4AFC!pXykISQ!3^emdyN4ZMoTDn z=FgsxSovC%VF>f%MsfE5Sroget!wDWiHUHZaT2Zu0A$h z%4wnqB3-x|N-yfyl8JPvB-^Oy!-ONH-Qv zVjGfc1DvYzU51r8`dnVS8EYge;Mbzb9kSmo@8#ITw3_ni^2uNhWD{XlpZvfi!*{J1 z0xK!-`n4mO_Jw{p2VUv|upqTId12K#%$n zO|9uoDvpiDKuB`{+^#vq;F^5H!>xr3x`?vtr{@KPny<)IadD>F1F5cM38~8b%^=a9 zi;@*2!^C*{wbVel6J#Ckf-`mt0072-`#nSUb+AEY4(kDiD-Ur4SsxY>S%Hl$-|}1e zEYl9lXwQJuQt$@Z?tmnNZIiB_<_X1U7(bkZBcQNvrel2Urs+HgDbCPKrR; z3#2^u)Lpz}wRU0Ssf1^KJVZ9njojuTsixzr*Oiq{5&4!O@hpu7jrqB=ixxGd2mZc3 z5%j=R%rlmKOT?L};1eS@TZi@{v<5A88B$lN>;S=Tb^EP!Dj8|EgJ$twolQpkOTT*$ zPxO|35r%O=XIlN_YWOwD+vR0;apeciHVD>Vm zB)*vj+0RY1L#emt`@5(vby!0eMRouSdX1U&SwWmC38*heLHih_%fj_Tx&>E0JY51ADzl-!EGS1UrWO=v zx)T~}Csd9XikCWt(1GQT8}NoqKh}?l3*4{+-VkXle*>#52@$!^?j_tQyyuzumrf4Q-67aM zRp2eI2Zzc_Fa*ABxm9LuWELM+wn84(OjO)c_a%Sr(gcK~ZaodkBhB2a=h{jSI0c+O zBhb2{?dD~LniplIrj-t36Gc$CGfa)ZmNd8l1YI_{20l}81e>l_pwE&Y(SyOZ!}RER zA+)(L0Vv)JY?R}7YuWcabcbZYHt_Cbt?YsPT4cx$VqE(V9lE%zPV<26DTsIEi2$ZD zGYC_q2cNlDN?_<>%ZtijRonzn5{E@5usvOS)0DusPl64K2^IibNp63U%RV%7apAC~ zU5P$t#pT&>^}0_Dz4TxKzt5^-R98a&S?eS(G$_yE2xtLDqenjkJ2O`S%W(h+J;y9K z%!SZQZS>DW>Koi}4rz4`1A2Yu6xo~G;vXrKna{$N9s(9q9-6komRy0~zGh@vM=Ht& z{Sw6N1J=-SwmJEvS4Wlv)nH*d9mM{i(<~VkP*hlV8L9cfCJLkyE`VOp@%3#R2N|4# zXVAUQY-?b?zM%JaJM(|OV>I~XIson&ChA@QmxG5TV|S#&PLLr-OEX{@P+E$HTU5+2 zUAUhP3P%}aBsTqrDwzfS*g4qfh zEA>VJ@Zve6$#{$rYRyFZ;qPbi>zu^iQy@bT)J7_LoC4KHuJ^K%YYSdpy*ozfRjzRwsrMQ3nwQE)?XeC84&qHb;r7oQ}Zwm3ioKt!PjUL(?W#5Kb6uTU>D5Jastx zLn_Gx<|*!5cmX>PGTgHpA+ji&LHPWxGxpdGG64ZV&ynxbaee!JC*|8Y$U7Cp8^VK) zM|`kRGU@`gka@n*p8DR7HFiA<*s7aMarI?b{|_|%L150LasdQ7=bq6VDc5z-S`83cfd(9*pNj8%4uc; zpakk!S1_8`X5q6*rIJCOy$4`~M0T87#TkqNu0sBB08b1g5FTemZnx&o?5Dhu_q-7x z+YlbU_3k4t-X19k8GP;bZ&}X%0guIjJgxZqHZ?4ugs=99E)YjT zBb#(rKpFm>XzBGT)NhC{w^!87iCLf1P04J)X^}b!UchtcXpguo71Ri8B~nPmR5}yn z-GLB#71_P#Af*X}d2zu$@U$TFMsAaiN(Hh|K!HKg{y3S7^e%|r0%ZC&QI5k{YOrvrE1ySlgA*Aj!LcoR);M-ya| znFXdoADyOyAbAYmPKPSMvjww;aaeNDH#uoBJ0J2Q~@Zv`+w3vDQI?s&46!0F^% zH(K61q)9K0N~Dlcq@IgVA5{2?D9ZlH^gQK}Gy;Yq$Y#!G86NVorC0T-gJSl@$qPT* z7<$NGt#aD}ETDr)+$*qaC5xIKS;e;Fh zC_4V+Xp2gg@!dW+?C002G7l|8)D^zPcY*x$z<8F`z1Rn1)- zhbr2X-7Cv@bTMQhx;FkxHh(k@<`w&C`8*cf3V|@8M|=(&E>QMt&2J7BKUZLv(g0#= zfC_hiLOPIx@J}wFE6p(MM_w>!D>2 z7Y}3<4kEhL7=P#RR+bfz#7m3GFSuNzst=#4S#|R2SGsWrWNnI*uY4b%xt7xt0}?XQZsmbZC{QWD%k@YNoW+rUfZNRLtkm4Vh{bbg z`%0GX@H5?LE}!|sl6z-=bpmNe2#4A$kXaty+X%M?1p?0f5X8=;1Jw@gah?M*9`ao3 zoBeGLEx3h{;=KDWpkg(nM7Vd8e-dX&gqrg!kZ&1gDot@>4$ix;yuwWs527x|b@qW` z*w6#n{qnzfjPv%-8%S%rF7K~@Kb8H$EfxjKe>Lu`F^XK-mvLEN*ENnPK7FIu*RL}_XpZ2Pl z)f$cNIayYq6Uq0wKxUVZgIUcD7nias4_~AY+JuOX3yTc*AAoyLp2Gc3_~448Wd_17 z$1X#QeRU(F6bHc42+6CG^?-E%P1wADH*6O^nE||Wi!G;NLu!0e+0*5?`3{M^oS=;S zusji_v+zPoY#1AqGc4FR)Z+lDItkrjbPF~6m7oXfy^p{d*p_)5Q2xP`q{wG* z`U-LvCNe!PX$4S;t(!@*22JMcnl zmZrDo6=0MQJ3L%6R-r@dqjWU>NkHv?Mn*wBJsi8x7PmM8CRMeVIP9LwFqA8q0$Jj# zVDMw2dpHVva0*WSrwg!Z_yv5APcMw0up^Jv5x2!4$I+H*F^rKZ5AT)y(MKHC#34Up~|e&xet7o%bkwThT^O= z>2q`0@Dz{Z*+4}*BeWX{aH*R373KJBJ$1F&W?Rh(Fn0V2d& zkXAq6m6&$|p_A`XsX&rE(rXU`0fNXrn-#_ ze&62HS6X2`i%59rC+wv)Jtg%c<@2HC7LZO(8K#0iyq%T92)b&LFJUb zxc%)*6OlJ%qFC!Gcx-uS`bH?nU$BQ>PgnXQsL&=j$#q!pRJ}cje8=ZySX^r}z zKn|pa8Ys63e5iuUNj24*ForHMQuv5nyGaspxXKR2QDswc+@E@Hdz+Yeb4)S`tIQDt zk#MlDIpbKCEiAC~i%N1*ucJ*oQwCp)R-h zAkQ1r+hd@|kC|6UMcXx@tYi8OesFIdX@;==l5Wn8N5po=KG>eh#k;^yIQ+yl^Hr=Q0 z>|aS9_;x4^$1zzHhsC7npU@BEMO1ZeC7lGN0yAiiQqh{7dF_x7=?o7n_<^XC5ipl< zHAVDts1a^6!@bwAX@&V?2mQMsKwI&cF*u3J*{J~HK|hAt1O^eA1}vdP4fe4cGe-hl z)YYr3AvvKv*~XIGey}Zfk#V_GySEx-19e|@fXcv)!#l7W2?TbA)Y(0~^uv>%8s=dF z>=4xqWiv(kbc#TyfLJDE*}xcM{(GF^ZrG!!#q=0E|IAHRl_FvnnSY4j8EW(j0$y3 z=>U;8NLUQuN%Gr1E-IB(O&63RaaX50q2duRHyAzuX&?khOCP2JvEL30+{`ZG_0M5> zoR(G{8&VXtW4q1?vV`5 zDR=Gb(&3 z7eH5Q(?RyC^J*7N07GiI;D5O54_7fPQPf~sXNmc8rhgWKC4*j&el(5W8fT7s6X*RI ztd9?mZaw))HE>5=Y_Zkjxg$HaMM-V+^dQ} zm!rfq5=W|M8Y8_*sh$QlJi|~);Fp{iA&+88l5c$g?3a1`I8xbbzO?|85PnR6YmBta zT^&ZBO_E}=_@8zF>X+nYUpkKzof9CcM=^;^T#?zP&rzvS8CmHwEDPPXyDy62gbpRs z^Q!WLv)>Yb)I+(PAEow^-hz-%r0TmR_x;|G*OvWHVS9Y`O@=iQyl2iFZ@q8hg|uei z%_?-71hvT)tm2Ke7?idbwoCLc(#|eQs>kq|4Zms5N&;wk_+SgvpHKFG#gn_XA1@dl z{8o(oG)&U;dl&m(c8A5fhrHX~mo$WJG z(LeG47;KqR$1$lQlTRW>^MNkK7prUSb+&gPGuuqHDwO{|;7e~O0BI%6#f%1gAjipW3Mc-~084pnSfxpD)^L@N{@ykdDb7tcwu<6z{xbB19DF#!O zl034!Twb670V!SZWoP)dVL&*pvlF;2K*NUXETd7T8i57%N^XtspzyZEvze%O7&M%H zi#W$faq*^)?Dj3aJwXyt?k%Nq)R+$>T>7rrJp-62S#_~K1t$u$9^eWdbMnHpyjmjp-+4LDsk-;!s;|zHJ5u)x*ETqM{zLyG%HLpEe-Q;YB zq+ic1*b@6QyT!8=wm{8R%UJ^@B)RQ7tXq54kV&hK?Mpb`Cqy{XTm1PC5VDPHx9&-s z)hKeZZWE3n@tP@%=CgQZb3Hue5g9l$xOI*$5xy=j>{o-@%5f(tCI?G zoh(W?K|O)fuEoJj4f zZ``R^8L3aM8H&F!49s}95w1Qv==MPslaJVemvd{>F#8LpFn zQ55mXRQ)vuQz*p-@*hd*(`Xw$JK}``FF_A>YH#?$mbnY}>r1sPTQ0@;2`Mp!@hhePVP=VF$*ifG zN%?ttbfzpAq|QVb(}=X6zWi}_<4}CJ1KHc3^K%-RuG+UX$7y!@4_z+c7 z8xkgI5#Jd)HM(Esj{i$OO7c!saYpfZ$HW5I)or;^*EA;k`>Q_16%S^S$Kd7m$F5P( zZF=Tp1DeV8m=poa!RAc}ll=%frv2CTxm~P^v^!WU&b?Ot<6<6(JG*>vBtHn5VgXM!&!vdwO&AFHK z3-XGjewP_3EnXWqk;a`}gu~AM?j!^@ST}uEZ4jx$T7deb#?SUL)#JvnW%xQZyLlo!S-jIMwuoJmCpJq9DXA zX~3ybn0N$pZjP9vMn7bhS?rKeb#uav@Od6Wg`2sI0%qtbTlx8m&_=~yo!{5Mwr9ET zLe#~8NwTZ}CsKM?@eD12W5UCaoAc~^)a&MouGrf=&rm-%34@Hn2&JN$#rb*1RQWlf zKnLPz+g;i1Y;)B<@ht=sz_4E(jGn>FKWWenq(2EjmKh+AHzQ74vq@K_zDjPwjhMd0 z?I#@EvM859vNJsB`-7gKLH_dPd88dZ7{5GOgQE5zY6HpWeV0*BI$AOpZSCfBT-hS- z7v!}boO}eEzB9Robr){rZc{Pm;8Rqw=Xbc=D@wr(XT`v2r9UT`}wWo$>ueet*64}2=FIF&*h_^79EA0L>88{$obI)sJ%i&0p z`^fX1raE5!NhC6zI2qc3uUTe*{mfX-S6X z55-N8J~ZBU6bu$D56RpaE&e&Lt6@`sUBu#toS+-ah*iE2Q=!6ree>-fxi5%6FPcA0 zR26Gzv+^c!rWV}ICE(eERWmLIWv3eH@@^E_=Ps9VH&H390Q*Xx!oVzYuOi8 zbL_z_mNw|#>Nd+BkUr|&eRO=$Q5uL8-!nu3#FonNq?Z!d6_=lE8^NIdEWdkza8Quj zkp-uyA!bR|6Fo6%a>4ep>06I$y1%uWL=;Q^zeR*+ZulaoIDB^se#bQIou7RjAFKh$ zoH5N9fM3E5A?iLSGqE?ZM*-1jXneGI^2fq1)y^(}(yo0GXgD&V)KR)SnkpBFYmf6L z!e&#i9bpO$S2U#=Ql*#A(Tg~YVZ?2QeYEqWyAo&kMBXOj?k~{Dg*p-Jo8l!V3$82# z8xU&M8~A>*e43|?B(Wro!FCkw$`+P^nXzl~ND-s zJ|R)KDdojkkmR-l+hkh`n(>5u&f-T8_yFrI1f4hryMy_9MSmLij&GO)q%QD*WP4L3 zT<7<)CV?k6ck>|ti6Quu_&h`S*$$1s z_`?eGk~F%=Sj7kOw@_;6ZR|d$+O%^g3>s=xGkzM(YrdU3qLoU02m5l?H`lW93Xc}Y z!KT#clxml!x8h^QIrA?Dr9JujqksvY^OX50G@F;f+hVjhfqS<=N4mVt$U-BD@B#B> z^KD3zPuz0+`g};Qt^sOAMS9QiM5i)!frdtK0gyGST#>pc1NVhjj6{9sgjA{2njX}$ z!Wmf1|B_1N)nIdR@n(|F_6gn96vz$xM}5{N84tY3aDN)VB;)RUA=~#)e6J04BK3RB zE75AvXE&Uod|Z`_mT+L~GFP;hTo2dpWg#M$F(aJ$Ikj82Ve^iB z7{$m87sp&#e%;mf`tZ$%wkm4ElSv!L|+*kFzO~*$71kHsq-riieKP6C_vpCS&;#)l8{-RNT&R%4{2x(4#K)Z25*Q_n4@mgke0yLJF zusVW0(`Zq|`Yp?@6l{ufrQ|{NmUcqTBoM}|6-3R>ah;JSM&NTa+zlG20$U8Q;e@fW z1IO=N;*^fC)!Wqc#cb9}rQt5)S4}zf7`;rvq}1e+*{ExKSLD~bLk}`tz3?M6+KQaxB zNSaPc8xSM#cc2h5U>FvRUwXd!S~cFG26?lSTki%xOn1b zl^i46YYG(u?g_01kMMPKS47H_7pwbQ@9%d27|%hT_DHq0y^3TEzd*~T&vWOroyhIB zcfzyFMTVFJXS+q*NZ*8E)UbPBN$jvaJG0!@_W~JnyakC9Wq*(oy!#muqty1qZsv08 zHw9C%uHAxSJ_6|haRCWw6RLToeI*HGDT0~U!_gNg^y^;#DG1q9-tDoWX>S`aXIRdO z9Ci69n6$un{kVxw4(n{vMMeFW*JFpNk}e+Ix2h%fOcqQ}C&SGy-$Hd1osAdZX^$VB z*VL$xBaD6U&IKkCh;N=ZN`~4pHp2GPnF{6tvU5OUF*Ire;l0oB;_KAA7H-|6&Oj_q zpZ&55l!!285eAJP&u2$FpcTtgcrfDXG)8A@ zcq)NXK55=F8GFAike*b$!d^(S`=mxt1FH?~L6hVQ!;qTxeG~gO&**AMF_^slAP;B= zy>qlbq|c~>pcjox6qzZ4q*sqf;>oHr5Ka%wL_S(j7gr>3HULP?l>cR7D)v!8<4I}( ztnLuEWF|Hi%Z=ANh)KJhtI;?V-`)@+${FcFfUIdE027!~a`3|?wwB2NPD z;^`!@d6UeAaRCDFmlD$SEHuxw7uTPHSW5Y$il?&ndd_Ot6C&n|U`^i06Bj?`rnV|7ibEB2^ zG(}Nk>a{m+F#qX@I(A}h4Udd9!2e}kZ-a2`o{5EF0PqBgL+Ucoa2_aoAv?{BPt{90 z&w`G~3C_W80gCyZFUB%=#tn^6X&uO}-;}PctuvxTs3nZh+HaSc8wlx6+#(rAtn#~L zqwO!t^()y#dYjKAF1Bysy5`y1O--S3!<@Y_nwIwpsuQ-5CIqx=$+TH6AyeScAFvsu z*}ILJ3+aqH4COR-pSx61szJ&ei@ky$XDV2<0a9t-<&j6Y9%vW z9y`H~>~N$v*^h!F9eQB}M`EuL&YfvZoO~O7KX-w z^1`HDxo3_aSi$ruBR9OPYmZ=%@m|_>63-$B{ctneo=^63Si^)Gqr?0JFeXsFSGnm0H?nE$mgl)Z&3ZW<* zJj1?gd_IE@CTppg)P6R1+f`M1Fk1DQg`F&KdWMxlQ>BRm#Es?@n~D=h zlOK)!dK5eYgh8N)s3{$I+}Gn1dOZ_1GmO*<%jeyFu7m;AdS2t2KWO!eSM8-?E|4C&c~_Ny;lOJVmwKm#vl8P1rtfdE{)NHMNzeVr$yg#oY^=( zNQ~AykT%D)Ipn+F>9yVO02VU+$44|sL7citQ(ONZX>T46^}oK4GZ98bq9}<%HiF=WyFT@U_W^1e!HST!)fn}XW4iFIGDC;#w9P$mn}Q{ ze9)Wj#m{O#iR8&?c^P_CqBQ6OTQ_~_j@h4WUeO@Kl#o2}bM6HqZ^3J%e%iMXK9Lw8 zKNDS)d@BgsHsWRVMC04yUX2K|9iEfK(UFIEO~+I=j@cI%bLLOFcpLPneLCUOTB|pQ zq?~(RCNG6pmMosWdgqN;!IOehjQB46WSSkw?&H@x*H7W=C#DL8G}g7{NJb6>%}$RlN$ zD(mUfWATk6rh?Y@A|ppPqz7jYoM0~SE#o}wQZ3!S%ff{M@(X?oQd;7_#|~2FnLIIA zU4h`_#7Il`Iaz!JhF}!JKwqKrDOXyf)(MLJZ|!vHt4mm;moiw^voGoJZj zVtbxx4 zxio6C7su^=YMVp6?S{`K8|0P^uVE$NHFaCp70$ivHi$mWamVu0mPUq4MfK8ypOo6_ zSSewo9xu<@74n}h)cF=L%^E%N6hc;u%#6!rCxv{I zhZTd)FrI=CKDfuZL4kh5Q5GNT@F_n7m;TD3@w}WHOEGB-dDA=^ESp9YEaX2)l{V;z zs%a2JF7MbKr9m`Q2pdoLy#FzKMp3W!woqPzhl_jl*{QqFhD*x=&FjMMeair~2Q+B^ z>YVbyj>Rgun4$5@=T%vPJdV;lDa-Vb2C9oItzsM}TG!;0WQXmG?Bn{Zrxj{+48Pp0 z*Pj=1$>?w6$O_C)nR{a7(~A}VJ)RV>$f0&1ZEK1;hiKbOYQO`qVP2MlrN4^NBIJ|Te6P}R6+T_)Sn{%QLV_AB;{suq{k&F zBP)D*&7SPTgm`UZO%r7}s*5?#-=+2?N0#-9eK0y-bTCExPPAE2{@c@Wy&(MKkh!-w zf4UQ-pnvRFO=IC^4{dHqrD6fjltNk)Xz}mk){r(l6#Od{SAy-!+1l zN@p%M**3axtMdTZRXrW1GjS>ePn|wp6DfL!eC~&#mTj{f($f)k$?JLKpO;(hE-rgg z^7;1*J0l^TloJ9l$8}JciL-}Y`h!IJsFqX?;bL4?BFhl)`HiPtuqCm^x7`vPhsjE% z4?P!p56HTaY;*^8c3c=fyoccVoxx#dYg3Ll_PXnE)5XjaPkV_o1|QsDXyK7Xil`TB zT-!q<@oed#Yjj+0wD|4kTdxpkKlr>n)9N{`td>?Q{u-0OqJTR3DpG)&3S=G-a){1I zw88J#KQa@a$l`=GP!usV{VYAaaZ=@tJI&5}G|KMBYEMx+YQ#xKvkQ|tbMCk^vrnd% zPR6BumQ=W&6r#XxiDzv+d*^Vg%;GFfOIavsR?v~O^CJwe+G)vuzwW`Jujeo2&kGIW z>^9c?AfCw<>=vWu6T7i%K#E<(*??YkmVdg}@Xd4tk4uYJoL;0)KeK`!Y4+2wwflL2 zvpwS4%@RqzkNuLNx!~yBBH};kqEvHsdqOOOH}kexC;%GnYxD3einX1REBkF5Ikt4) zWP)X*>g--|db?7Fni(%c3qkhS`E^Si#(6D;1+89&nf&uxwO)IcD!P;%iTkt=kr9J* z)NIse^`~jd+I05eW__kSf(=-{j`luU<~x`EGhT(hXve40wU>j`X^(&7A@NxEW|FA~deX!=`_(QSW%vf%G~Vi-#7h2uSk3EwI|Q}2h-UurdCA8DEohf%cW zqTwXMi1$BdoEqnQhZ27aT?cj6q@n;CC?tAsk8av6#iqVUnj8f)68!DfCU>_S07~6E;PUbKH;ct@j?Bek0Ead} z8tq+22!@wq_HNhs@&X3@cUFkg|C(mKNi~q{`G}&RV7mT`{zc7|&_Z9Jk0ly4 z=NcXWS6F4jVS!k|Ee3ZrHB5}Xj8C<{TX@0>`TD6hwXeUaGH7v#0%%3u8k?6SIHUk7 z*7*MQ{zk1jA0WL5NbN2 z>r2qqK99%gv6PG~=3{)ZyF5}Q1UQpo<6b1Oc0;$b+hfvfR=4HXm)|ck))=xZCDs%I zO7Uh&r0#jI*7QqXg!>f%d@Z1{3UTfUMG zX(|Kz#=2#RnmZTf<9)A7B9lj#u?sn#=_zF9n1NrZQIH^VN)q$o#h zG3_|(+b5t)51BkFp+3A0DbIcF!7%b46L7fNUzQzq5(+Yzyn^eASxmnky>7aHWlnVG zz0k2GHm;L;vv)Q`qmhp)5|;bSj&~<_bf%qsR!{i){)fdOx)Ue*pgiq-(uM@^VFfL> z*o4=w9Ldff(3F>0tEc-?FovWv!x9Q#^}9KCE!4gj@=aiHwt4#is5N`J zX`Hl3{Sg;Y>0nTKwt^txuR$o)KIu8wHto|7<>NyBXNwvvBLc=(UTsumznUT#oXG#J zRfnVHyh46;)a^o|imUtiiTo#mVkGPc=x>*_z0bQ4xP|?l{XT4;1Plji^&{r9Uc%}9 zV{tW^FXn2}e|+-Cv_1>uczDv>=dA(9+sOGqF7b0=A8d*akjdmVY4 zMq89hrS;pQ*QQ*D<-3mPO8)#wFg}}^zHnyjy-m|{E{^X@q+QY5@e!7{!{1P&MJR*4 z@k?m~#6gwdk9 zPKch5gcbc~j%i&y|1ctIU(}~{AY>BqFBnYHGe)mn<~~T7Qmx#Fn>-X~5hAnF05^MD z4(ym;F-g`2PGc}LSAT+G&vrZ7Wd>dnUED3!n|TnQSL;<4*}F{YaBvX%ufv39#U^cN z^%Z>sGrBXx(ogC%B?*Qza{VN_o1}e1EKxlGE4hil@B)B` zt;b9cXo=wSHGS}UIvj*j>>Z<_6J0QuBbQ?kyufj!7-lrE+_^r5BSUv|;!cHZy=@Is zzqjdn5mamxC>Tx^@1FKbXN%8DTZ+j{bbjKD*T(0!iPuZ-(sFC*Izu$17h*Qxs5qZ; zX8sUVL6K3tx(K?499;KF2S)gw!@IGXDawIynmT*zMY8GKwIu9o_qYKw!!Jj- zEA@U;ZRqGaUvb+1-INVffsZ2`~uQ@Dk8)1aQw zL89b`mk&r!QfZvMg=IzIJm`z+_i zavO>&=pFTAj7bMc>YI`Q@t3;$$qF|dAQ#ypR3JsQ6y@vDKY7K9NhEW4jgk-l<6zB5 zE56`t3}E3}U9qH}53?Vb_ECPs7l)%?Ah0dgzGiTF{(Hm8Phuj{QqVUkhM}h05(`88 zbsWJYV9gvoNqd66xupMX>6#WOYAwMa@4&oKb6LVPAR*wY+u1z>RH$m`QC)u}VJ{=? zX10%{tzjS8zI3Xx*bkRx3KBMdV0S}u4_!xU8$Ln>xJvBS<-Pt^9Ik}s`(Ho8FszyX zwIM|v$2@?m-QzEuk~?N%qVKvdh@93d%ilv zH;#t!^{zZaC75)#&rqdfP0WZhGx~CnWzXyNGZFRQBH%!!YDCKymK!Y$o~Fgqb8{R} zoNhe)ZvN^s7zvbvku~PA!>!u+M?94^gosyXtKy&CG?F#SWTM~y;Jr)G>DkSt1DQix zd&;&P`p_Us*x0&&?_uZE-KQ(;-uph}vPj`qHW;7Lk8b-8%@=#1eNvkd9acJyc9ib8 z6m>@*p&fnRP8KpE_F;!^I`&NKpplyKoZ17-6UJOzm@3v^-+Y!w6^}H1vo1Og`E~z= z>FF{b=X_j8nAxu8Ya02=e!H0{o{)#ug=2?K~3Pm^N92F zV9I+=cN%Ogw<%&s5{*={?09mNd5h6I`$9*1CI2rlE{`6L&4dO$67LB4B*uK)(LbIbXQ z`boUq3_Co7lY~Tk!yx8gpN{JVq%i03PndVC$#uDE@@9q1-f3(pHbJnA+}vkBv9nKeY;I;@iY{cv9zN570-ykK!UoF937h?aQI; zN2bdx#-P+^_1jv4a3V0{7KoD>^UL=DTHXRVpN4@ibEsEUXJj=18>e}LB2 zodrXabQtp~u1Pl7*=2(?J;0E6fM)7Y=+m~BAx8LMCy?$-T*eQsP#i)%-udI{$yVmL z&CG)TL;)Ls41(|PJZs%C4)?gf1JAKxetOsxnshfk4OxN?z)*(55z_Cuve~w>rB>ke ze3VoZ?;4n)lbR{8&Jzm4MZR&NTOP&NXJQ;iUKVThZEr72y8;zXm{8ErNy!60pV$`{ zfhmPpxB$eg*gJzlL(71HVpm(7nqfp6MsZBUMKaLjkpkeAFp*c{jJF2#j9laM1@F4dV3PXt$j?r7EFC1q+#` zUigz$^M}*jdtSiO9jucs(AXgJl~uQbph5f$!~|pc@s;1P&pk9+Z3+F7AsU$n>1$fq zZ|EMiUT)Y!a8d*ws$DFks_`@ zC#D$-Gnx}Gr-oR1#qD;kTUAV}<|T^KX(1u`VrVu-6%E8ceZ`D5-t214J~S23wm>)$ z|42&rs3xJWWn>?{1brRMb8&M$stj@ulaTF8B6(x)2uS}zQ`Oc{*cZPeLz&QYMR(4O zHJTX}*gu?J_armQrRn&@a??_XQi-C@)AwiZckl4iXnjhG?SOw6HCSOtKdBQ1gi`4l zD(M)9r9|LRW7HrXlCW)q5%1aJwy$VTZ%fIHls`7#-ZApEGvsu~T(wZ9s;fMIlwrr^ zZ--B&j~YGDrJn*D<3QMjCgVu=NsUjJ-QP<*HBRUaNa3H_s`b;eL3VV%ZmVuOfX_2z zQ*|})=bI(s+fpk(0ctosa`YODq9ti^M1npuKcP6HOli?jxsLh3^Ku2ol&stgexGGX zlU*xpMbw2=OP8i)rz0?-r0ed`RZ)GBID#5LK?{b;r|yX8YfKqI(mtx`e8XE~c&m05 z;amPGsA1xVnwOoG^i99dI-|(}z*ByG;Q~?V^C^y=Cu@Frt1e!e!O|pL@SG0!BtqZ! zs9%FovfOXgIMvm>HL;wnX-H*5aI*D&_`y4uSQ~Tf3_`~M8Q^qM zP6_bq87C6UKuN6=eBs*Jr%yr?AjR)+*l=1#)hqbPMaEVH0J`FB1+6-DTH&DNTTOH2 z&F8lZgvI|+-~mCWN>=$h8=S0VY=u(|A1BuMV>3uSP-c>J8Pc8|L_<5;5Ckm_EM<&5 zac3>gO0>;CRMPelMkCTxgLv#7L2tb3++`h(%`xsHDQZJ4a)}dF0$C)7@V2}1Kh&C= zhTn&50a{cZ{kw*=GX5V+%1s;}U+5V86tKf}R{Me#$()2sAw8IjB)uA;HTKcdn!S{_ zP}uv$W7b}0CL8z>t_mi+b~OI4Y>MMU4V*LW$tU*6-Ycwc9 znNXCK0W^S#cR{3ll!}VUn_U-i2{0yiKX1-PLZ^jA^wSvfRn{PZPEML)rZhE_YB`>_jvlR0 zqPLuxvH`f#y~BubF2lfv6zRP*1Vr$a8Nij$J{pYuJUTOx*`0PrhhASv&N7@ocGM22 zyX+dFRzKQ((15(>V*1ce-4mnmnwD90AUwS5|Kh=V;>Zj1(PxyRslXNQ* zM{&QDf?0a^{h^m-J%9`YhtsLP)8A%WkTNW3QvY!xDFAret`u7fjDuv(v7%F=KM;gD zgr2}B9!esTirf(AyyEoIG|cEZ`t;^mJxCo$xmbqMm|oW|TSVo-?v@6#$K5VFb`~8K zA*ADi{gjQG*A((+ zi`-}JFL1>d-1`Rg-JhNEXs@GTuQ^Wo-;X!McAY0!61ZB=`!|<)K{%i{xUtrCsV~K- z%l(dx%$1%82dtOegU>1Vd(HMpHN;JCy?4|EabQaVFaj?sTlN!@mcllIi$fuB(q`=Z z0om}@6!)?5GT?QQgT{_&xa+;HecYMBsbvCnDKSFt5A1#H;D^3JBw!~C+u&O4!;#Wb z-Gh>Imq)&7a+m;XE-RBDiMJfpN`J&(3#d^()Y9fk{{1&z9nA|y4SqrHT^g2~~u!?ASztqs#iaM}BRiNnmzeVeGpo zp!qg7Oz3Nh>D5f(?V~`6Jhel}!O><|eJ7&wbAxf!-$8Iw^yNbG*;Csd2r1 zkFl<=o<^;(du=fP2XT*GzPKFvX}&N;wHGkF-5ub0i0V2(9EbTjznfr6clWt1l}#Sy zMRpR}&Sk?_U5NE#i@WaS7U+DvIvs8 zyIMK;oo83s_)Nr^=W=CoyJvg1GR(V~1&o#!TGKbq6O7n+fklsBYu+ci&UW|A6h~ zV8l-zN=Uk4#jlS`jkP>}H6Lakx`2OTlPoo9@7N(v2bu&C>6J#;Fd^DsO<&sO~+2t7-V&E;{svSq&`lls8O+H+<=C z9=`I1xDQMKhI$F42VVyeyLA@~j?Siu8&`%4X8~W*HqeKF8(F_J|8aS6I0vorhQ6)l%lL@N5U7)etvV&szJ2LJ0*0y_efFA4iO)igkrjSe27^h+YRt#cR7Ym9Oq|vlLQN3Kw%>fU6UZx zm=S~YnKJLiJf4_qlq?753g7pxeyTogFcj|Tcf zePDWS%IIa=4>JSzlLReOTlmQjUvheSF;GQ%1~YAiEDv>_hOZR18W}dt$)qmpqAq^L zHr`#7$u3$t6;w65zBfdGV_)pk_WZy(Kr4MNc>iNC>9Ny^>?&#^zF5%=7>7<^^HEVW zO$@-9GyS@jR9IM;(J4%3eT5FPT0VFI9p+{wawcfC!q9zaab)q`4#^{N-9~Bf8Ax_?VtM1-GTrL$ z;CN?XxAFFM8~t`o!n{t`Db?-$Yx5wlX@_~RG?4MA;xW#d7y5})d0`5bDkPv}7n+@M zjNOS19zB*0#AuBnzi>3&>9#c)|I(P;C}c#BuN`BwXJsfNSOWv%G)EJ}I-m$T2JrZr z#9{HaV63G+3_-6A_lt)r;4_$i-x(Lar?~9;+L!g<>u@ymno5ft2?ISX%$e&I8 z2RFd@E&yDq61ds|eNGo4 zX=@E#+-#`We1uGNOWTV}e`MUW<-u-OIh$tIvAaREIS%8VF4sVqH2&RV8S%KA&(+3~qUOoC2K3#`OI zl=w07o8maZTmAECzZivrwQlT|P(~KyzLolD{0yL?*O)0i0bbTe<%NUMHX^0d_Ys)F znO0{j^{;$!BlIw$WPW>#h%3WRw+MIpyTP(VGz~)vgJYEqzP96zRPXb)3MzE!JWM4J z6oip)Z+R!bpa7IawXO&+c~h_t@rwXciqo&X_3JiPv%)@bIX&UrL;f*7R87g*RO3Rf zrs&2(*G|%;l8zzExB`QBKt*fvg1)L**L#kN1=tnKpbJ}UAtNJG0D35Ht{2b#ahDgs zz6kH(E~YT4a~ zq1A281KjAuDCs)Mfz*bykASB5+>0qSS07?!O=HE-!bnN-uzUtg+#R;4%-Xnm^(d&e zJ#cQ{UC({RNse1?D94gHAk3ci1DUA_;7Wo_L?l-Q29|t?Aj8-NmLLsc$O6ybPOJ8x zmad5xEa>`b?w$RJ5~MBUjgCn?qpgw$P-dOo5Tx46Yfca~SSB_=Y`X0D8Wb*cWZc?I@EP!g%yj_5k` zz}qDZS94QYl`D6~viKni2c!v~ey&h#fAa-$IF9U8ENY$1O^ZI4ri=Djx;hHF#Yjv1 z=)_ZAQh`Vsia{Bw*7{>TK}XWH+wslOf}8!^Du8`W*`k+cc`90EH!{HW8!7gs&jTsy7!!nv9$^UXvTCO3{2z*ihO3xqL68)_XXUqVAn z+sx}0(VC>>@?iPv1FbYDc>aWL!Dd-0ujR+i^#V>ysI9yvM>!4yMTuu%UW;v)U}mY9 zVGAVs+BxtHCqKl*lV{e0-@zYqe~*b@K}Vmc&2$dH_dfv)S}3zP6|k<3H-)^{_Q!X2VPG<~)X?*L)fqUek)kGk+Z|tR9D;RcVus82X;b+p^0}+N0M}jL z^GCQW`Xx{fDtYQCk%|~rN7^!XWH5|NO&Ip_~HoKTWWX9 zK@A+q-8%H>=y1-+wM{gLD23id!G)?@)h!@) ze*qaQC^1&OyEnGBI0$&m! zex(*3nEyjvL>(fab?eb|6_R=eUC-V5_Ojq6S{UV_{owj?y;M7d%{(%`XH*)mS*6&) zL+TVaLA+pwT;rJBV29)vphD_Ea^;8x7s#}VKW?%D-*_)OO9a+Py9sUb+&Tx!C~1x^ z82F#j9_A}$1XeL(83+da1UlsB`at{Ddsk*4EcjjUFcp_VqDRwLh(8CJI53fTFX=f| z8X_J23sBL+w`L8wP81GyLPMKvtaP#`ccxw7=u>A{Lj$x59wXt>XsCx; zAJZGafr?ip2Rp|${{kd@_q;FU4+e<#3A}y*ENB8f|Jk6Z&F412ck1)^(QD0!RzQfC zV?Cix^=53~$|J&dKq^ZHR(}T*y!qo@1+pbze29an*cNg;J9UV6m|EI7sb|FOpK>S( zU7GBxa0P1&yV50Q+8D@2fo!r?JHT>td1JUJEb9Ca(C5*8mpMeKi7PY$ ztUSaG+hyAU1!Rn>|Ip--liy^zhx)3LM4+4O0%gAqsUYwQ^hy%8Z~AeRzxBmQg7tbg zklWBrer7dw*w_o+V|OS)NEP^e15df1l$l*^s+C4+WVYZEh+DT^qY_%zv2rSUKJS4N zCWL_!T|fh3zAoYvg?|Lt=g?EX)Z%?fK2ouC^ZCk7@xv(DO=wt^+%1a>K} zgYL##C^j9uk{g_X*Fvv4pMpc=~)wOYC4%{kHgVYFMCNLN5*sD^d6^}uF_*WvZW8UIF zsZYO*-sJ@KPygp#z@N($fLfMKV=NKzBD^ha-cB(?X4ibT$OEVMO4PC~v5uR3+F-dr z;mXb6bCNGD`Jtf64{!6cPH2<@lQGC)lvH2fe9MCQ71R}c+qc2*+L@R;;ZeB*jMx=<<*eDAeAG2MV__PZx2V7 z$+@0m7eyoK61?C`*JI%<=+|%`u!n3rTj-BKo?;4D;jIC~9`e4?V5+uE`X$XZs<7m( z@*#s_G1`)u*W46HMHVVljD}w{B5xQSde6y*jZ|%jJw$+*yo9jdJWB3L0fggw62012 z8Qv$E-74^c$sC)HxC{G%q#qSm@Zwyp%644g-pkIRMhr z3*u3@RC%50kG=;SEY5?Kh*Cigz@}*W^Va{b4M8WzsI-&nsQzU`L_L2w6axVa;_8)z z@aIyPnDgq~(1~;K%r|2&l6;1+PSbdqicL~S)ART%J6FndOj{6s4|Cd=0M`m~i@ujG z8uyYPg*Vu@9E5DlVHq+J4-`Uq;k3rc+m2R>HPv?u=lg4~++)N3WUGSk{bvLUCg$eb*-1fWPh0+!`l3%GbhDeGEYTMqDt4OXOz_UP| zDq((_&jAL|x`1lP2I}JZAmx$pnRR-VqnVc#jNQYNRBG^B5a#7QcN(Lbx0`T1G<1R& zDbH~O2VI;oD5hph^}4+TH9MZ*QwJgcSUL06yNO`%-)x2sHfY-AAv*r1My^#i_3xJa z#JO1LiTu$1nH&ry$U0FcJ(dTYB-->YzW#o3M<|}|=Jj96p zQBE}i`eHVT)OUHyZi%$(4U1a*wIBtGs>>Lr>fo{BVrgJ^&TXZvu=Y7xe{~LNkdG`G z?=F1MXXVJ(L0z!Vkf3gr;-a`cR&^q@*4tNK%fiN$5*jJw6N}w zE7>UX-oSXOZG4qmNs(!*-cP%vbWeZq_Ipau32=a4N_x`uyK>2E7P}iZDD=AQ8>)Xm z0gWvA?|A7j=e=e^2p|Fe?knuaGoS|g$M}pomFc=kAPXs4fw-m|^yOf)B%=Zb^;WO& z2jo~f@eQxYOQEI*t6zD2HEXMa6x={v+LhAUP{W`+9a#0A^Pw3Z*VkMYbXIPGWce#v zIx(CvupWJY2wJKMNUhtUM;%TZPtkROpTrHIsC~h?dL8-V>=Pgk^$mmYYC2poehKbX zyQ9Aw*6+5aBz`6MV9YFsg2)9Z&bn^$1cJ*n7yq)X zad^ssg40?8+g-Sma#>@aW8POZ11%!^Gohc9ub`#-3=!_uEnBvcjW=8;q>6?Vjn+y5 zaBG{igRv+>O)~YqXJJ6C0EO&@-_b>`m!GODzZ*g%`wWPnOwhL_=Dww2fZTQ# zYHxqS$L+^A?EFIR2E=|vr}eRdDy2Elg`R442u+1g6uGtD(&EUIh=~M_EK5~M7?qYh zL5u2-u9O47D@-u9iL&SrubdV_LQOWkC58Q8zlJSA)t?%}Y~%zL#Tgj+%3)^7c@_Vr zfVyTkz$G1-Zl@$JzKoXo=X|8U!pdd=@j1Pj%Q|W%?ss4k0Igln2HVE9hePX{_iIjS zG2;4BSVz73-BXm?Xhv7Ee9}#IubY9`ATgd|AMYUh_&rVB0__Ia$9>#T40}{vf}+@@ zC|84_fw$MG$46pC%L6>Ss%(smb0Q$w4@xk^>r(fTh6qoMKd_eaXSE~n^E=(gs80DN zxK)iKL0*(?yipEST{CF2*qI$dqhcT$E6y8F5#E59$A!4kf+-q$QY|`I7j6pZJEpm; z)k+I5h`9YrB6dQ@7>a6V0C`i*ne1lpB&FMzQc?tIW)oE1Cn9 z9;lPA60r^}SHvGzq#auhnWXKPH$l(Pphry-kV)r3V8uldeu9Wan~1;xiCQssK--iL z43=Fc0oymHJlXKqR$GG!Nc`}qmwaTa*Afq!zD6o>Owr~q-5i>3{>fEclK zf0zuO>MZF_7*XVfulVic_YtIq-CRPVAgDBpbJWzlI~=$9PuX+>oRMMe0kU)rV}f!Y zRHB^YnnB+{5Au^SD2C=h$44JZNzD!}8>k^d_`WPaFr|XRLo4XDuJAcbxj2e6T7^-?PP0h)aX1VB?gqeu%OxBz1tA zO}(WaT>yW(CZTqW9RJf`h#RSCX#w;Iiy<$w1?ujfkOFk+TSRe$9Ta1wTz?#I9bAo< zp042(o%!L7lzqL{XXXA}221``#swu5A7jbSdR?s##rQ~Ic%rAcCvAh$f&-fANOKu( z;)~$NQww}%jCH^zjY<_zWkw~^x(z^vg1CNr7&zQ-_^;-Iyut1W6xso!KY_QBQl1Sk zQhtblOKo?vg@%hs)Sf9S6Rj_})Aj94Ceq{&?G|hVx`s#@XY+(eY6s2o86}Pd9Lgq3 zN;LrWB-U>|lm&4Q$Sk#90__#PNP*_ngxyc5Px#Ks$wSWvZ`>nC6s%@MfMDvw2X`Ib z?Y8x6ZdE(km4KE`MYBVcmN|LFeG!ez2M7Rfyh7D=fL^FldvL5b7{5Yk2v}mrU>YD7 zVyR9@3C6(Pi4(d(v@q5M|ligYAYEAClslwaS) zWv)p6Cv>Rs;n1*t7ug-hwqy22x!f;>qORTYnhnzBFP7$PP)js>-jrH)VtnMwbNc;D zK^FN*U+~%=sTBtp!P0}uL#2d1<&7X~r$ZsBuhs?tzo28wyJp4v9_Dw8pxt|ikL-O} zQEP}#=AJsmo0pZt9ML$yZGt?l0Dj{Npvi0G;t+gcJG4d9A$H5?9JYw@GKZ>I9uW5! z0JGdBsCyRxP&sb(v%JB3;G3=d04%a{J+AA-qGqr1g?y;(cR=S|MHZh(^?1stL!KvI z=|)~Kwfi{04A=sReFh53iv-PKN$l^tCs8|T)jG7oWr-Ktp-y3fkbWrwoO@mn28D(K(gA`E2zQAF#9en^ig@tA6n0mzu)={N6wg{M z2+yv6xhQ-;`WBod6LbN$AljOhnT|YA=C}ke^KK7jfSNI#!XVjqRCr~-)DEn@NL%i% z^k>F-Xu@0qfC!LuZ>gh1F|Zp=`(o!MfEVG4s+m>yp-Sg{wR4h zm~T+A09K5ef_O^Sat%DJdE?s)$>eo?B_s+-X)zq%9=kW(&VgRgUN}S2NpUMS@t~Lp zMq)WM6w`o^7&%}dn;#qlXlz~pk9#$6lv)IAcMU@VdZ2$6&RX|SfMU&PFyXsmNoI(h zVNLzJcloHlU*E?iKv~y^$>m`OP1Asd`V4TocNID(ZIl;&-&|2a@l>*C1+UbEi>|C- z0TZ-m1adA-B#=k1I*yflQa7975=s2#H!v)aizj#CX~Ak|Zdq6wi&M z_AE0)ul53B2j^imryc}GIyKz#4tz)s^5>AdU=E4>LrrFtIVP1#o|F$m!J&GY-_JdV zisj=&EsLg2wRz+dGRf=-IF5{(4tO3*IJNoNrf)FRo29?APq^3>hV0QLLJg1=!6~G@ zh+=cp`hhI-A^%qOO;lgS7)_0q_6Kb%!N0sgF-vJw<+~5iY>_%fQ1k+sD|LeQABXm@ zF(fMut(UK3@72M=$&}Eh*84@&$|mD8-=#&}U}amtfhN`@StD5+jTprqBoYm+;uqVY z;_>MpV^{Ktg$w0N5B%GZ)Y)AJ?j4J#5i~JE|B!tNPMZ!)iaE&YWUus%XR;ja?CicO zYHPoKD^0mSyeKPu>0uYnMLvrjOqMqdMI4@d+zVK67|If*T4YugB7&+w@H1|XWMojF z-5mqc9hYqYnm8}ML+$$HD{+3xHK~@S`ih?Ch)M^0f3*xxtfYgJW{I*k)Yk{-S)U{f zh_b8(C%8@&ZQqGlLvcInh=4$O&jZ6NQemh|4MOxN^sM0IUd<8{7}X;s-$5t-^PDVj zMB7&Q(N8qMv*jbLpBIQDeuR{YzycaI--oD_j9|qN60sbD?SN!S2ik_jr_O(NOBn;i z-vvOycoyUmF4ct{oS+RwS;5Qw)Q!UN8p6^w^S`6OH5h|^?QkW(2O{rn?D3p>C+YOH zn&wV$9K{0Q9O>Q>F^ozpS99n}_5j!S3Jk;QUhwU{!m9Lp;3@ zMkmsYz;irk7dND2_PBOBo$X#AcYuVdb!X7#BcW12ajLZ^Qs&Iy<;vml)_6K`QbNiU zHl!g02C)v#Ifu+EroE4i#m(!oOoJ382?0;fQ+7@*t{g~Ikx>g=m{)Y@!)-fw;mFq; zy#Z{1vB*QbuC9PLPjoosLhW)wJ`?0idJM!TJ>z09?%%xJ^Jg#fd?%J$()63Xu0km} zsz4`V}fuQCd~jdM0wK z48=SXCZD>yyM6E6{Y2d;Ryruv+JO_xL9FwTp6pM)V$~y)D(z*k67Qen?61ENDl7nMNASAJ{;Uc7qAL0%(G+%?x!Xd|#87ZFyR^0-c zSX_GQ%oI#F#eGnae6CKME>Cq`iSgG6p|BIq;d2i~z}5@BjdQ$2wHhkO(YZB+QwYF* zGsy!}BSOhM?{|xj47E5Fe6+Sehor+qY0I$g<0Art*$Rz2CJD$eUHO{Ph%2~do-K+q z2%S3ymD^{4KI&PVSF~=~hm`!7?nJz#)Hop!dnMQipq)s#e_fABN!g@qO2+tU%Z&_I zQhAE*q6-9MpBRj(y$e=pcuJxi|2lFn5MrNS&PIN%#z~TWj{fHa;B(ckP_j7-~u!$W>MuAP%ma(rH6jm^H)QpXPQjcw z%Fk1CTq~LOK0iNKOv-x?uMmcD?^%Lmp}?Xc+IU0oDLz&)TK^M}u~;ERNjOY3z25V- z&=79;QFofQ85LoRT*s}GqTNaJy->w7+(#(W8NUF{fr(Ls9ZmJ?glU1`;|D1cr|=VU z^d&Xs5nfR4*)Js}CC3*gL0(|}{jpgoDv7A74qc2+5Zbf_A;%A;9#>|sGPi2x{`zb@ zLVjyHRLrH(#2lss(0Dok@0-A|*t17Q?r;4sezrx)Eo3D}F)5_p4*=64$Ifbg<-qPV z4rrnRB)c#JQMJIVTt)Nlz9xE%B5`K4tr$x{@-qN)s91y`!;r}0ywcofh7k-C!0je3 za>!~o_T{%3<-&R#2(pLcG!}Z+E*m^4{R*UUB}5|zGXW^|HK5wQnM+WdVzqfS87>TU zB2ij;b&f-=gMvj$3B1-WGk7{mWdU-Se}$K<+tOZO8z~Ip%TPQW@J61mD*6<7v2;l6 ztDt$k5y$IIMACs!le30$Oc4N~yeDR0_Iw+dLbfevj^D-}y7+b5w|h=jOjN8ZJwRAb zC<8&!$kLy>7n{L!hAoY^h>&i+QLm#~7hl{lY@SV9Jy?k^uQLMfO$W144Qr)HpMvib z4<&4rH9>};)EZMdlJrUUk6l7NRb@rFK=S8_>o#czYt+&qopuz~c7O}&`R0z*JxRL^ zz4D1!fQ(wS*KtyS8^avZpKt6+1F5kyz;-P6B~biawNC4w_>~6J!5`}(h>e7af)6mL z(^mB_l~ix_Qv+n_b4N7PYkRLrik=bc`w0f$^*)EZ%^( zPFR?O^{ZPx$?=u#cd=j_LSi+vPfIMj-JUBRP^~?Ols(%O=f@rlJ`$Wc=A+@GH9fkt zSgQ19PGb2xbJrlWd9qP?4#6A(xSei5WK|c%E&NgKrKmMJFb{q7 zB1pC_#zQFHwGvfC&85ctbC%daHM;)>!N&3CVSp$hm-+GU!&cvy^p*Gc*Oe^(=u(>V z_zr-1Tju$QEy>N#p@3&PSDJkOrrlmuSm%UeIFpn9VVf57;g$?Axx3S9FMq>&kF>=s zO(&^5yR+fWX7=5!Z5)!+*aSUr@G$1OmiXd2F>kUXzO{KWKog=*YY@{aK%)g9dfHQO zG}HXV;{v4^4c3G@bMnW`Lju^!!}0LW>?2H`k@1IR3!fX39p`mv+IDmcTdwPEo0|7d zn@>Ae*aUsqi>N%4a^VX|t)_u9+TS1LXG6$Xs>y#(tC@Miw&c8SFrN0^f=a~u^HY_N zkJ@@bmi83qOP#ADS7Ep??>{v|E>QUN3N>^O{*A$gqgYg9_ujp4%p0O@7w2cMe8NjC z7Jr0#Q(eqHakA}#_6W2v*1ti_}N#Sf6S&mZEBI=oujApeuyg0b2)kc|%& zr9d--Idxy~32N@&$DACIqLKtPHK$o5#X7cRIIEHjM*V;b$>$4o)qHWRuo`Q>r-|qcYu0I7r47iP;}43Ybms%STq&t?Wh+opeWWuF(&9FqvG-IlQ<%~aA`5L$lIP) zCPR;OPs08E#&eWt{Vj%MM)Dnog3CDq-d_{3LZ~EK8!?6i9KXL#>k8%lgI&Ow9^d=) z@L!MOCjxlGE$s`xr&h2domNRmscEH>2`)hP*ENglf2|&RmW{OjXV?{^KrebeLNH#y zw-e^&Fv;ikl0Qawgjd!f;$zmd{VWtWe$C494hF7*3O<3QEL8b(w^*xHh=3C51YyWA zs2M+l*|+8;(6;E>sLE{uy?4T9Ytf5;JuF<%DS90N4dP1p^45*E1q`jEE+vZ2&t$NH=JO+Smm^ zkGwNtC*#f0@~`Z{bsTDT94PrruPwn(II>;dO_UhQ`uKd}$|r)kFh}V%0cdEChHD)n zxRM@Fk*+vJ^xpgb^}TBk6xV^QptY95%tPq8>OnF$2DwWP6w&uHON6b`1+RQLt0L;_ zgn1uj&;~~1fnJ8w1Yys?$6PCB_F-B%WT2?ol^B4V9$bi6TK{1UA2y04D?|0NtWXdI z0vGpzKV?t&UM9xrv5samAdi|{0P{Et5m_44@qPj;`<_Oj;y($+$^y`77=vX#Km#H7 zWBJ4QNgX~Nzhq@O)9-gIAZET=S@j(zM?a7nb+z>b-@h>JQDQW`aXHQ3c1!5hSJtOs z0y1#@dx3?d?~jh03`Hdfu@7atyB}OuFRh2@r7R!PQ?W(hPZYRBicRtU-lv)~Jxs-m zpD=(J?RX6BU8+tRYzdBu@!aKB!p|U|g_kf)XYVuL^>IwZ=lAW_48tx(2=>`H*9ZK` zk5>$wTE1_kDE9TxBNegt@0g#smw9~D)!VaAxXcl#j*nn`orLzOvDaqDKRcC-|FV)g zD6==dWV~76_A;-EX(@631ZUUcc$+l?XMOLy5FG8_8$$H{(#;tMmjkD>n*}%{@PPkeh0{gI@hqs8zb6q5RU1Dc)~69?6VB;DjS6U<>t{4_p@ua zO4^4T6P)mBhd$t}iwaK@hBKa5B#7 zDtduz&5mtEw#}2F86uxd#xA=-Hujf;VBL+PP1$X$up79t#6wKo@D;95tm%Nzf2?Gx zJ{PLxMJxi-CV$4ZDDHQqjS_|tHpt6@3QTn$N+i&Tttdk+72!g5@_Aqp4trRKb5d*z zdQ%`+1nZA@CfXrtv_p#JFdkFwr548`^nczH{euejMz6=v5K~?I42IRNoDcX{Z<>Hc zGGy~*Hvjb-v>Q2PoDzB1B)U+#1ICTLD%J$%mVpK5SUvET1w4_eP?L2Qp z8TP{c6&%8|SV4t4;*8yfza9Z6N_Q-X$5yJ_;Tq~h!61!2py=}B_zeLTGxZ$;=}}j zpbW~pGfIA(D2CKvJT13A2QsQonCsp8-`@*qra~oG>+7gN>9N#yYNA1LT>tsCfQ}%C zN5NeWra039zPU2F)UkZtV|M#R!sXeZWz(@Ir`a{KXto}Gzt32g9fYm6XKm8KDYGAZ z`6^RF(726LK=Q(xv8am89P!32@|)={(9PUy9P>AC+gFy~@GV@Qcc1t}Xfk_^=bKk_ z%UFDC@E)IUllhk0K+EvzM(@+sO}bd0RLIA0oC%<6wAaj3;Lvn!@sA_7q0v-92g z*Wcqb>FKnbYivdTeEv6|1DxwuNG0VBkH;nM%PprIA=h|a!LWln2xxS?*^{wbxoIN_Rw>yNEI8?O=_loVe`!#q`PqZN4f zcv!Ue&>n$fZ}#7Q#ICSE6f$|${z0e=x*#A*!rw0pF?&VxW2bF_s|$ehW_u*azts;?|HF7A5h_YjXi}}F0a%5$L%&i);O`gyssr`n zr0%u5R@X6j2L{?ZZcqv5gQj}l5P+UGD{4pyPe5mRVV^d~-wQ$Bo!gA^@ZOFvYNg}7 z1hbXLAWA;I@voiZO~Uvk$@EJCPJ{BVi3_Z1#U=@nY*1(N;r1BIc7!?5i_1`z8UKAM zR`Bm-AV1h;WOF+=L#(#!1JqR!bs!&h609q>l z?N{7@i|YcA+hr^)WWV9LeQks64ffTihW~I91bc(GyY}bxs#%CI?sgEIX^x+1(E|^=jQ{NEkHf|=?G7oOtJaS0PqeqWaj~{3H-)D>?^J15Ir0wTdo3sLzptE}F%$dzlVZ8j`E(;)~-soNJ z4}n*K3;YDG*Z;mO;4|g2t2Uo~1+}e}4M8F^_0nGgpZ};4n)=UccE%W1IS7@-=DQ#R z>K7I~>q5t|rfMEziVfTC&T;Lt5+>Uhr z`-ebBL-`QY-X%LN351FuKl9@aoT9wUvDSZ%3FU&CUhA@@VgWF}g|gmB{(qf)c|eU>|M-lTcMLOw z5n~vpqJ6u!<+e$Qk`~flZriPUX;DhrP>Mu5ttv|UzGo>dXrWZvv{055rKn^}>GwJ3 zsqXdSo%j3ekM6Ua=RD^*=d*9;K^1t?3l_YFNLEA)-&`>WXMtI^2e|G~?f4HCL<(0;)@p{>D>YR#+LFBRBSkYCWwXB&SGa8 z8HrA4m*3Dpd0N$JDbP!7vR40VC9|n!EG$O#wO0&{d5mV~_fExx%f4J1W&DD&#JO$$ z?%Y90?E-KV-p%Pxf|_i3FTfVMK|fP`j6tX1Q)vIJ4Yz^|U*074#CP3`10k#n34h!^K7n4K0M z$pg$cLlG*IyHHwP#(8*6e}BJ8!+^k7xBC^DzJ8f@(g9^^bjNcc1xY8U&jLqkTM^ zA%MvhiiFa@aRY+N4pC;Cxk0%J9t6Nt0xwA6679urVe_8<3I1&%kzfqMVwAx*@)RU# zKk!m)LZSqJ?BMdRza#p0m1WERcJ4Iq8UQhSJHm;(&3h~Q9 za9rx3+i+%nH5FDZM5QU#KtbEAE4}Vx;8Uz_-7UW!d`7!hH99S386Ghz1&yDlp!7ok z)WVZn=K=ZDW4`iJm;U)npv2#m4{owgDSS}BNQ150A8Q? z?+nr=mXTBo0xaFlw0|}KP9>o^Lab#4&c&)u*i6~4yXx7`bKTCpsCcUx2!}xs07e#u z8aoKVt+(B=-ZU>cE5sjP2ynEYtl=}aV#gH@FN7f0QCFb#{JYPKTWKNeXdk?pKmY#u z0||CbPz$5P_U)oNchMcdQrn@h=oD-BQ2?g?Zf_ed%yl21wn)b1)n7=tOTK{=>Akl3 zO5d9Mc*FJcM~ia;j@zp#OK~9fV##5Dq2Ko}N-OQ*UhkmwDeM-5&;tvitk_&^}DI zASZus-tU1q7pWH$kZuBzhx-3owdUO16a%B7tp-Lj&@SmR2dG{Nt9gZl0>PW3v-T+1 zF!FodU#==Xb7vkW=BCj4L?wssU%v-$ncR;AHL_Xd@ovq6wXE~P4)e0WNL`y_ZeG|m z*L%&ppZRP$1DJNWL*(q$O&1SR{4(z3)0!TNMmQi z;!hwvdfx#WFw~0Kfs^$^YuslxP;(sq7ob7bji(Uwl(m@-o20f&_k0W3H)(>v zkAe=stj2?Ol3bf{GmjMB4d2$54H-$yr7YF!U*erZ>HJY~L|Y4Ua2${S4w^r+4&k^K`*0V+j>>i>`(}H{Lm=*`4`R}#Oq;GGMK{lRY4@v>TRcfNna%)zzTdfR{-$E7K^W(1HK;@wEun; z00Qlp+a(Q~KOvzi!RWbc)PIgyA)c`?r+jiq3aD-(l%R3|@#wz#3T3W&P*aHCk4TF1 zphoQ6!||Pq?2ym`xk2;=FZrbx$EzGyr6kT)nm|73L@xF4+OJ z{NVi-_4$=qtfOWIdslYltVz$V_&hlVu{k;~kNz~j!t+bn7J$<05{in%QDP7>>Dr_$ zPGliF-<)%xI{T0<;m=$49&ch?!4d9%p=yc+*$A>#toRs-0rFE%mgNH-tN~q3U%*A08+OtKuQ(3 z55j*GY?=K(4ITD1Pej?k(qP;^J=RyN|2=?#Vl01wS`uJ7J)}Pd6;Rv$hoM6?)M~KX z$cdhUI%0e#P{fPILxyr=Oo&A@qmaG)D&)rYfslFEdK%;+8t7hGs}6sOr^^9P0}hKX zWj@`$8d+=#E3K?cM=tM8V$WdFQD@ODWM;vwQ@{E{k`sr(1gugJs<7qR%+Jd8&5%&R z;L|uchoZ+7-Yx|1*&3LU+q=2}eEWc&XPW#J#636J^ZYq&g%?y@+73pqg8WqV^S{R& zxNI2MX0FK`mYkkwzBp~uNW<9s*)jd%sDHZUhNgKxA^_I1_jy|!mBv_njlD^#z@>^gCa`SQ6p zSt~wB%D#=C>yWvqF!a(_ zB?1uRd`>rd1NW|FtG-asZ-)a8unRAeW$TDQgf+Nlo*@g@+b(kDE5DO*eKbjUTVObU4H9)ky4OLe%KU!1H3;F87rjk9Jgx1Lp zb}1b?{CGbLbP=EFwRVN;=#8KHPHzmlT?5t7>ifWRk#Sb$7uC5>11xhuR-5M~F%t8$ zgibOw5Z;4%9HNuWY$MrW8nx0uZj zR`gOC>>lyLMW`bGV0klXVrDeOApEkFiw~H&&_9P}i%3oI=Bs>Iy&NWc7 zu#Y*t?3z`G`(OW%GSB@L;vwF245Gx8UiX&u0W0{|HwTSsr||Oe-Qj<$;2>l`;$m_) zUJ{ZC_iDB>#{)7USjVcNT76$p>n?vJc|Of31YH0GD5N zX$CAy;)kp=YxH|!nX5Y$rvQ`N2MTT=sC>v~b&WYwEC>&QpPOZzUWDjIFG#ccN#_gW z2UKX>+z?*mzyjEpDwWqAU_-U6W8DVMJ5;aIe`fBZ%4)SI*6>4mCDPwf;Pg8Oh?RPJ ze&0nerv8cy)gZDB1avDf*K~Y$JQQLhgJO#eg?;DLgzr==&}Dsy03$F?LmJJW5QL`i z?&B`m5jLw$rH@OO{SRW$LUXXJXO8Y56@Dsm0L{7c70NU^$9*xBSC?~tv zSpY@b3_kA+syUSd*_2Xm+qB;ls_1^B^G&0mH`IbIW%#iRLW2?@XCaIU&CA(CRsvqe zlGd>>Vvi-LY6@5}cUM7NUm}!V_-L4v!TJzENml>v3OP&(VC4>vYltFmq;y%XRAr74 zT#9FaLhXwBl}RetB$ znoK}N>I5_Om#fKxR@0oqw1|04u_347Lnvm{wHvh4@6C3IcM38U_3xYY_O1@f9lD@&6O#kvyh8 z?1$0<{rj#wbX1Eyc=PA~0rDUadJLr3>PoMFCE7nK{~qK;NjcDpppx8pA+QakW-9+P za6qEaa`N^-{(2m8ut`3!Bbc%yjScuust5M1v2=3k)5aytPpp< z*EwXutpGFff&P8q=_kWRegBM*5KO;b1WKPHGk`-EJ+l8h(_+?=v@;)^VLBf76L$n( z1$FVCL8TM$r4QAoL*CFaD0;yq@2|6Jo<`0cR4OuE$Ib{JKrGhy=LHRteYFNcRghL% z1qRa4?_oRGx&$ffD#?=2RAB z!j3^5-Twhpp!jeNS}4d#4h9x0@x3{j`BX8p4)&6#_wPeQ1+l4r#-Jqqf@J-|!-Fkc zP?a?3duR_O|G7LM#!t@!>L9%tenR_F>;b*6!KZ-CLR-@-!TYfRZH_i)8WGu@sk3@+ z1?TBerS}44R0TN68czh%>h?)>7N^8<1z|)2FWLUW<=ti8$KSlbjE zntnbpcy^vFz=1pnY;VKo6tCs%n*IyH70w1R1+-cj&y@jslA2h3^2ADc^$U!G(b-T4UzRwC9~XR$ zhLz*1AhTnqI*Ob|#J5Ks;w6M8g_tBq|5iffE16 zmrDE`utIqq5g>*!#{N5(@#$X=9PnN$Z19gzx^z*Ch7UlWaO=zA){p6Neo#<)D)}5# zowK@JYE^BQnjSh)a%IsclZ>DXta2PdGr_tAMYc90>#*QacZi>^{&QdK3eejaND8fD zovUwAO;1$lry8=96Cg@ z18V>WL8%qm7l9Wib6BPkcBWeodC|xI@|+qwyFq6I#nzx*)`8V?u`mLLJW6wF!uYsNm-XQtwgKTgkGFfaUg8S#hQ zOabUK8q$Bz1RDTRdYoG8x=?)L(vjmOn<9$*mAm^+;vP#QQa zKs#M$T^oot{4jxHsi86v`<%N-|6#m4t2MlG1`J4({4A6#dBH8;WjG=ff}CiOU($Y2 zsX8cm6;C6fo`>?kMfoPSS6V0Rm&ByV0KCNd?Ecnth=lZ>Dy&&+Qw6pl3n%~|09FQp zBT}wz#ZEn`PcJ?1Z%_4L0bbr;fX&=A*ikr7LwFUv7M)0hI&1+&|FS-ewyA%5rDFO( zKi}YcBpa$4Bfm6ML0Hbk#YJ{`^$@$NUv`MJJYPFMt#b#Jet)RkXl;YMl)s_uK)`zE zP7ae}Z`=DR2dm%y-ElNxU3w66ENlV5{ci{+pP8Q*wnPO;hoM0TXxGbEt-qzUTY;S6 zEDm5Y9yV)Q&`lO@u}kIqV3hyB3R#sOwZ6*y#yCWlf{}a&)Ow>?ZQ#y%aSgUI${DkT zi07`u7h$jJL)V)1sWWbXqR6{bpKZFHh0JPx0-?xeW^MG3bDyQKVyVvX=CcdpKt0ci zKrx0iaAl-#=2>KL1>`WUcV`#mAQb^(F!xEWhm?(cof{oozdd8&<+HftwM2(%y3;;% zCr4Yd)v6n?%2b)=mMj>InM2ApSpIDzIWN0t}ERlYHG}4-bVc()9gxU4-$zbi2&O7g3^dK9qu~ znR9R-E;Sq;z>EhgkO)a*6qXKaOujt|L|y9#?`L_er75Z++D8%sroe2vZZbBip>|~ zJw3AWYt|aR5ckp4H>8KtX~H5RO^W&Hs6cY*=Pw3iw)Mvw+K+x>er++;>_*IwP#7^7 zayWFXlu?N3Fl-zfUb_WshWX&bpB}!pw0uDh5KLIkA0+?I*fhebOK~;C+rcL10cd-yv2wqrx@xC8ji^+eyOjoCMo=Jc#Vlr?!eg`?wt&ophZ-Xq9 z@PVRLeN7i*V1SbAS^`5L(698PCKvrD)(^+B;c5}hu@L)7nnFZeOrUlE0;K4If)c z5>!umu^&iMzd0C?Z2EK3mtNeP|4A9~hnT;i9>{6P)v?_AEm?DL(dwiA8oIfIIsunK zWUc|;uo6|m3JVLXf&}GNV1<09*l{F7+i*!Vlrv9G@HYN>!%>-6de zI`i`VlD+IBjz)TV5gG;jxw=O{*Lqs{uVq==|0IHCZB``t>1Q2=bPXuqxQ_3%3_z&L zR{d}2ZmdHDXD9tqYi{`@Kk^LXoy0I{%A>a?b!=dnwA`{=Lf!? zDn!6Wj>FzH|H;w>OBJf$Mz(2p)15%V(j9V|iviyPgkd`WrU31^NnC+SZ2#7%TwGCP{yirMQ@RRUYLsme66olvg@w+W# zuBbN27l5TCj4?Jd0|Af=)8s)rB&E z9YEmL|18%NrXtD1Z&dwjFq@f%2c&6;Wj#qaD$&{?Art7hP&!;e6BR_gxsFl^lw?6gtw8_K}v1$_IXokcXV`DKGC zV4hogp%KymAd>g;3#jBLIQXlSe`d+kCw=G6om2VI;0qjA1HZNLxsVDbjHJ;QEPbUl zrk2Zql)g_-AwMf8*0@9(rE?6whoZYXW|io!S8G9!$!PgC*ho2<%JQukNfmk*C)tQW z#e~M8oy&et{mIWW9gJ}9hA$?7miwb}fV*S{lTiNOL&(r-kJhekOxOLnR4>zlH6Tti z4`6IjX%Y9lKBswi0mQeQ8Ej46cd5DPP4(06*@%;zDec*SgL)5pKmkJK9xTkb{xmzP zff+PBXC%uLT(ESDdhFzR*r++lX0v<;)Vf@QHg!ansxipps{yvK4()l@2Z16D-5N!fBGNn*yH6)S*hT>UctOCi!_TK@+o&Aqfl z@andjrzYXf0OPd~bZsg&J76KFLDeqbzk#Avf`r# z+FElAl3c4mnM7V^Sji(*PzBaBnbUXK-y1+xY6>!bSe(dz_$jLd>xc4Ecq4m~=9#G9 z)_8C&l3hn1+h+JbDCQioj&_y?0%eC}Q79yP8Zj;BTjmHgL2S0nHG*oXrb#`NFQ^ip zf3H;{Avt%Dqi9_kGSMtZ@V5a$vraJ;MTme+4E yAlPfWHJA$^SySVz0PkA+1ICQ z@%+X#t|-LwqL5X`E{*89>5E^putng0OT(!)*b;XgBy0^Uw&rxUbCyL2m7N=bQsaRT z0fnR`V56-zJuQu?gW+~o@4qFDR4*00y3%Ux$aCk7J^K>_ftez47%J4e*%r6!HG{np zS<@p8EK3GLd)-63pKdTPq5bsRJm9k{KuA6e&;6su#rfggTeSKiM_=lXEl%1`POjW_ z8hJGsccWIIqzp**V93U&tlw2%S69%awOsdW;&wZ*()-dq@uy9TwxKu>SE$s26jd_N z*x|LiCk2h48*1$(J)Asr<388hC$E|8XfazZ@XoQEvh(w_jm@hPibMnMSX=$k3Sy~V zV+p5g2?T`JB0vH7?|PLoxXNzuu$@({j;smWjmRptc~~H153lPhQOXx=tHqfqAZM@{ zELTd_>RVgcWWeHBeBVd_X*j5Y@ljCj)na$MtL-Xzr>&*+J0xVOZSMV%WqivGG(q-w z&!QCmxD<+y3M~ywxeqG7pn*{{?A&!9Wr?A1M6y*&k^vYq`oQ_oa5Dt~@o$BFN0q+dL}dJ) zL$Ajows|V6z@7{1_{QChZC>D2FzZ@`63dX~RK|VQa?v$oKbys!v|gCsxj{uzuq7wW zDiS77u(WIgF=g}I_{Rlm0ywA|qF^nAEw_Y70Zq^RIZ$shwDCG>Pu464~ zBJ{ZMhzN$Hpq6HP&>u>ZK4g}BIot`m$ikLeU1THtSWjx;n^5r;NH2Oqt2NEry==Y6o8JfLm>rlgno)e= zNK1^=+;l3Ce|92x$5{Sj`HT$%yJDHF{EF-V&oCBd?r?6|! zK&oskSRXcnqSDm_8{g+IR;@0+gzSr@7p++**#JfJCx;(mVyTxAcZeNtQb)RO5z5gs zG&JmgotagjIt8)uffH_^CfjrkhpBxv0Cf1lD4=w{0x(u+a-ph!-kUw-0vG;6VYvD!KYGTaE!0h0lo_Iriy_yZLq?F0WqFbbobOMXKIY#bmMMo?!8u{YST9CpZR zdCTzyTc`(NutdCiX zETg-MNqkN+vw4dsC&&R}_2}|tN8aZMnu8AqD^Tx&AM5}>hu(I#Nft+J{AsWl`|r=! z2%jI0!tW}wmZ-o0M033S#S(11INN!kDeiB`WmXoq@BQnGfOA6Cx%hLEjSP}@Gpxah z_0HZaZ=CeQ4@;Ns+`d((yV_~$!&ukreX$P8sBTtQ6F8tv43D8g995@R>>(rrH;O?2 zKTXt}k^yaq>H*F0L+(we9dIQ;PIf*cavrJ7lz!GZsiHkI_~Z$gBda02bTx8_ zfF@auN+nFkdVcp=b8ZM4d{p82 z%Ni2J6~VigivrIKr+ zmTRtd0Nj_&Ae|Y>tfbG&m2*qyw{0$Xr0xzv^L(&mRRfN6NWlh9g>lHOexy(X^yk99 z>w_s$lk?z6m-|645j<*#P{q?l0J#EgkE1 zQ2)jstYI>!nhvDLbtsl5G=eY#27dhsyB}C2J%cUqA@#L;M3`{Ha(7OkS$_L`C4Xkt z?~on54c8@t@SqyVTlx$1SX4O(d5iiV96-C5Ag_MokSHrZ_7MTt{9t2y>c75&Evgc< z=H*Zfcqb(j_P?t^A$Z73i|8YmJ@-mKXlZF#BfekLtD)D4Wsqq*fvH8eNwPBAZ@ei& zF&@d~ZsX5}?-tctEr~)KdBB83j<^~%BklnP;Jtn;Vp(MXuWHbKCmC}P!}8MknE@>- z;^$!~PYfGwOeGc!0rFD7ixoO;0z?C4j=h^HT4xQlR;<6|qY7J~>wz~zXI*W>nI zfn?XskT($SX$3B(>)==DdJRE|fsia^`D5E67x_g@xCDW$p95IOX12Fq6_a2YGBo=O zRT~zD?O_UUpU%uFu|_$isICpH=pGZ3i?=d#;84$^#c= zE!d1oZ^t6ahqj(W1Y2R#vp9A3N|-MguIvbp^h&iBMiX6IC$>l)YlaE3j}iG&I7>3B@-a=@H8sE zb!i9(l0gt}!TLQQ%f;*q7w~0{%Bx!#M*cuwbNcH^V7bC}p%QjN`U_dfVRxPFVDXxd zakNSfr-ANten)kMlCQ;0mWQ%50i0LWWghzPlaghC%Vjx($uS5U)bHxSilFMFtrkaiv2nzFYR)K1lwP!hNRlxylnSazvIsK@$16oZZ}IKbBc%KA8qUV-+6t7mE>$x$xh6nB8?q_Di$VPFc!kx~AiznJA~6~X}^GOM1kTIaq^Dp^Me4(;#F zCQIMUfq3x)H`F_GXX`(H0P~q2;q%M?^?!Om7fkHgzlWaq=MP}P&xN~>{q%o&AOneO zT-;x~lmA;UfH1!?;gktW-<&QqxBp)V^I_(P`{rhn`)Xgm`QZm{4JRc7C-Z{`ZLKWK zoviHbM4as`h3T#q=C)Rrj^-``)`#rvemKJEOm{p4cR6J^$((|mbUO=sODns5a7sJm zOq2Qa+1KN985wtD{@_HpJJm^OMh>6S)pr#4%RUIb zb8zZ;#Z1}cNnL!IHsNtJqxrxD@yPTYgR<8%Z57(-GeR>jKU~<8NJ)RUx2I+t-6o0E zN9xJ@@O2%%EcHUfGr}=|bllsc{07lI{?EvaixD3hYG)M7+GUwE?>@#;+ZS`~c5l3c zt;|E$&uuxp3OVUOL6$V*yA@{_#y-UmweLHHgx`)2fin15jSJv z;l0$cM(UPRUE$_;;!cURkj#Q3S z#@Sm*4(lCB=)I-ahkK?;Ms(l+EZ;qvhK!s>Ja&|I#yOW}K1Y{Hl;Xy^@p5VIrv)F1 z9b_Dcrk2C_R~)wx<)C5+Bhe2G_l8n>I`LJBqO0z>5lv}3(d;DE316VtTn^R@xZHG} zXm=G~6hB8a;^jMax@ znWb_scGtc0Eq_d^2#5$5i`O@M~`|iUx#G8o+-@i*}BR*ZKz41t>2VOLi=slHa ze4j3gf5d&N@lzH9+49xb@FfX+LE0w@|B~>$kVxj5H9N>uJ35t`PdPeQ5&-J}<8EZTjwobhq8RPi>|X}|uX`j5WvGEd;iAd8=~(U$uxp2tqxz9*mPnS_6c z|DtAh@R^0ZjjpfzmYn)~*+D#ATXXmAZVSjocSw@Xo(0l(`*ACAJON~Loe|~YS7fTw zbDNkK_y%pro=ScGy8V%sz)LFibKjfSGt;-;^jMkVF2q{!4}(KLZf0PrwP_DN6<3ZM zYWyUPk7=jc+0g-6ivHx7(x`@bo4&$v!K+UM+H?&M;Tx3w7UI5d@S((Mx2iaIl_1{7 zktY=J<0R7QN{szvIt^n8nIt~D%$8YQJ-7|ybQbNN{PhZ#z573P9<#-0LYBJb8AWw0 znbzCK@oFegFX^7%H3@b7E2NZr#7h;2d^f3HWA}4%+rPZpK*rhAb0vHm5Ogr zZftt*e@Lj_kFTWX>9}O#Ub&E-J3w#H?2`xZk0d!qL;xQV%SJA!4T{I-jFG7#>F7#E z@!10ymPwL@2_L&Q;(MYwmFSmDal}95b6M8-KvZ|n;ozyWrCukEsZJa9y-rZ=8rf$# zQ4)SqT#Z02iBI^HuKsCvyOx7qW*B~+GSX};94B^mx737~a{z8Z*2=d(DcE?Vr3Sa4 zl@{U4;)(c&gh@CFkDWy3q0+Kr%82!*s8tQ8=kXH#iaKCmBuV&$xwUINJer`~lqCFS zJ0I>+npj{7#b#Yh6v*NMXS6T7GIIU!gp$qcaWi_6;xv9IjXO*YABg5t?HG#NMr2HP zKk8K>UsPAlJ^$3qeS)_nWgB&NW(IEvn1{w6!|lo3r*Tg-%_w`K13!{tyGqrguo>IF z@I%D9Fba;DMCo_C)JEF2UB4@LXp^5QKS4TD+dQy-r-jf;~|OH2%X z@IbruEPey!Z0UYqqC0h7_Gc}DJj48*v(!tPOXi?>Xr9b9s#E#hK%<_G-LG*=3Hhpi zUv`e6!}42>a;Wa6A3jU9>)7ADGq}3|_bDFJldEh{Zqux(NC3Xn3Gt(+`j1Hj5^o}3 z38~AY(tOmp48tx_9k=J>4=0nVqX@Dpp>^CcKyBczE$&ThmX8tKjFw_Rykn~Tq>lxa zGfPPLQE1+%$w`7f;SVR9s}keH|E2h^o*6xA54W`;%Ej{R4bY|mW0V*T=pqiZ#RAYVn#$cri;zPyqt3({f zO{q@a>K~h^M$CdX-|HeIP+FNaPFY>M9|l91mYiOq56E z#P(h)>CO(mxwn= zhFO#(h`UuB&DIln6Y%Wy?qUB!j#lioX85*+<^c-@_A^SZ*Sz2}uN>v*2*W5&rb)%0 zd1A(6D3o+O{c*7WGpFJ^=hPpTbPM%j_DiA|XIFWIY@^a%dT+&p6VEx1d!!tyExt*0 zlB*{qJ$m!d7`{*2(RK5};OWE?+=`xewu(wKSvaS{7TY2k8BqRMlTFH03nh+}*56+=D8y`?0sEpXwYAW@dk|u%V z;*Yj(yMW&>;Z>QP+5fT^pNQHA47_e`r}1yXr{om75$oc(`Zo_p-fB;eTuWk?aktk? zHLstzAzt|IlWfGGMX=MQ3H)M->8+QPG>7mpc}vUN^5|3B&JgU}f;Wq35&;e|Yf1C$ zh-`c=)^MW&<2#wezlA=6uTfGx&FI;EdUnUv>*J(!?-LK=|K=7NPI0AWw<#^>r!4Rl z$;&+WS8UG_k*FZD_rtw46DAD@ox%eOBGR_1S`B-PM)&XVDU=pyH_0fJ-fVZh0?!hO zf*vDLL{&q2cZ=dfhdx=B!ycqV$w6ft~s?*(BN=wIgDetC+v)w4EyLoDIPo`6y+(%VA z#R;KKnlAJVV?J5B<9x}ezv>0PEdqj~xA2(g`}>9^WK`edPUutyUKBEg$~YRCsMC^5 z7dq}M>GIkz#_pASbvvI|59w$`$dlJe$9+y>6eE#zu74^WR|Pb(>lC{9@iEoTKz*v? z7*}oG6z(5WRuZvBjGJ;)$3xW}m@<$g)Q5+65MxiS{y0pv3sc8W5HM!GwPl;;_Kqh? zv|IX8R3||l6Cfg4dS)uVr}b!yP)iyPu6by?QKC z)-6{@MEDdTA5vaFc$=B4yZ2UQ#itXv8xp3KBvQbwTem;aqVW*u8`WolBJbt#o9uiF zBT2_~yreRL+qz-NE^;_)I)zGyWx6RC9UtJbi;t7{XrFofQMed6iC|q0#~g z+Gsvbd*?(^PsJ^0$@OmLld1(Hhg#1nqbp?TckF`a@R5|c&$&v)N{&!cbjs$fH=|9( zZx0^7@XX{%L+jvReM9qDLyT9IH|_>Q7nyQ^*XuNurg~G&tZd(b>t+7zRHrOr;wcw# zm!!hs1Wd2U5&`V-=Po_FPk@Cecf{3Ad3%q(xxtm!iCZ$PsI;_M{8YhL=vz)6i7}PO z$C8Z~cPM>wkFdimf<#H?>8v2eV7Z@4wH-D>tw1qHA4DM$XJjlnkV(X(OGS0#y9|1b z=xh7-r&98Ss9_Q4=rWy%A18-$ZRD$Q!Gwh@O11ODS4ljAN3$E|QK8`b@Fu-XBzc!R1>*iN^pJ`FQipJ7oy_80mG^ba}e& zk=yubQB0@Fgz_Z5b(6yfqlEX>7zxQ1s@|1C-Uh%9(I*h>jofbMXOMBzMA_1NZ^b$P zqkY7^Dm#Zs+#i8klq!5enJ`Ge_oepW9|@haqk{zbA$p_xKbLUQE$25WuW$;+O=#86 zb10WX1HOrS5X?x!F z{C=iatanImf}&&%egM-}vQ*{hTld#Hfi|7AYpyy)rKWdxjJn_kV$~T$m-vj%4k8cd zlgF6{Rj)^Pnmsz|sv$Vqqns6>u88kTSv@bGcK6gjA7?4DYrvUX?C7ia_y#4l#)Yg; zdh>!3W5A8Ch-(o)0#`%$+fq*5AH+i^GYYiiG)&(;K5-$H5Ln6bcgKlU5IgVl$t5FR zhst>uJql_R`cJoi-CIcM=_QmkViLuxTapAld2|I+tWSdSPmmT8m3k9DNEVIcclNj6 za-ILaX@l?a6903U`IAYPc&H3_H`!MjhaN}V8SneRh~N_mc&&LOzjSu8wptdsG~!{4 zVxmo!5Wr_rVpmJ>U?`?rF7A9eRCE(xre)tBp7>mj??~LBa*F5fr!o#D(4u(zKjQ|L zZq@pGcsMxVDn1u4r`iq3S+xdUc+5V+e{SdbX}fM+UJ{q65l@~-wSa?_{uS4OTQ>Sz zk2~Y`cwR{4S=lB0iCh0*Uy-0M@xo36%kejb%JQCSLzf3NwYi_&5Rl3@GLRbMzZHdB zknV1Lo2@>6G645Qb|)S?W_ay<7{5zku$Fw>D}2W?CMuuwh|0K-!K?aW!2MDKaNe32 z*#`;68h(b(LyxF-*A%@>>Sv74a|w?P;YYxMbZ{)=&A}`U4B#MSo+E%)YAe_0`$|_{ zhc>eBy^fnQHeY-%Q>-k!?>c6(BogfzzYjU9LxdR4o_9X%dgoniM->AIWrf@?_0szA zgrHuc*Qh;}GotMM1FTe$$rEKqw`4fGSAQI=6}ZM9S4Iq;_@Va`WKZ%#Z)ebLg8_pu zDVLbq>XTKb7MYm7k{Ce_VHD>piG}{eL@>%TuJ<3tgP@n{^Spoi;QAOoBPDlI9W|qI z@8Sw?Ieh&-NZ~0bTTB~(W^bo-{N%P9XSVz9r84~P+{4ez(g@-i%ymhWy;Mi`OZW=y zgtD{+L%!S2y0@+SL0fzrDA?4dAxd;8ei+Xji4sR;obs3`qkPcFd50e}SBT#|8jhQg z3yGFimT&XbO zLG~r3>{L!ppRByGuQ%zwPbF?Csz9}CpE;9+Pe|Eq^mJ1hGuoaG+grtbRL1~1PAHF7`wzGqva*UUEXN?6C>OEAdAij->9hqF0$+3gu z`5|?kJp)5Gs7{mJjY1>#-IGs5hqk$4hC>oRrp8}KEHGJ0A=XF4glgwDCMx}Oe7ah= zyLRG<+%Y#NTFIepcY7Rm8(XSzYil{klBiCb-x*+ZBwMK5y?3#seVSl11S}Clm1^cy z!Xp=#kL#}xv6-&Nl#WdD=(v~h+HCuAe3O!!hJPjY6C6)`Y!=+aHBUCww?5e6IIVR+ z?9;38f!)@jm#3~0WWqAJPQ>V34wdt|#8uIL*-N6By^%!2{4oP1i`wH(=>lU^yR>J1 zJ2(Q8ykrP6PZmFs_)v*^Q2-uYxbSi|hkkrmESn%jr2g>HWS3{mQwP zofIndpgMkvj8~Z~bwi~dpA%3g863#vH6GU~717!0Vj=dH?x47dy^iX1O60EbvFpul z7WeFoFPBWEoHUAbxs@^~m3*&E?39Boh}kwRA-Eq=4fI12&%Y5m)!CpPk0}XBoFka_ zSe>gNBw;&lWgaqg!HpzMwJXw^^t@Bh+w|yR;EP$K45PD%6;~)>JNDx)iFqK_#)1oX z10Aq$y0$lMr;=j5gARBn%!#QZot;$Cd@XeM9+k6Y?BG_ao!Zu&Rn?zv=@*vrz0{eC`r;%G+=diUsCsz{A4>I8ojwv>?5istqH?}y zyp2yK-ta!kf6mvPKO!i-rOu=RD1YevkvpGkl8v`y%0=W*9UmH^h9uGH-98K|?L|L6 zC6jtP%Xki4&c`!ACMmgT>?GYZN~nBR(shWIZ|QUh;|ocYpAg|F0S9j$uflJnf6BZr zb6*R0is6GKUVYYy`_qU3zD*|n3p!RZ($*Tun3XJ zhsUUl7DAj5!|Z`1`mmfhC%KMO8R)*U-#*+GDXG5$~6)nNgN0W zIbHC`M)K)lr#nuwR&6l$yuf$Oo%ZuQJ{C!3xZq)ndJ{itaS18ovN=-3w2GZ+6cf|YJhVd_1R!F@{N4Ty~^^*LsadZ$l=WYJ}!{cr4dKj)q5?8=3w9)y| zC(Y`Ea?$N7X9=-i)RLjqf!}Ny_{m54*!?3^YS?&i&&{_M#o~T7LVNZQ0+rYmVti5u zQ>dI6AW1Zj&BO?Zk+?;p^gVpa_&{|$&vhRk zQyTUjop`cW{1b6U2tyM|f`ALsL41{DBI53hjtFW<2xw%+8@x0mG5*xUhY19rxO@zK zd1g=nKP486AHnzygp8p^rS0d~3xXEDO!i`@+U1?woJ*hw%VShcq|Cf`NWHmv!C6UwIqoXpei{l##&$~A(P6K zuz*2g3_mw9_psb_D2mT0T&`*%G-1cYowA;|1M;igV~+>u z@5YbH?hwLF#Q084x@74*Q`8}zz|F*N=H7H~>UOO+weP)45sc$eCd*3LNAPzh5EO;+ z$(WBjr?+A6^$Fp!m}4#{Kb#2ImazB4j{R6mBU@aLwoSUOf_o$dYcq7}UJaABA2Tn0 zU6Mi*#;?Hg7g;>(l7dkQ`_&zR1nQDR2`r+>9&991UJoQIsv-*d`YkS?v{G!x$m!pS1fSVq?^H%sxqE)0Wgo{q`vPGMaHlw4zCGz8FzF`jI{>}pXb zv^AM#(9=t{?M($>p(Yd)}F0iORdjtW4d`CgTB!lXNc# z#_5qJE)7S$JC2D75P7>Qs^fGi{thuw5c-s>rv5>!JR-;u^$lNrQ4hIdwa*zuuH zJVh_muRge-*a7x)%t?A5>0Fr=8i@|^f3Zt@-^vPWShx4KU6b6~zu#1rN*yh>oIcof zu{aJp z!|8*MwB-doKYdJolzGeCEkXF>^K9++ojEfB^?G8TKHEt$cG%teq<`om#vT&6as0FO lCQ5|!XvdWb0xB5$vfq_)9;;&LRQ&*dJC$~A&rvk<{(qh<2D1PF literal 0 HcmV?d00001 diff --git a/docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-hash_join_with_spill.png b/docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-hash_join_with_spill.png new file mode 100644 index 0000000000000000000000000000000000000000..85a03894753d595a7258444eff80d2f1bc3df5d7 GIT binary patch literal 496887 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⾢reQDifBDBX1qXgqbMaNgtw|_^#%kW? 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

h>+hV~Y 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 z z9-P=IlffUyHs^9KXHM)QUwPMK=y{jdkD}E(Fz+GVi9`RT@AxsF+GT)H;3xwcq@GAd9772XQI<*Imu& zY}e6-6tk75fmqI-^{tk^oiuS(*ZUtZQ*Y}O#6*lkn`H1k&=q9ILjW8;gIFu!v`lnj zIh4@;$`%vn^pJM5=o6XEWdmIZ znxB}&!~Mm}m7RBX5#9_a>x|%r1&&0^N@($YIlads4>b2X0uHfW_eH7?Yv%@bKhF=8 z-d`|?X26VAH?QT4<;3Rfs=847TBk}p%lG>-!)WjV%E#}v#tWQ6*ignHt}XQ#3v zYq&D%^H8$bLL~KP3QECZv#22^X66qy=0RA z!TrtD02Xh24V3vB;zsuuXrOJ}VJOvYaiOOr3o>r5{<=8CO<9&-t;UjR%{zmf3wn}b zIrQrs#YQ>0$5!R>0)t2)#O078Qefpn;81pSz*5N_8{ekBy^!v^YcL0~B>N;F^|yVp zoRs;?x^-h#pJpRzf-Af;p-fJy&rpjJ(XA}hl@gHaoz8VZM!FP;pBsF&C)d}ewt#d) zD}^S8xgay+&1jVF>`!dS&Rn8vGbb(c3ogZMvlJGtij1p`K9?V`DoZ1a$)Yq;*1Lnp&739f;aR`HiggC(nS~E)zao|# z*DlcC{}{xUh?dR`ZECR0s(#-r$6b65Bg4?eC7xB6-{7Iqq?G&gAa6Fs%R|Orcby*& zA|>oxZ3*!VrX!N1+fWzqsC&8}fVN8YL~iRPO@E}&jh;iOQ%y-nTHOj69n@to zI4n@7ys*BkZvD0=?n+z=kuq0)&a*CMzM3m>;l195Xk+EY3v*tWRrSYqgyOH1FJy=n z>@e^86+vfAS6}<$vz6&InLQq?lxUQy$ouvpEe11myOtTMCbGw0jnYl1#xV+=O@AV4 z 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%0ATN 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 Oesa=EQkfF>JpLDlhcCSV literal 0 HcmV?d00001 diff --git a/docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-sort_with_spill.png b/docs/design/images/2023-03-13-tiflash-supports-spill-to-disk-sort_with_spill.png new file mode 100644 index 0000000000000000000000000000000000000000..8225d8462a3e2866b24a276edf5382b8fb9ed377 GIT binary patch literal 223722 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

uUut%R0ey50fT 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/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 literal 0 HcmV?d00001 From 47e527b4d1e2f1bf4364a3e1bd62b1de63866948 Mon Sep 17 00:00:00 2001 From: xufei Date: Tue, 14 Mar 2023 12:04:38 +0800 Subject: [PATCH 05/18] Fix agg spilt bug (#7063) close pingcap/tiflash#6993 --- .../tests/gtest_aggregation_executor.cpp | 122 +++++++++++++++++- dbms/src/Interpreters/Aggregator.cpp | 52 ++++++-- dbms/src/Interpreters/Aggregator.h | 4 +- dbms/src/TestUtils/ColumnGenerator.cpp | 43 +++++- dbms/src/TestUtils/ColumnGenerator.h | 5 +- dbms/src/TestUtils/FunctionTestUtils.cpp | 14 +- dbms/src/TestUtils/FunctionTestUtils.h | 4 +- 7 files changed, 221 insertions(+), 23 deletions(-) diff --git a/dbms/src/Flash/tests/gtest_aggregation_executor.cpp b/dbms/src/Flash/tests/gtest_aggregation_executor.cpp index 1a04717e590..898716b7dfa 100644 --- a/dbms/src/Flash/tests/gtest_aggregation_executor.cpp +++ b/dbms/src/Flash/tests/gtest_aggregation_executor.cpp @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include #include #include @@ -20,7 +22,6 @@ namespace DB { namespace tests { - #define DT DecimalField #define COL_GROUP2(a, b) \ { \ @@ -610,6 +611,125 @@ try } CATCH +TEST_F(AggExecutorTestRunner, SplitAggOutputWithSpecialGroupKey) +try +{ + /// prepare data + size_t unique_rows = 3000; + DB::MockColumnInfoVec table_column_infos{{"key_8", TiDB::TP::TypeTiny, false}, {"key_16", TiDB::TP::TypeShort, false}, {"key_32", TiDB::TP::TypeLong, false}, {"key_64", TiDB::TP::TypeLongLong, false}, {"key_string_1", TiDB::TP::TypeString, false}, {"key_string_2", TiDB::TP::TypeString, false}, {"value", TiDB::TP::TypeLong, false}}; + ColumnsWithTypeAndName table_column_data; + for (const auto & column_info : mockColumnInfosToTiDBColumnInfos(table_column_infos)) + { + ColumnGeneratorOpts opts{unique_rows, getDataTypeByColumnInfoForComputingLayer(column_info)->getName(), RANDOM, column_info.name}; + table_column_data.push_back(ColumnGenerator::instance().generate(opts)); + } + for (auto & table_column : table_column_data) + { + table_column.column->assumeMutable()->insertRangeFrom(*table_column.column, 0, unique_rows / 2); + } + ColumnWithTypeAndName shuffle_column = ColumnGenerator::instance().generate({unique_rows + unique_rows / 2, "UInt64", RANDOM}); + IColumn::Permutation perm; + shuffle_column.column->getPermutation(false, 0, -1, perm); + for (auto & column : table_column_data) + { + column.column = column.column->permute(perm, 0); + } + + context.addMockTable("test_db", "agg_table_with_special_key", table_column_infos, table_column_data); + + std::vector max_block_sizes{1, 8, DEFAULT_BLOCK_SIZE}; + std::vector concurrences{1, 8}; + // 0: use one level + // 1: use two level + std::vector two_level_thresholds{0, 1}; + std::vector collators{TiDB::ITiDBCollator::UTF8MB4_BIN, TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI}; + std::vector> group_by_keys{ + /// fast path with one int and one string + {"key_64", "key_string_1"}, + /// fast path with two string + {"key_string_1", "key_string_2"}, + /// fast path with one string + {"key_string_1"}, + /// keys need to be shuffled + {"key_8", "key_16", "key_32", "key_64"}, + }; + for (auto collator_id : collators) + { + for (const auto & keys : group_by_keys) + { + context.setCollation(collator_id); + const auto * current_collator = TiDB::ITiDBCollator::getCollator(collator_id); + ASSERT_TRUE(current_collator != nullptr); + SortDescription sd; + bool has_string_key = false; + MockAstVec key_vec; + for (const auto & key : keys) + key_vec.push_back(col(key)); + auto request = context + .scan("test_db", "agg_table_with_special_key") + .aggregation({Max(col("value"))}, key_vec) + .build(context); + /// use one level, no block split, no spill as the reference + context.context->setSetting("group_by_two_level_threshold_bytes", Field(static_cast(0))); + context.context->setSetting("max_bytes_before_external_group_by", Field(static_cast(0))); + context.context->setSetting("max_block_size", Field(static_cast(unique_rows * 2))); + auto reference = executeStreams(request); + if (current_collator->isCI()) + { + /// for ci collation, need to sort and compare the result manually + for (const auto & result_col : reference) + { + if (!removeNullable(result_col.type)->isString()) + { + sd.push_back(SortColumnDescription(result_col.name, 1, 1, nullptr)); + } + else + { + sd.push_back(SortColumnDescription(result_col.name, 1, 1, current_collator)); + has_string_key = true; + } + } + /// don't run ci test if there is no string key + if (!has_string_key) + continue; + Block tmp_block(reference); + sortBlock(tmp_block, sd); + reference = tmp_block.getColumnsWithTypeAndName(); + } + for (auto two_level_threshold : two_level_thresholds) + { + for (auto block_size : max_block_sizes) + { + for (auto concurrency : concurrences) + { + context.context->setSetting("group_by_two_level_threshold", Field(static_cast(two_level_threshold))); + context.context->setSetting("max_block_size", Field(static_cast(block_size))); + auto blocks = getExecuteStreamsReturnBlocks(request, concurrency); + for (auto & block : blocks) + { + block.checkNumberOfRows(); + ASSERT(block.rows() <= block_size); + } + if (current_collator->isCI()) + { + auto merged_block = vstackBlocks(std::move(blocks)); + sortBlock(merged_block, sd); + auto merged_columns = merged_block.getColumnsWithTypeAndName(); + for (size_t col_index = 0; col_index < reference.size(); col_index++) + ASSERT_TRUE(columnEqual(reference[col_index].column, merged_columns[col_index].column, sd[col_index].collator)); + } + else + { + ASSERT_TRUE(columnsEqual(reference, vstackBlocks(std::move(blocks)).getColumnsWithTypeAndName(), false)); + } + } + } + } + } + } +} +CATCH + TEST_F(AggExecutorTestRunner, Empty) try { diff --git a/dbms/src/Interpreters/Aggregator.cpp b/dbms/src/Interpreters/Aggregator.cpp index c3ed6e815bf..c0b4d58a017 100644 --- a/dbms/src/Interpreters/Aggregator.cpp +++ b/dbms/src/Interpreters/Aggregator.cpp @@ -1211,27 +1211,56 @@ void NO_INLINE Aggregator::convertToBlockImplFinal( }); } +namespace +{ +template +std::optional shuffleKeyColumnsForKeyColumnsVec(Method & method, std::vector> & key_columns_vec, const Sizes & key_sizes) +{ + auto shuffled_key_sizes = method.shuffleKeyColumns(key_columns_vec[0], key_sizes); + for (size_t i = 1; i < key_columns_vec.size(); ++i) + { + auto new_key_sizes = method.shuffleKeyColumns(key_columns_vec[i], key_sizes); + assert(shuffled_key_sizes == new_key_sizes); + } + return shuffled_key_sizes; +} +template +std::vector>> initAggKeysForKeyColumnsVec(Method & method, std::vector> & key_columns_vec, size_t max_block_size, size_t total_row_count) +{ + std::vector>> agg_keys_helpers; + size_t block_row_count = max_block_size; + for (size_t i = 0; i < key_columns_vec.size(); ++i) + { + if (i == key_columns_vec.size() - 1 && total_row_count % block_row_count != 0) + /// update block_row_count for the last block + block_row_count = total_row_count % block_row_count; + agg_keys_helpers.push_back(std::make_unique>(method)); + agg_keys_helpers.back()->initAggKeys(block_row_count, key_columns_vec[i]); + } + return agg_keys_helpers; +} +} // namespace + template void NO_INLINE Aggregator::convertToBlocksImplFinal( Method & method, Table & data, - std::vector> key_columns_vec, + std::vector> && key_columns_vec, std::vector & final_aggregate_columns_vec, Arena * arena) const { assert(!key_columns_vec.empty()); - auto shuffled_key_sizes = method.shuffleKeyColumns(key_columns_vec[0], key_sizes); + auto shuffled_key_sizes = shuffleKeyColumnsForKeyColumnsVec(method, key_columns_vec, key_sizes); const auto & key_sizes_ref = shuffled_key_sizes ? *shuffled_key_sizes : key_sizes; - AggregatorMethodInitKeyColumnHelper agg_keys_helper{method}; - agg_keys_helper.initAggKeys(data.size(), key_columns_vec[0]); + auto agg_keys_helpers = initAggKeysForKeyColumnsVec(method, key_columns_vec, params.max_block_size, data.size()); size_t data_index = 0; data.forEachValue([&](const auto & key, auto & mapped) { size_t key_columns_vec_index = data_index / params.max_block_size; - agg_keys_helper.insertKeyIntoColumns(key, key_columns_vec[key_columns_vec_index], key_sizes_ref, params.collators); + agg_keys_helpers[key_columns_vec_index]->insertKeyIntoColumns(key, key_columns_vec[key_columns_vec_index], key_sizes_ref, params.collators); insertAggregatesIntoColumns(mapped, final_aggregate_columns_vec[key_columns_vec_index], arena); - data_index++; + ++data_index; }); } @@ -1263,25 +1292,24 @@ template void NO_INLINE Aggregator::convertToBlocksImplNotFinal( Method & method, Table & data, - std::vector> key_columns_vec, + std::vector> && key_columns_vec, std::vector & aggregate_columns_vec) const { - auto shuffled_key_sizes = method.shuffleKeyColumns(key_columns_vec[0], key_sizes); + auto shuffled_key_sizes = shuffleKeyColumnsForKeyColumnsVec(method, key_columns_vec, key_sizes); const auto & key_sizes_ref = shuffled_key_sizes ? *shuffled_key_sizes : key_sizes; - AggregatorMethodInitKeyColumnHelper agg_keys_helper{method}; - agg_keys_helper.initAggKeys(data.size(), key_columns_vec[0]); + auto agg_keys_helpers = initAggKeysForKeyColumnsVec(method, key_columns_vec, params.max_block_size, data.size()); size_t data_index = 0; data.forEachValue([&](const auto & key, auto & mapped) { size_t key_columns_vec_index = data_index / params.max_block_size; - agg_keys_helper.insertKeyIntoColumns(key, key_columns_vec[key_columns_vec_index], key_sizes_ref, params.collators); + agg_keys_helpers[key_columns_vec_index]->insertKeyIntoColumns(key, key_columns_vec[key_columns_vec_index], key_sizes_ref, params.collators); /// reserved, so push_back does not throw exceptions for (size_t i = 0; i < params.aggregates_size; ++i) aggregate_columns_vec[key_columns_vec_index][i]->push_back(mapped + offsets_of_aggregate_states[i]); - data_index++; + ++data_index; mapped = nullptr; }); } diff --git a/dbms/src/Interpreters/Aggregator.h b/dbms/src/Interpreters/Aggregator.h index 1f1f8ddc30f..f8189dd2278 100644 --- a/dbms/src/Interpreters/Aggregator.h +++ b/dbms/src/Interpreters/Aggregator.h @@ -1220,7 +1220,7 @@ class Aggregator void convertToBlocksImplFinal( Method & method, Table & data, - std::vector> key_columns_vec, + std::vector> && key_columns_vec, std::vector & final_aggregate_columns_vec, Arena * arena) const; @@ -1235,7 +1235,7 @@ class Aggregator void convertToBlocksImplNotFinal( Method & method, Table & data, - std::vector> key_columns_vec, + std::vector> && key_columns_vec, std::vector & aggregate_columns_vec) const; template diff --git a/dbms/src/TestUtils/ColumnGenerator.cpp b/dbms/src/TestUtils/ColumnGenerator.cpp index 36b4bc2d4d9..a027d97d273 100644 --- a/dbms/src/TestUtils/ColumnGenerator.cpp +++ b/dbms/src/TestUtils/ColumnGenerator.cpp @@ -55,18 +55,36 @@ ColumnWithTypeAndName ColumnGenerator::generate(const ColumnGeneratorOpts & opts switch (type_id) { case TypeIndex::UInt8: + for (size_t i = 0; i < opts.size; ++i) + genUInt(col); + break; case TypeIndex::UInt16: + for (size_t i = 0; i < opts.size; ++i) + genUInt(col); + break; case TypeIndex::UInt32: + for (size_t i = 0; i < opts.size; ++i) + genUInt(col); + break; case TypeIndex::UInt64: for (size_t i = 0; i < opts.size; ++i) - genUInt(col); + genUInt(col); break; case TypeIndex::Int8: + for (size_t i = 0; i < opts.size; ++i) + genInt(col); + break; case TypeIndex::Int16: + for (size_t i = 0; i < opts.size; ++i) + genInt(col); + break; case TypeIndex::Int32: + for (size_t i = 0; i < opts.size; ++i) + genInt(col); + break; case TypeIndex::Int64: for (size_t i = 0; i < opts.size; ++i) - genInt(col); + genInt(col); break; case TypeIndex::Float32: case TypeIndex::Float64: @@ -178,9 +196,18 @@ String ColumnGenerator::randomDecimal(uint64_t prec, uint64_t scale) return s.substr(0, prec - scale) + "." + s.substr(prec - scale); } +template void ColumnGenerator::genInt(MutableColumnPtr & col) { - Field f = static_cast(rand_gen()); + static_assert(std::is_signed_v); + constexpr Int64 min_value = std::numeric_limits::min(); + constexpr Int64 max_value = std::numeric_limits::max(); + auto init_value = static_cast(rand_gen()); + if (init_value > max_value || init_value < min_value) + { + init_value = init_value % max_value; + } + Field f = init_value; col->insert(f); } @@ -198,9 +225,17 @@ void ColumnGenerator::genEnumValue(MutableColumnPtr & col, DataTypePtr & enum_ty col->insert(enum_value); } +template void ColumnGenerator::genUInt(MutableColumnPtr & col) { - Field f = static_cast(rand_gen()); + static_assert(std::is_unsigned_v); + constexpr UInt64 max_value = std::numeric_limits::max(); + auto init_value = static_cast(rand_gen()); + if (init_value > max_value) + { + init_value = init_value % max_value; + } + Field f = init_value; col->insert(f); } diff --git a/dbms/src/TestUtils/ColumnGenerator.h b/dbms/src/TestUtils/ColumnGenerator.h index 3edce5a40ec..fff794bc633 100644 --- a/dbms/src/TestUtils/ColumnGenerator.h +++ b/dbms/src/TestUtils/ColumnGenerator.h @@ -47,7 +47,8 @@ class ColumnGenerator : public ext::Singleton std::mt19937_64 rand_gen; std::uniform_int_distribution int_rand_gen = std::uniform_int_distribution(0, 128); std::uniform_real_distribution real_rand_gen; - const std::string charset{"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()、|【】[]{}「」;::;'‘,<《.>》。?·~`~"}; + /// todo support multibyte characters + const std::string charset{"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()|[]{}:;',<.>`~"}; String randomString(); int randomTimeOffset(); @@ -61,7 +62,9 @@ class ColumnGenerator : public ext::Singleton DataTypePtr createDecimalType(); void genBool(MutableColumnPtr & col); + template void genInt(MutableColumnPtr & col); + template void genUInt(MutableColumnPtr & col); void genFloat(MutableColumnPtr & col); void genString(MutableColumnPtr & col); diff --git a/dbms/src/TestUtils/FunctionTestUtils.cpp b/dbms/src/TestUtils/FunctionTestUtils.cpp index 6cf9387543d..43310601df7 100644 --- a/dbms/src/TestUtils/FunctionTestUtils.cpp +++ b/dbms/src/TestUtils/FunctionTestUtils.cpp @@ -98,6 +98,7 @@ ::testing::AssertionResult dataTypeEqual( ::testing::AssertionResult columnEqual( const ColumnPtr & expected, const ColumnPtr & actual, + const ICollator * collator, bool is_floating_point) { ASSERT_EQUAL(expected->getName(), actual->getName(), "Column name mismatch"); @@ -120,6 +121,14 @@ ::testing::AssertionResult columnEqual( if (!is_floating_point) { + if (collator != nullptr && !expected_field.isNull() && !actual_field.isNull()) + { + auto e_string = expected_field.get(); + auto a_string = actual_field.get(); + if (collator->compare(e_string.data(), e_string.size(), a_string.data(), a_string.size()) == 0) + continue; + /// if not equal, fallback to the original compare so we can reuse the code to get error message + } ASSERT_EQUAL_WITH_TEXT(expected_field, actual_field, fmt::format("Value at index {} mismatch", i), expected_field.toString(), actual_field.toString()); } else @@ -140,12 +149,13 @@ ::testing::AssertionResult columnEqual( ::testing::AssertionResult columnEqual( const ColumnWithTypeAndName & expected, - const ColumnWithTypeAndName & actual) + const ColumnWithTypeAndName & actual, + const ICollator * collator) { if (auto ret = dataTypeEqual(expected.type, actual.type); !ret) return ret; - return columnEqual(expected.column, actual.column, expected.type->isFloatingPoint()); + return columnEqual(expected.column, actual.column, collator, expected.type->isFloatingPoint()); } ::testing::AssertionResult blockEqual( diff --git a/dbms/src/TestUtils/FunctionTestUtils.h b/dbms/src/TestUtils/FunctionTestUtils.h index fad289043af..15b7748092a 100644 --- a/dbms/src/TestUtils/FunctionTestUtils.h +++ b/dbms/src/TestUtils/FunctionTestUtils.h @@ -586,12 +586,14 @@ ::testing::AssertionResult dataTypeEqual( ::testing::AssertionResult columnEqual( const ColumnPtr & expected, const ColumnPtr & actual, + const ICollator * collator = nullptr, bool is_floating_point = false); // ignore name ::testing::AssertionResult columnEqual( const ColumnWithTypeAndName & expected, - const ColumnWithTypeAndName & actual); + const ColumnWithTypeAndName & actual, + const ICollator * collator = nullptr); ::testing::AssertionResult blockEqual( const Block & expected, From 0f23c4ab9c030108b8fab9452cadfdb56f83dab6 Mon Sep 17 00:00:00 2001 From: JaySon Date: Tue, 14 Mar 2023 13:54:38 +0800 Subject: [PATCH 06/18] Fix several issues under disagg mode (#7060) ref pingcap/tiflash#6827 --- .../src/Flash/Disaggregated/S3LockService.cpp | 11 +- dbms/src/Flash/Disaggregated/S3LockService.h | 5 +- .../tests/gtest_s3_lock_service.cpp | 11 +- dbms/src/Interpreters/Context.cpp | 5 + dbms/src/Server/BgStorageInit.cpp | 102 ++++++++++++ dbms/src/Server/BgStorageInit.h | 42 +++++ dbms/src/Server/CMakeLists.txt | 1 + dbms/src/Server/Server.cpp | 145 ++++++------------ dbms/src/Server/StorageConfigParser.cpp | 5 +- .../Page/V3/Universal/S3LockLocalManager.cpp | 13 +- .../Page/V3/Universal/S3LockLocalManager.h | 3 - .../Page/V3/Universal/S3PageReader.cpp | 4 +- .../Storages/Page/V3/Universal/S3PageReader.h | 9 +- .../V3/Universal/UniversalPageStorage.cpp | 8 +- .../Page/V3/Universal/UniversalPageStorage.h | 4 +- .../Universal/UniversalPageStorageService.cpp | 18 +-- .../Universal/UniversalPageStorageService.h | 4 +- .../V3/Universal/tests/gtest_checkpoint.cpp | 4 +- .../V3/Universal/tests/gtest_remote_read.cpp | 4 +- dbms/src/Storages/PathCapacityMetrics.cpp | 3 +- dbms/src/Storages/S3/MockS3Client.cpp | 22 ++- dbms/src/Storages/S3/S3Common.cpp | 52 +++++-- dbms/src/Storages/S3/S3GCManager.cpp | 31 +++- dbms/src/Storages/S3/S3GCManager.h | 5 +- .../Storages/S3/tests/gtest_s3gcmanager.cpp | 6 +- .../Transaction/BackgroundService.cpp | 19 +-- dbms/src/Storages/Transaction/KVStore.cpp | 19 ++- dbms/src/Storages/Transaction/KVStore.h | 19 +-- .../Transaction/ProxyFFIStatusService.cpp | 2 +- dbms/src/TiDB/Schema/SchemaSyncService.cpp | 13 +- 30 files changed, 370 insertions(+), 219 deletions(-) create mode 100644 dbms/src/Server/BgStorageInit.cpp create mode 100644 dbms/src/Server/BgStorageInit.h diff --git a/dbms/src/Flash/Disaggregated/S3LockService.cpp b/dbms/src/Flash/Disaggregated/S3LockService.cpp index e400d9995d7..b636951a7c9 100644 --- a/dbms/src/Flash/Disaggregated/S3LockService.cpp +++ b/dbms/src/Flash/Disaggregated/S3LockService.cpp @@ -43,14 +43,12 @@ namespace DB::S3 S3LockService::S3LockService(Context & context_) : S3LockService( - context_.getGlobalContext().getTMTContext().getS3GCOwnerManager(), - S3::ClientFactory::instance().sharedTiFlashClient()) + context_.getGlobalContext().getTMTContext().getS3GCOwnerManager()) { } -S3LockService::S3LockService(OwnerManagerPtr owner_mgr_, std::shared_ptr s3_cli_) +S3LockService::S3LockService(OwnerManagerPtr owner_mgr_) : gc_owner(std::move(owner_mgr_)) - , s3_client(std::move(s3_cli_)) , log(Logger::get()) { } @@ -200,6 +198,7 @@ bool S3LockService::tryAddLockImpl( } }); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); // make sure data file exists if (!DB::S3::objectExists(*s3_client, s3_client->bucket(), data_file_key)) { @@ -245,9 +244,10 @@ bool S3LockService::tryAddLockImpl( return true; } -std::optional S3LockService::anyLockExist(const String & lock_prefix) const +std::optional S3LockService::anyLockExist(const String & lock_prefix) { std::optional lock_key; + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); DB::S3::listPrefix( *s3_client, s3_client->bucket(), @@ -318,6 +318,7 @@ bool S3LockService::tryMarkDeleteImpl(const String & data_file_key, disaggregate { tagging = TaggingObjectIsDeleted; } + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); DB::S3::uploadEmptyFile(*s3_client, s3_client->bucket(), delmark_key, tagging); if (!gc_owner->isOwner()) { diff --git a/dbms/src/Flash/Disaggregated/S3LockService.h b/dbms/src/Flash/Disaggregated/S3LockService.h index 71f8b368cce..d32214f321b 100644 --- a/dbms/src/Flash/Disaggregated/S3LockService.h +++ b/dbms/src/Flash/Disaggregated/S3LockService.h @@ -54,7 +54,7 @@ class S3LockService final : private boost::noncopyable public: explicit S3LockService(Context & context_); - S3LockService(OwnerManagerPtr owner_mgr_, std::shared_ptr s3_cli_); + explicit S3LockService(OwnerManagerPtr owner_mgr_); ~S3LockService() = default; @@ -100,14 +100,13 @@ class S3LockService final : private boost::noncopyable DataFileMutexPtr getDataFileLatch(const String & data_file_key); - std::optional anyLockExist(const String & lock_prefix) const; + static std::optional anyLockExist(const String & lock_prefix); private: std::unordered_map file_latch_map; std::mutex file_latch_map_mutex; OwnerManagerPtr gc_owner; - const std::shared_ptr s3_client; LoggerPtr log; }; diff --git a/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp b/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp index f84a5af44f7..3b2ddd18d6d 100644 --- a/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp +++ b/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp @@ -52,15 +52,8 @@ class S3LockServiceTest owner_manager = std::static_pointer_cast(OwnerManager::createMockOwner("owner_0")); owner_manager->campaignOwner(); - if (is_s3_test_enabled) - { - s3_client = client_factory.sharedTiFlashClient(); - } - else - { - s3_client = std::make_shared(); - } - s3_lock_service = std::make_unique(owner_manager, s3_client); + s3_client = client_factory.sharedTiFlashClient(); + s3_lock_service = std::make_unique(owner_manager); ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, s3_client->bucket()); createS3DataFiles(); } diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 7004eebcd0d..0ebc700a8a6 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -275,6 +275,11 @@ struct ContextShared tmt_context->shutdown(); } + if (schema_sync_service) + { + schema_sync_service = nullptr; + } + /** At this point, some tables may have threads that block our mutex. * To complete them correctly, we will copy the current list of tables, * and ask them all to finish their work. diff --git a/dbms/src/Server/BgStorageInit.cpp b/dbms/src/Server/BgStorageInit.cpp new file mode 100644 index 00000000000..2fa8a53a94a --- /dev/null +++ b/dbms/src/Server/BgStorageInit.cpp @@ -0,0 +1,102 @@ +// Copyright 2023 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace DB +{ + +void BgStorageInitHolder::waitUntilFinish() +{ + if (need_join) + { + LOG_INFO(Logger::get(), "Wait for storage init thread to join"); + init_thread->join(); + init_thread.reset(); + need_join = false; // join has been done + } + // else the job is done by not lazily init + // or has been detach +} + +void BgStorageInitHolder::start(Context & global_context, const LoggerPtr & log, bool lazily_init_store, bool is_s3_enabled) +{ + RUNTIME_CHECK_MSG( + lazily_init_store || !is_s3_enabled, + "When S3 enabled, lazily_init_store must be true. lazily_init_store={} s3_enabled={}", + lazily_init_store, + is_s3_enabled); + auto do_init_stores = [&global_context, &log] { + auto storages = global_context.getTMTContext().getStorages().getAllStorage(); + int init_cnt = 0; + int err_cnt = 0; + for (auto & [ks_table_id, storage] : storages) + { + // This will skip the init of storages that do not contain any data. TiFlash now sync the schema and + // create all tables regardless the table have define TiFlash replica or not, so there may be lots + // of empty tables in TiFlash. + // Note that we still need to init stores that contains data (defined by the stable dir of this storage + // is exist), or the data used size reported to PD is not correct. + const auto & [ks_id, table_id] = ks_table_id; + try + { + init_cnt += storage->initStoreIfDataDirExist() ? 1 : 0; + LOG_INFO(log, "Storage inited done, keyspace_id={} table_id={}", ks_id, table_id); + } + catch (...) + { + err_cnt++; + tryLogCurrentException(log, fmt::format("Storage inited fail, keyspace_id={} table_id={}", ks_id, table_id)); + } + } + LOG_INFO( + log, + "Storage inited finish. [total_count={}] [init_count={}] [error_count={}] [datatype_fullname_count={}]", + storages.size(), + init_cnt, + err_cnt, + DataTypeFactory::instance().getFullNameCacheSize()); + }; + + if (!lazily_init_store) + { + LOG_INFO(log, "Not lazily init store."); + need_join = false; + do_init_stores(); + } + + LOG_INFO(log, "Lazily init store."); + // apply the inited in another thread to shorten the start time of TiFlash + if (is_s3_enabled) + { + init_thread = std::make_unique(do_init_stores); + need_join = true; + } + else + { + init_thread = std::make_unique(do_init_stores); + init_thread->detach(); + need_join = false; + } +} + +} // namespace DB diff --git a/dbms/src/Server/BgStorageInit.h b/dbms/src/Server/BgStorageInit.h new file mode 100644 index 00000000000..66036fae09a --- /dev/null +++ b/dbms/src/Server/BgStorageInit.h @@ -0,0 +1,42 @@ +// Copyright 2023 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +#include + +namespace DB +{ + +struct BgStorageInitHolder +{ + bool need_join = false; + std::unique_ptr init_thread; + + void start(Context & global_context, const LoggerPtr & log, bool lazily_init_store, bool is_s3_enabled); + + // wait until finish if need + void waitUntilFinish(); + + // Exception safe for joining the init_thread + ~BgStorageInitHolder() + { + waitUntilFinish(); + } +}; + +} // namespace DB diff --git a/dbms/src/Server/CMakeLists.txt b/dbms/src/Server/CMakeLists.txt index 327d5b75cac..3fb10fbfbb4 100644 --- a/dbms/src/Server/CMakeLists.txt +++ b/dbms/src/Server/CMakeLists.txt @@ -46,6 +46,7 @@ add_library (tiflash-server-lib Server.cpp StatusFile.cpp TCPHandler.cpp + BgStorageInit.cpp StorageConfigParser.cpp UserConfigParser.cpp RaftConfigParser.cpp) diff --git a/dbms/src/Server/Server.cpp b/dbms/src/Server/Server.cpp index 0873934f5a2..cc687f20f55 100644 --- a/dbms/src/Server/Server.cpp +++ b/dbms/src/Server/Server.cpp @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -517,68 +518,6 @@ struct RaftStoreProxyRunner : boost::noncopyable const LoggerPtr & log; }; -std::unique_ptr initStores(Context & global_context, const LoggerPtr & log, bool lazily_init_store, EngineStoreServerWrap * tiflash_instance_wrap) -{ - // If `tiflash_instance_wrap` is not nullptr, S3 is enabled. - // We must wait for tiflash-proxy's initializtion finished before initialzing DeltaMergeStores, - // because we need store_id to scan dmfiles from S3. - RUNTIME_CHECK_MSG(lazily_init_store || tiflash_instance_wrap == nullptr, "When S3 enabled, lazily_init_store must be true."); - auto wait_proxy = [](EngineStoreServerWrap * tiflash_instance_wrap) { - while (tiflash_instance_wrap->proxy_helper->getProxyStatus() == RaftProxyStatus::Idle) - { - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - } - auto status = tiflash_instance_wrap->proxy_helper->getProxyStatus(); - RUNTIME_CHECK_MSG(status == RaftProxyStatus::Running, "RaftProxyStatus::{}", magic_enum::enum_name(status)); - }; - - auto do_init_stores = [&global_context, &log, tiflash_instance_wrap, wait_proxy]() { - if (tiflash_instance_wrap != nullptr) - { - wait_proxy(tiflash_instance_wrap); - } - auto storages = global_context.getTMTContext().getStorages().getAllStorage(); - int init_cnt = 0; - int err_cnt = 0; - for (auto & [table_id, storage] : storages) - { - // This will skip the init of storages that do not contain any data. TiFlash now sync the schema and - // create all tables regardless the table have define TiFlash replica or not, so there may be lots - // of empty tables in TiFlash. - // Note that we still need to init stores that contains data (defined by the stable dir of this storage - // is exist), or the data used size reported to PD is not correct. - try - { - init_cnt += storage->initStoreIfDataDirExist() ? 1 : 0; - LOG_INFO(log, "Storage inited done [table_id={}]", table_id); - } - catch (...) - { - err_cnt++; - tryLogCurrentException(log, fmt::format("Storage inited fail, [table_id={}]", table_id)); - } - } - LOG_INFO( - log, - "Storage inited finish. [total_count={}] [init_count={}] [error_count={}] [datatype_fullname_count={}]", - storages.size(), - init_cnt, - err_cnt, - DataTypeFactory::instance().getFullNameCacheSize()); - }; - if (lazily_init_store) - { - LOG_INFO(log, "Lazily init store."); - // apply the inited in another thread to shorten the start time of TiFlash - return std::make_unique(do_init_stores); - } - else - { - LOG_INFO(log, "Not lazily init store."); - do_init_stores(); - return nullptr; - } -} class Server::TcpHttpServersHolder { @@ -881,7 +820,7 @@ void adjustThreadPoolSize(const Settings & settings, size_t logical_cores) GlobalThreadPool::instance().setMaxFreeThreads(max_io_thread_count / 2); GlobalThreadPool::instance().setQueueSize(max_io_thread_count * 2); - IOThreadPool::instance->setMaxFreeThreads(max_io_thread_count); + IOThreadPool::instance->setMaxThreads(max_io_thread_count); IOThreadPool::instance->setMaxFreeThreads(max_io_thread_count / 2); IOThreadPool::instance->setQueueSize(max_io_thread_count * 2); } @@ -1231,8 +1170,10 @@ int Server::main(const std::vector & /*args*/) LOG_INFO(log, "Global PageStorage run mode is {}", magic_enum::enum_name(global_context->getPageStorageRunMode())); } - if (global_context->getSharedContextDisagg()->isDisaggregatedStorageMode() - || global_context->getSharedContextDisagg()->notDisaggregatedMode()) + // Only when this node is disagg compute node and autoscaler is enabled, we don't need the WriteNodePageStorage instance + // Disagg compute node without autoscaler still need this instance for proxy's data + if (!(global_context->getSharedContextDisagg()->isDisaggregatedComputeMode() + && global_context->getSharedContextDisagg()->use_autoscaler)) { global_context->initializeWriteNodePageStorageIfNeed(global_context->getPathPool()); } @@ -1260,7 +1201,11 @@ int Server::main(const std::vector & /*args*/) } else { - LOG_INFO(log, fmt::format("Detected memory capacity {} bytes, you have config `max_memory_usage_for_all_queries` to {}, finally limit to {} bytes.", server_info.memory_info.capacity, settings.max_memory_usage_for_all_queries.toString(), settings.max_memory_usage_for_all_queries.getActualBytes(server_info.memory_info.capacity))); + LOG_INFO(log, + "Detected memory capacity {} bytes, you have config `max_memory_usage_for_all_queries` to {}, finally limit to {} bytes.", + server_info.memory_info.capacity, + settings.max_memory_usage_for_all_queries.toString(), + settings.max_memory_usage_for_all_queries.getActualBytes(server_info.memory_info.capacity)); } /// Initialize main config reloader. @@ -1375,7 +1320,7 @@ int Server::main(const std::vector & /*args*/) // Load remaining databases loadMetadata(*global_context); LOG_DEBUG(log, "Load metadata done."); - std::unique_ptr init_stores_thread; + BgStorageInitHolder bg_init_stores; if (!global_context->getSharedContextDisagg()->isDisaggregatedComputeMode()) { /// Then, sync schemas with TiDB, and initialize schema sync service. @@ -1404,13 +1349,18 @@ int Server::main(const std::vector & /*args*/) LOG_DEBUG(log, "Sync schemas done."); } - init_stores_thread = initStores(*global_context, log, storage_config.lazily_init_store, storage_config.s3_config.isS3Enabled() ? &tiflash_instance_wrap : nullptr); - - // After schema synced, set current database. - global_context->setCurrentDatabase(default_database); + bg_init_stores.start( + *global_context, + log, + storage_config.lazily_init_store, + storage_config.s3_config.isS3Enabled()); + // init schema sync service with tidb global_context->initializeSchemaSyncService(); } + // set default database for ch-client + global_context->setCurrentDatabase(default_database); + CPUAffinityManager::initCPUAffinityManager(config()); LOG_INFO(log, "CPUAffinity: {}", CPUAffinityManager::getInstance().toString()); SCOPE_EXIT({ @@ -1482,19 +1432,11 @@ int Server::main(const std::vector & /*args*/) GRPCCompletionQueuePool::global_instance = std::make_unique(size); } - if (init_stores_thread != nullptr) - { - if (storage_config.s3_config.isS3Enabled()) - { - // If S3 enabled, wait for all DeltaMergeStores' initialization - // before this instance can accept requests. - init_stores_thread->join(); - } - else - { - init_stores_thread->detach(); - } - } + // If S3 enabled, wait for all DeltaMergeStores' initialization + // before this instance can accept requests. + // Else it just do nothing. + bg_init_stores.waitUntilFinish(); + /// Then, startup grpc server to serve raft and/or flash services. FlashGrpcServerHolder flash_grpc_server_holder(this->context(), this->config(), raft_config, log); @@ -1561,23 +1503,36 @@ int Server::main(const std::vector & /*args*/) tiflash_instance_wrap.tmt = &tmt_context; LOG_INFO(log, "Let tiflash proxy start all services"); + // Set tiflash instance status to running, then wait for proxy enter running status tiflash_instance_wrap.status = EngineStoreServerStatus::Running; while (tiflash_instance_wrap.proxy_helper->getProxyStatus() == RaftProxyStatus::Idle) std::this_thread::sleep_for(std::chrono::milliseconds(200)); // proxy update store-id before status set `RaftProxyStatus::Running` assert(tiflash_instance_wrap.proxy_helper->getProxyStatus() == RaftProxyStatus::Running); - LOG_INFO(log, "store_id={}, tiflash proxy is ready to serve, try to wake up all regions' leader", tmt_context.getKVStore()->getStoreID(std::memory_order_seq_cst)); - size_t runner_cnt = config().getUInt("flash.read_index_runner_count", 1); // if set 0, DO NOT enable read-index worker - auto & kvstore_ptr = tmt_context.getKVStore(); - kvstore_ptr->initReadIndexWorkers( - [&]() { - // get from tmt context - return std::chrono::milliseconds(tmt_context.readIndexWorkerTick()); - }, - /*running thread count*/ runner_cnt); - tmt_context.getKVStore()->asyncRunReadIndexWorkers(); - WaitCheckRegionReady(tmt_context, *kvstore_ptr, terminate_signals_counter); + if (global_context->getSharedContextDisagg()->isDisaggregatedComputeMode()) + { + // compute node do not need to handle read index + LOG_INFO(log, "store_id={}, tiflash proxy is ready to serve", tmt_context.getKVStore()->getStoreID(std::memory_order_seq_cst)); + } + else + { + LOG_INFO(log, "store_id={}, tiflash proxy is ready to serve, try to wake up all regions' leader", tmt_context.getKVStore()->getStoreID(std::memory_order_seq_cst)); + + size_t runner_cnt = config().getUInt("flash.read_index_runner_count", 1); // if set 0, DO NOT enable read-index worker + if (runner_cnt > 0) + { + auto & kvstore_ptr = tmt_context.getKVStore(); + kvstore_ptr->initReadIndexWorkers( + [&]() { + // get from tmt context + return std::chrono::milliseconds(tmt_context.readIndexWorkerTick()); + }, + /*running thread count*/ runner_cnt); + tmt_context.getKVStore()->asyncRunReadIndexWorkers(); + WaitCheckRegionReady(tmt_context, *kvstore_ptr, terminate_signals_counter); + } + } } SCOPE_EXIT({ if (!proxy_conf.is_proxy_runnable) diff --git a/dbms/src/Server/StorageConfigParser.cpp b/dbms/src/Server/StorageConfigParser.cpp index 563bded1de4..c6833e2a407 100644 --- a/dbms/src/Server/StorageConfigParser.cpp +++ b/dbms/src/Server/StorageConfigParser.cpp @@ -211,10 +211,7 @@ void TiFlashStorageConfig::parseMisc(const String & storage_section, const Logge readConfig(table, "format_version", format_version); - if (auto version = table->get_qualified_as("api_version"); version) - { - api_version = *version; - } + readConfig(table, "api_version", api_version); auto get_bool_config_or_default = [&](const String & name, bool default_value) { #ifndef NDEBUG diff --git a/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.cpp b/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.cpp index 71513c2c4e0..49de7bd6b80 100644 --- a/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.cpp +++ b/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.cpp @@ -34,14 +34,9 @@ S3LockLocalManager::S3LockLocalManager() : store_id(InvalidStoreID) , log(Logger::get()) { - // store_id, s3lock_client are inited later because they may not - // accessable when S3LockLocalManager is created. - auto & ins = S3::ClientFactory::instance(); - s3_client = ins.sharedClient(); - bucket = ins.bucket(); } -// `store_id`, `s3lock_client` are inited later because they may not +// `store_id` is inited later because they may not // accessable when S3LockLocalManager is created. void S3LockLocalManager::initStoreInfo(StoreID actual_store_id, DB::S3::S3LockClientPtr s3lock_client_) { @@ -57,7 +52,8 @@ void S3LockLocalManager::initStoreInfo(StoreID actual_store_id, DB::S3::S3LockCl break; // we need to restore the last_upload_sequence from S3 - const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, bucket, actual_store_id); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); + const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, s3_client->bucket(), actual_store_id); if (!manifests.empty()) { last_upload_sequence = manifests.latestUploadSequence(); @@ -174,7 +170,8 @@ String S3LockLocalManager::createS3Lock(const String & datafile_key, const S3::S // e.g. the CheckpointDataFile or DTFile generated by this store. // directly create lock through S3 client // TODO: handle s3 network error and retry? - S3::uploadEmptyFile(*s3_client, bucket, lockkey); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); + S3::uploadEmptyFile(*s3_client, s3_client->bucket(), lockkey); LOG_DEBUG(log, "S3 lock created for local datafile, lockkey={}", lockkey); } else diff --git a/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.h b/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.h index badeadd1388..34d9cbd068d 100644 --- a/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.h +++ b/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.h @@ -62,9 +62,6 @@ class S3LockLocalManager String createS3Lock(const String & datafile_key, const S3::S3FilenameView & s3_file, UInt64 lock_store_id); private: - std::shared_ptr s3_client; - String bucket; - std::mutex mtx_store_init; std::condition_variable cv_init; StoreID store_id; diff --git a/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp b/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp index 5d56bcd97aa..a5f4c633227 100644 --- a/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp +++ b/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace DB::PS::V3 @@ -24,7 +25,8 @@ Page S3PageReader::read(const UniversalPageIdAndEntry & page_id_and_entry) const auto & page_entry = page_id_and_entry.second; RUNTIME_CHECK(page_entry.checkpoint_info.has_value()); auto location = page_entry.checkpoint_info.data_location; - S3::S3RandomAccessFile file(s3_client, bucket, *location.data_file_id); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); + S3::S3RandomAccessFile file(s3_client, s3_client->bucket(), *location.data_file_id); file.seek(location.offset_in_file, SEEK_SET); auto buf_size = location.size_in_file; char * data_buf = static_cast(alloc(buf_size)); diff --git a/dbms/src/Storages/Page/V3/Universal/S3PageReader.h b/dbms/src/Storages/Page/V3/Universal/S3PageReader.h index bbf92437c61..0507b569419 100644 --- a/dbms/src/Storages/Page/V3/Universal/S3PageReader.h +++ b/dbms/src/Storages/Page/V3/Universal/S3PageReader.h @@ -38,10 +38,7 @@ using UniversalPageIdAndEntries = std::vector; class S3PageReader : private Allocator { public: - explicit S3PageReader(std::shared_ptr s3_client_, const String & bucket_) - : s3_client(s3_client_) - , bucket(bucket_) - {} + S3PageReader() = default; Page read(const UniversalPageIdAndEntry & page_id_and_entry); @@ -51,10 +48,6 @@ class S3PageReader : private Allocator // return two page_maps, the first contains the whole page for given page id which is used to update local cache, // the second just contains read fields data. std::pair read(const FieldReadInfos & to_read); - -private: - std::shared_ptr s3_client; - String bucket; }; using S3PageReaderPtr = std::unique_ptr; diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.cpp b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.cpp index 0de563d3b1c..d02d615e579 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.cpp +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.cpp @@ -35,9 +35,7 @@ UniversalPageStoragePtr UniversalPageStorage::create( const String & name, PSDiskDelegatorPtr delegator, const PageStorageConfig & config, - const FileProviderPtr & file_provider, - std::shared_ptr s3_client, - const String & bucket) + const FileProviderPtr & file_provider) { UniversalPageStoragePtr storage = std::make_shared(name, delegator, config, file_provider); storage->blob_store = std::make_unique( @@ -45,9 +43,9 @@ UniversalPageStoragePtr UniversalPageStorage::create( file_provider, delegator, PS::V3::BlobConfig::from(config)); - if (s3_client != nullptr) + if (S3::ClientFactory::instance().isEnabled()) { - storage->remote_reader = std::make_unique(s3_client, bucket); + storage->remote_reader = std::make_unique(); storage->remote_locks_local_mgr = std::make_unique(); } return storage; diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.h b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.h index 565fb646d8e..328f7ec0de9 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.h +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.h @@ -73,9 +73,7 @@ class UniversalPageStorage final const String & name, PSDiskDelegatorPtr delegator, const PageStorageConfig & config, - const FileProviderPtr & file_provider, - std::shared_ptr s3_client = nullptr, - const String & bucket = ""); + const FileProviderPtr & file_provider); UniversalPageStorage( String name, diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp index 4c781983300..4916efc1695 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp @@ -47,20 +47,12 @@ UniversalPageStorageServicePtr UniversalPageStorageService::create( const PageStorageConfig & config) { auto service = UniversalPageStorageServicePtr(new UniversalPageStorageService(context)); - auto & s3factory = S3::ClientFactory::instance(); - std::shared_ptr s3_client; - String bucket; - if (s3factory.isEnabled()) - { - s3_client = s3factory.sharedClient(); - bucket = s3factory.bucket(); - } - service->uni_page_storage = UniversalPageStorage::create(name, delegator, config, context.getFileProvider(), s3_client, bucket); + service->uni_page_storage = UniversalPageStorage::create(name, delegator, config, context.getFileProvider()); service->uni_page_storage->restore(); // Starts the checkpoint upload timer // for disagg tiflash write node - if (s3factory.isEnabled() && !context.getSharedContextDisagg()->isDisaggregatedComputeMode()) + if (S3::ClientFactory::instance().isEnabled() && !context.getSharedContextDisagg()->isDisaggregatedComputeMode()) { // TODO: make this interval reloadable auto interval_s = context.getSettingsRef().remote_checkpoint_interval_seconds; @@ -89,12 +81,10 @@ UniversalPageStorageService::createForTest( Context & context, const String & name, PSDiskDelegatorPtr delegator, - const PageStorageConfig & config, - std::shared_ptr s3_client, - String bucket) + const PageStorageConfig & config) { auto service = UniversalPageStorageServicePtr(new UniversalPageStorageService(context)); - service->uni_page_storage = UniversalPageStorage::create(name, delegator, config, context.getFileProvider(), s3_client, bucket); + service->uni_page_storage = UniversalPageStorage::create(name, delegator, config, context.getFileProvider()); service->uni_page_storage->restore(); // not register background task under test return service; diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.h b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.h index 5580b9b065c..c80ceb61113 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.h +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.h @@ -54,9 +54,7 @@ class UniversalPageStorageService final Context & context, const String & name, PSDiskDelegatorPtr delegator, - const PageStorageConfig & config, - std::shared_ptr s3_client, - String bucket); + const PageStorageConfig & config); private: explicit UniversalPageStorageService(Context & global_context_); diff --git a/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp b/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp index ae3f931ecae..c859540d891 100644 --- a/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp +++ b/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp @@ -758,9 +758,7 @@ class UniversalPageStorageServiceCheckpointTest : public DB::base::TiFlashStorag global_context, "test.t", delegator, - PageStorageConfig{.blob_heavy_gc_valid_rate = 1.0}, - s3_client, - bucket); + PageStorageConfig{.blob_heavy_gc_valid_rate = 1.0}); log = Logger::get("UniversalPageStorageServiceCheckpointTest"); ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket)); } diff --git a/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp b/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp index dca79d63027..0b295400f27 100644 --- a/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp +++ b/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp @@ -61,7 +61,7 @@ class UniPageStorageRemoteReadTest : public DB::base::TiFlashStorageTestBasic ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket)); - page_storage = UniversalPageStorage::create("write", delegator, config, file_provider, s3_client, bucket); + page_storage = UniversalPageStorage::create("write", delegator, config, file_provider); page_storage->restore(); } @@ -74,7 +74,7 @@ class UniPageStorageRemoteReadTest : public DB::base::TiFlashStorageTestBasic { auto path = getTemporaryPath(); delegator = std::make_shared(path); - auto storage = UniversalPageStorage::create("test.t", delegator, config_, file_provider, s3_client, bucket); + auto storage = UniversalPageStorage::create("test.t", delegator, config_, file_provider); storage->restore(); return storage; } diff --git a/dbms/src/Storages/PathCapacityMetrics.cpp b/dbms/src/Storages/PathCapacityMetrics.cpp index a263d90959b..f32f573b30f 100644 --- a/dbms/src/Storages/PathCapacityMetrics.cpp +++ b/dbms/src/Storages/PathCapacityMetrics.cpp @@ -210,7 +210,8 @@ FsStats PathCapacityMetrics::getFsStats(bool finalize_capacity) if (finalize_capacity && S3::ClientFactory::instance().isEnabled()) { // When S3 is enabled, use a large fake stat to avoid disk limitation by PD. - total_stat.capacity_size = 1024UL * 1024UL * 1024UL * 1024UL * 1024UL * 1024UL; // 1024PB + // EiB is not supported by TiUP now. https://github.com/pingcap/tiup/issues/2139 + total_stat.capacity_size = 1024UL * 1024UL * 1024UL * 1024UL * 1024UL; // 1PB total_stat.avail_size = total_stat.capacity_size - total_stat.used_size; } diff --git a/dbms/src/Storages/S3/MockS3Client.cpp b/dbms/src/Storages/S3/MockS3Client.cpp index 1326dffc2c6..44b988c248c 100644 --- a/dbms/src/Storages/S3/MockS3Client.cpp +++ b/dbms/src/Storages/S3/MockS3Client.cpp @@ -91,13 +91,27 @@ Model::PutObjectOutcome MockS3Client::PutObject(const Model::PutObjectRequest & Model::CopyObjectOutcome MockS3Client::CopyObject(const Model::CopyObjectRequest & request) const { std::lock_guard lock(mtx); - auto itr = storage.find(request.GetBucket()); - if (itr == storage.end()) + auto first_pos = request.GetCopySource().find_first_of('/'); + RUNTIME_CHECK(first_pos != String::npos, request.GetCopySource()); + auto src_bucket = request.GetCopySource().substr(0, first_pos); + auto src_key = request.GetCopySource().substr(first_pos + 1, request.GetCopySource().size()); + + auto src_itr = storage.find(src_bucket); + if (src_itr == storage.end()) + { + return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuckBucket"); + } + + auto dst_itr = storage.find(request.GetBucket()); + if (dst_itr == storage.end()) { return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuckBucket"); } - auto bucket_storage = itr->second; - bucket_storage[request.GetKey()] = bucket_storage[request.GetCopySource()]; + + auto src_bucket_storage = src_itr->second; + auto dst_bucket_storage = dst_itr->second; + RUNTIME_CHECK(src_bucket_storage.contains(src_key), src_bucket, src_key); + dst_bucket_storage[request.GetKey()] = src_bucket_storage[src_key]; storage_tagging[request.GetBucket()][request.GetKey()] = request.GetTagging(); return Model::CopyObjectResult{}; } diff --git a/dbms/src/Storages/S3/S3Common.cpp b/dbms/src/Storages/S3/S3Common.cpp index e63f0cc6150..a37d6cc2a14 100644 --- a/dbms/src/Storages/S3/S3Common.cpp +++ b/dbms/src/Storages/S3/S3Common.cpp @@ -32,11 +32,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -70,7 +72,8 @@ Poco::Message::Priority convertLogLevel(Aws::Utils::Logging::LogLevel log_level) case Aws::Utils::Logging::LogLevel::Warn: return Poco::Message::PRIO_WARNING; case Aws::Utils::Logging::LogLevel::Info: - return Poco::Message::PRIO_INFORMATION; + // treat aws info logging as debug level + return Poco::Message::PRIO_DEBUG; case Aws::Utils::Logging::LogLevel::Debug: return Poco::Message::PRIO_DEBUG; case Aws::Utils::Logging::LogLevel::Trace: @@ -367,7 +370,9 @@ void rewriteObjectWithTagging(const Aws::S3::S3Client & client, const String & b Stopwatch sw; Aws::S3::Model::CopyObjectRequest req; // rewrite the object with `key`, adding tagging to the new object - req.WithBucket(bucket).WithCopySource(key).WithKey(key).WithTagging(tagging); + req.WithBucket(bucket).WithCopySource(bucket + "/" + key).WithKey(key) // + .WithTagging(tagging) + .WithTaggingDirective(Aws::S3::Model::TaggingDirective::REPLACE); ProfileEvents::increment(ProfileEvents::S3CopyObject); auto outcome = client.CopyObject(req); if (!outcome.IsSuccess()) @@ -393,17 +398,29 @@ void ensureLifecycleRuleExist(const Aws::S3::S3Client & client, const String & b throw fromS3Error(outcome.GetError(), "GetBucketLifecycle fail"); } - auto res = outcome.GetResult(); + auto res = outcome.GetResultWithOwnership(); old_rules = res.GetRules(); static_assert(TaggingObjectIsDeleted == "tiflash_deleted=true"); for (const auto & rule : old_rules) { const auto & filt = rule.GetFilter(); - const auto & tag = filt.GetTag(); + if (!filt.AndHasBeenSet()) + { + continue; + } + const auto & and_op = filt.GetAnd(); + const auto & tags = and_op.GetTags(); + if (tags.size() != 1 || !and_op.PrefixHasBeenSet() || !and_op.GetPrefix().empty()) + { + continue; + } + + const auto & tag = tags[0]; if (rule.GetStatus() == Aws::S3::Model::ExpirationStatus::Enabled && tag.GetKey() == "tiflash_deleted" && tag.GetValue() == "true") { lifecycle_rule_has_been_set = true; + break; } } } @@ -411,23 +428,39 @@ void ensureLifecycleRuleExist(const Aws::S3::S3Client & client, const String & b static LoggerPtr log = Logger::get(); if (lifecycle_rule_has_been_set) { - LOG_INFO(log, "The lifecycle rule has been set, n_rules={} tag={}", old_rules.size(), TaggingObjectIsDeleted); + LOG_INFO(log, "The lifecycle rule has been set, n_rules={} filter={}", old_rules.size(), TaggingObjectIsDeleted); + return; + } + else + { + UNUSED(expire_days); + LOG_WARNING(log, "The lifecycle rule with filter \"{}\" has not been set, please check the bucket lifecycle configuration", TaggingObjectIsDeleted); return; } +#if 0 + // Adding rule by AWS SDK is failed, don't know why + // Reference: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3OutpostsLifecycleCLIJava.html + LOG_INFO(log, "The lifecycle rule with filter \"{}\" has not been added, n_rules={}", TaggingObjectIsDeleted, old_rules.size()); static_assert(TaggingObjectIsDeleted == "tiflash_deleted=true"); + std::vector filter_tags{Aws::S3::Model::Tag().WithKey("tiflash_deleted").WithValue("true")}; Aws::S3::Model::LifecycleRuleFilter filter; - filter.SetTag(Aws::S3::Model::Tag().WithKey("tiflash_deleted").WithValue("true")); + filter.WithAnd(Aws::S3::Model::LifecycleRuleAndOperator() + .WithPrefix("") + .WithTags(filter_tags)); Aws::S3::Model::LifecycleRule rule; rule.WithStatus(Aws::S3::Model::ExpirationStatus::Enabled) .WithFilter(filter) - .WithExpiration(Aws::S3::Model::LifecycleExpiration().WithDays(expire_days)); + .WithExpiration(Aws::S3::Model::LifecycleExpiration() + .WithExpiredObjectDeleteMarker(false) + .WithDays(expire_days)) + .WithID("tiflashgc"); + old_rules.emplace_back(rule); // existing rules + new rule Aws::S3::Model::BucketLifecycleConfiguration lifecycle_config; lifecycle_config - .WithRules(old_rules) // existing rules - .AddRules(rule); + .WithRules(old_rules); Aws::S3::Model::PutBucketLifecycleConfigurationRequest request; request.WithBucket(bucket) @@ -439,6 +472,7 @@ void ensureLifecycleRuleExist(const Aws::S3::S3Client & client, const String & b throw fromS3Error(outcome.GetError(), "PutBucketLifecycle fail"); } LOG_INFO(log, "The lifecycle rule has been added, new_n_rules={} tag={}", old_rules.size() + 1, TaggingObjectIsDeleted); +#endif } void listPrefix( diff --git a/dbms/src/Storages/S3/S3GCManager.cpp b/dbms/src/Storages/S3/S3GCManager.cpp index 9230a990cff..8695be20a91 100644 --- a/dbms/src/Storages/S3/S3GCManager.cpp +++ b/dbms/src/Storages/S3/S3GCManager.cpp @@ -51,12 +51,10 @@ namespace DB::S3 S3GCManager::S3GCManager( pingcap::pd::ClientPtr pd_client_, - std::shared_ptr client_, OwnerManagerPtr gc_owner_manager_, S3LockClientPtr lock_client_, S3GCConfig config_) : pd_client(std::move(pd_client_)) - , client(std::move(client_)) , gc_owner_manager(std::move(gc_owner_manager_)) , lock_client(std::move(lock_client_)) , shutdown_called(false) @@ -88,6 +86,7 @@ bool S3GCManager::runOnAllStores() if (config.method == S3GCMethod::Lifecycle && !lifecycle_has_been_set) { + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); ensureLifecycleRuleExist(*client, client->bucket(), /*expire_days*/ 1); lifecycle_has_been_set = true; } @@ -135,6 +134,7 @@ void S3GCManager::runForStore(UInt64 gc_store_id) { // get a timepoint at the begin, only remove objects that expired compare // to this timepoint + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); const Aws::Utils::DateTime gc_timepoint = Aws::Utils::DateTime::Now(); LOG_DEBUG(log, "run gc, gc_store_id={} timepoint={}", gc_store_id, gc_timepoint.ToGmtString(Aws::Utils::DateFormat::ISO_8601)); @@ -196,6 +196,7 @@ void S3GCManager::runForTombstoneStore(UInt64 gc_store_id) cleanUnusedLocks(gc_store_id, lock_prefix, std::numeric_limits::max(), valid_lock_files, gc_timepoint); // clean all manifest objects + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); const auto manifests = CheckpointManifestS3Set::getFromS3(*client, gc_store_id); removeOutdatedManifest(manifests, nullptr); @@ -227,6 +228,7 @@ void S3GCManager::cleanUnusedLocks( const std::unordered_set & valid_lock_files, const Aws::Utils::DateTime & timepoint) { + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); // All locks (even for different stores) share the same prefix, list the lock files under this prefix listPrefix(*client, client->bucket(), scan_prefix, [&](const Aws::S3::Model::ListObjectsV2Result & result) { const auto & objects = result.GetContents(); @@ -270,6 +272,7 @@ void S3GCManager::cleanOneLock(const String & lock_key, const S3FilenameView & l const auto unlocked_datafile_delmark_key = unlocked_datafilename_view.getDelMarkKey(); // delete S3 lock file + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); deleteObject(*client, client->bucket(), lock_key); // TODO: If `lock_key` is the only lock to datafile and GCManager crashes @@ -380,6 +383,7 @@ void S3GCManager::removeDataFileIfDelmarkExpired( // error when the key is not exist physicalRemoveDataFile(datafile_key); + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); deleteObject(*client, client->bucket(), delmark_key); LOG_INFO(log, "datafile delmark deleted, key={}", delmark_key); } @@ -390,6 +394,7 @@ void S3GCManager::tryCleanExpiredDataFiles(UInt64 gc_store_id, const Aws::Utils: // the keys by prefix, and if there is an expired delmark, then try to remove // its correspond StableFile or CheckpointDataFile. const auto prefix = S3Filename::fromStoreId(gc_store_id).toDataPrefix(); + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); listPrefix(*client, client->bucket(), prefix, [&](const Aws::S3::Model::ListObjectsV2Result & result) { const auto & objects = result.GetContents(); if (shutdown_called) @@ -419,6 +424,7 @@ void S3GCManager::lifecycleMarkDataFileDeleted(const String & datafile_key) assert(config.method == S3GCMethod::Lifecycle); auto view = S3FilenameView::fromKey(datafile_key); + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); if (!view.isDMFile()) { // CheckpointDataFile is a single object, add tagging for it and update its mtime @@ -431,7 +437,7 @@ void S3GCManager::lifecycleMarkDataFileDeleted(const String & datafile_key) // Rewrite all objects with tagging belong to this DMFile // TODO: If GCManager unexpectedly exit in the middle, it will leave some broken // sub file for DMFile, try clean them later. - S3::listPrefix(*client, client->bucket(), datafile_key, [this, &datafile_key](const Aws::S3::Model::ListObjectsV2Result & result) { + S3::listPrefix(*client, client->bucket(), datafile_key, [this, &client, &datafile_key](const Aws::S3::Model::ListObjectsV2Result & result) { const auto & objs = result.GetContents(); for (const auto & obj : objs) { @@ -450,6 +456,7 @@ void S3GCManager::physicalRemoveDataFile(const String & datafile_key) assert(config.method == S3GCMethod::ScanThenDelete); auto view = S3FilenameView::fromKey(datafile_key); + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); if (!view.isDMFile()) { // CheckpointDataFile is a single object, remove it. @@ -462,7 +469,7 @@ void S3GCManager::physicalRemoveDataFile(const String & datafile_key) // Remove all objects belong to this DMFile // TODO: If GCManager unexpectedly exit in the middle, it will leave some broken // sub file for DMFile, try clean them later. - S3::listPrefix(*client, client->bucket(), datafile_key, [this, &datafile_key](const Aws::S3::Model::ListObjectsV2Result & result) { + S3::listPrefix(*client, client->bucket(), datafile_key, [this, &client, &datafile_key](const Aws::S3::Model::ListObjectsV2Result & result) { const auto & objs = result.GetContents(); for (const auto & obj : objs) { @@ -476,12 +483,13 @@ void S3GCManager::physicalRemoveDataFile(const String & datafile_key) } } -std::vector S3GCManager::getAllStoreIds() const +std::vector S3GCManager::getAllStoreIds() { std::vector all_store_ids; // The store key are "s${store_id}/", we need setting delimiter "/" to get the // common prefixes result. // Reference: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-prefixes.html + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); listPrefix( *client, client->bucket(), @@ -536,6 +544,7 @@ std::unordered_set S3GCManager::getValidLocksFromManifest(const Strings void S3GCManager::removeOutdatedManifest(const CheckpointManifestS3Set & manifests, const Aws::Utils::DateTime * const timepoint) { + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); if (timepoint == nullptr) { for (const auto & mf : manifests.objects()) @@ -576,8 +585,7 @@ S3GCManagerService::S3GCManagerService( const S3GCConfig & config) : global_ctx(context.getGlobalContext()) { - auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); - manager = std::make_unique(std::move(pd_client), std::move(s3_client), std::move(gc_owner_manager_), std::move(lock_client), config); + manager = std::make_unique(std::move(pd_client), std::move(gc_owner_manager_), std::move(lock_client), config); timer = global_ctx.getBackgroundPool().addTask( [this]() { @@ -594,11 +602,18 @@ S3GCManagerService::~S3GCManagerService() void S3GCManagerService::shutdown() { - manager->shutdown(); + if (manager) + { + // set the shutdown flag + manager->shutdown(); + } + if (timer) { + // Remove the task handler. It will block until the task break global_ctx.getBackgroundPool().removeTask(timer); timer = nullptr; + // then we can reset the manager manager = nullptr; } } diff --git a/dbms/src/Storages/S3/S3GCManager.h b/dbms/src/Storages/S3/S3GCManager.h index 6863976aace..a11106084df 100644 --- a/dbms/src/Storages/S3/S3GCManager.h +++ b/dbms/src/Storages/S3/S3GCManager.h @@ -85,7 +85,6 @@ class S3GCManager public: explicit S3GCManager( pingcap::pd::ClientPtr pd_client_, - std::shared_ptr client_, OwnerManagerPtr gc_owner_manager_, S3LockClientPtr lock_client_, S3GCConfig config_); @@ -121,7 +120,7 @@ class S3GCManager void lifecycleMarkDataFileDeleted(const String & datafile_key); void physicalRemoveDataFile(const String & datafile_key); - std::vector getAllStoreIds() const; + static std::vector getAllStoreIds(); std::unordered_set getValidLocksFromManifest(const Strings & manifest_keys); @@ -130,8 +129,6 @@ class S3GCManager private: const pingcap::pd::ClientPtr pd_client; - const std::shared_ptr client; - const OwnerManagerPtr gc_owner_manager; const S3LockClientPtr lock_client; diff --git a/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp b/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp index f3ba7024c38..30b87aa8046 100644 --- a/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp +++ b/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp @@ -70,7 +70,7 @@ class S3GCManagerTest : public DB::base::TiFlashStorageTestBasic auto mock_gc_owner = OwnerManager::createMockOwner("owner_0"); auto mock_lock_client = std::make_shared(mock_s3_client); auto mock_pd_client = std::make_shared(); - gc_mgr = std::make_unique(mock_pd_client, mock_s3_client, mock_gc_owner, mock_lock_client, config); + gc_mgr = std::make_unique(mock_pd_client, mock_gc_owner, mock_lock_client, config); ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*mock_s3_client, mock_s3_client->bucket()); @@ -373,22 +373,26 @@ try { // not managed by lock_store_id auto df = S3Filename::newCheckpointData(store_id, 300, 1); + keys.emplace_back(df.toFullKey()); auto lock_key = df.toView().getLockKey(store_id, safe_sequence + 1); keys.emplace_back(lock_key); // not managed by the latest manifest yet df = S3Filename::newCheckpointData(store_id, 300, 1); + keys.emplace_back(df.toFullKey()); lock_key = df.toView().getLockKey(lock_store_id, safe_sequence + 1); keys.emplace_back(lock_key); // still valid in latest manifest df = S3Filename::newCheckpointData(store_id, 300, 1); + keys.emplace_back(df.toFullKey()); lock_key = df.toView().getLockKey(lock_store_id, safe_sequence - 1); valid_lock_files.emplace(lock_key); keys.emplace_back(lock_key); // not valid in latest manfiest, should be delete df = S3Filename::newCheckpointData(store_id, 300, 2); + keys.emplace_back(df.toFullKey()); lock_key = df.toView().getLockKey(lock_store_id, safe_sequence - 1); expected_deleted_lock_key = lock_key; expected_created_delmark = df.toView().getDelMarkKey(); diff --git a/dbms/src/Storages/Transaction/BackgroundService.cpp b/dbms/src/Storages/Transaction/BackgroundService.cpp index ef1003a6c4b..4da10f002ec 100644 --- a/dbms/src/Storages/Transaction/BackgroundService.cpp +++ b/dbms/src/Storages/Transaction/BackgroundService.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -27,19 +28,19 @@ BackgroundService::BackgroundService(TMTContext & tmt_) , background_pool(tmt.getContext().getBackgroundPool()) , log(Logger::get()) { - if (!tmt.isInitialized()) - throw Exception("TMTContext is not initialized", ErrorCodes::LOGICAL_ERROR); - - single_thread_task_handle = background_pool.addTask( - [this] { - tmt.getKVStore()->gcRegionPersistedCache(); - return false; - }, - false); + RUNTIME_CHECK_MSG(tmt.isInitialized(), "TMTContext is not initialized"); auto & global_context = tmt.getContext(); if (!global_context.getSharedContextDisagg()->isDisaggregatedComputeMode()) { + // compute node does not contains region + single_thread_task_handle = background_pool.addTask( + [this] { + tmt.getKVStore()->gcRegionPersistedCache(); + return false; + }, + false); + // compute node does not contain long-live tables and segments auto & global_settings = global_context.getSettingsRef(); storage_gc_handle = background_pool.addTask( diff --git a/dbms/src/Storages/Transaction/KVStore.cpp b/dbms/src/Storages/Transaction/KVStore.cpp index 81da81d34e0..51ec448d7d7 100644 --- a/dbms/src/Storages/Transaction/KVStore.cpp +++ b/dbms/src/Storages/Transaction/KVStore.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,7 @@ extern const char force_fail_in_flush_region_data[]; } // namespace FailPoints KVStore::KVStore(Context & context) - : region_persister(std::make_unique(context, region_manager)) + : region_persister(context.getSharedContextDisagg()->isDisaggregatedComputeMode() ? nullptr : std::make_unique(context, region_manager)) , raft_cmd_res(std::make_unique()) , log(Logger::get()) , region_compact_log_period(120) @@ -56,6 +57,9 @@ KVStore::KVStore(Context & context) void KVStore::restore(PathPool & path_pool, const TiFlashRaftProxyHelper * proxy_helper) { + if (!region_persister) + return; + auto task_lock = genTaskLock(); auto manage_lock = genRegionWriteLock(task_lock); @@ -174,6 +178,7 @@ void KVStore::tryPersist(RegionID region_id) if (region) { LOG_INFO(log, "Try to persist {}", region->toString(false)); + RUNTIME_CHECK_MSG(region_persister, "try access to region_persister without initialization, stack={}", StackTrace().toString()); region_persister->persist(*region); LOG_INFO(log, "After persisted {}, cache {} bytes", region->toString(false), region->dataSize()); } @@ -190,6 +195,7 @@ void KVStore::gcRegionPersistedCache(Seconds gc_persist_period) if (now < (last_gc_time.load() + gc_persist_period)) return; last_gc_time = now; + RUNTIME_CHECK_MSG(region_persister, "try access to region_persister without initialization, stack={}", StackTrace().toString()); region_persister->gc(); } @@ -211,6 +217,7 @@ void KVStore::removeRegion(RegionID region_id, bool remove_data, RegionTable & r } } + RUNTIME_CHECK_MSG(region_persister, "try access to region_persister without initialization, stack={}", StackTrace().toString()); region_persister->drop(region_id, region_lock); LOG_INFO(log, "Persisted [region {}] deleted", region_id); @@ -239,7 +246,7 @@ EngineStoreApplyRes KVStore::handleWriteRaftCmd( UInt64 region_id, UInt64 index, UInt64 term, - TMTContext & tmt) + TMTContext & tmt) const { std::vector keys; std::vector vals; @@ -280,7 +287,7 @@ EngineStoreApplyRes KVStore::handleWriteRaftCmd( tmt); } -EngineStoreApplyRes KVStore::handleWriteRaftCmd(const WriteCmdsView & cmds, UInt64 region_id, UInt64 index, UInt64 term, TMTContext & tmt) +EngineStoreApplyRes KVStore::handleWriteRaftCmd(const WriteCmdsView & cmds, UInt64 region_id, UInt64 index, UInt64 term, TMTContext & tmt) const { auto region_persist_lock = region_manager.genRegionTaskLock(region_id); @@ -329,6 +336,7 @@ void KVStore::setRegionCompactLogConfig(UInt64 sec, UInt64 rows, UInt64 bytes) void KVStore::persistRegion(const Region & region, const RegionTaskLock & region_task_lock, const char * caller) { LOG_INFO(log, "Start to persist {}, cache size: {} bytes for `{}`", region.toString(true), region.dataSize(), caller); + RUNTIME_CHECK_MSG(region_persister, "try access to region_persister without initialization, stack={}", StackTrace().toString()); region_persister->persist(region, region_task_lock); LOG_DEBUG(log, "Persist {} done", region.toString(false)); } @@ -872,6 +880,11 @@ KVStore::~KVStore() FileUsageStatistics KVStore::getFileUsageStatistics() const { + if (!region_persister) + { + return {}; + } + return region_persister->getFileUsageStatistics(); } diff --git a/dbms/src/Storages/Transaction/KVStore.h b/dbms/src/Storages/Transaction/KVStore.h index e5c171fe8ca..ba43fd72566 100644 --- a/dbms/src/Storages/Transaction/KVStore.h +++ b/dbms/src/Storages/Transaction/KVStore.h @@ -78,7 +78,7 @@ class RegionPersister; class KVStore final : private boost::noncopyable { public: - KVStore(Context & context); + explicit KVStore(Context & context); void restore(PathPool & path_pool, const TiFlashRaftProxyHelper *); RegionPtr getRegion(RegionID region_id) const; @@ -96,19 +96,20 @@ class KVStore final : private boost::noncopyable static bool tryFlushRegionCacheInStorage(TMTContext & tmt, const Region & region, const LoggerPtr & log, bool try_until_succeed = true); size_t regionSize() const; - EngineStoreApplyRes handleAdminRaftCmd(raft_cmdpb::AdminRequest && request, - raft_cmdpb::AdminResponse && response, - UInt64 region_id, - UInt64 index, - UInt64 term, - TMTContext & tmt); + EngineStoreApplyRes handleAdminRaftCmd( + raft_cmdpb::AdminRequest && request, + raft_cmdpb::AdminResponse && response, + UInt64 region_id, + UInt64 index, + UInt64 term, + TMTContext & tmt); EngineStoreApplyRes handleWriteRaftCmd( raft_cmdpb::RaftCmdRequest && request, UInt64 region_id, UInt64 index, UInt64 term, - TMTContext & tmt); - EngineStoreApplyRes handleWriteRaftCmd(const WriteCmdsView & cmds, UInt64 region_id, UInt64 index, UInt64 term, TMTContext & tmt); + TMTContext & tmt) const; + EngineStoreApplyRes handleWriteRaftCmd(const WriteCmdsView & cmds, UInt64 region_id, UInt64 index, UInt64 term, TMTContext & tmt) const; bool needFlushRegionData(UInt64 region_id, TMTContext & tmt); bool tryFlushRegionData(UInt64 region_id, bool force_persist, bool try_until_succeed, TMTContext & tmt, UInt64 index, UInt64 term); diff --git a/dbms/src/Storages/Transaction/ProxyFFIStatusService.cpp b/dbms/src/Storages/Transaction/ProxyFFIStatusService.cpp index 45c7c4a4a9b..46d77e6f23c 100644 --- a/dbms/src/Storages/Transaction/ProxyFFIStatusService.cpp +++ b/dbms/src/Storages/Transaction/ProxyFFIStatusService.cpp @@ -35,7 +35,7 @@ HttpRequestRes HandleHttpRequestSyncStatus( pingcap::pd::KeyspaceID keyspace_id = NullspaceID; { auto * log = &Poco::Logger::get("HandleHttpRequestSyncStatus"); - LOG_DEBUG(log, "handling sync status request, path: {}, api_name: {}", path, api_name); + LOG_TRACE(log, "handling sync status request, path: {}, api_name: {}", path, api_name); // Try to handle sync status request with old schema. // Old schema: /{table_id} diff --git a/dbms/src/TiDB/Schema/SchemaSyncService.cpp b/dbms/src/TiDB/Schema/SchemaSyncService.cpp index 862165f3207..e35521a285f 100644 --- a/dbms/src/TiDB/Schema/SchemaSyncService.cpp +++ b/dbms/src/TiDB/Schema/SchemaSyncService.cpp @@ -32,6 +32,9 @@ namespace ErrorCodes extern const int DEADLOCK_AVOIDED; } // namespace ErrorCodes +// TODO: make this interval configurable +constexpr size_t interval_seconds = 60; + SchemaSyncService::SchemaSyncService(DB::Context & context_) : context(context_) , background_pool(context_.getBackgroundPool()) @@ -45,7 +48,8 @@ SchemaSyncService::SchemaSyncService(DB::Context & context_) return false; }, - false); + false, + interval_seconds * 1000); } void SchemaSyncService::addKeyspaceGCTasks() @@ -62,12 +66,11 @@ void SchemaSyncService::addKeyspaceGCTasks() auto ks_log = log->getChild(fmt::format("keyspace={}", ks)); LOG_INFO(ks_log, "add sync schema task"); auto task_handle = background_pool.addTask( - [&, this, ks, ks_log] { + [&, this, ks, ks_log]() noexcept { String stage; bool done_anything = false; try { - LOG_DEBUG(ks_log, "auto sync schema", ks); /// Do sync schema first, then gc. /// They must be performed synchronously, /// otherwise table may get mis-GC-ed if RECOVER was not properly synced caused by schema sync pause but GC runs too aggressively. @@ -97,7 +100,8 @@ void SchemaSyncService::addKeyspaceGCTasks() } return false; }, - false); + false, + interval_seconds * 1000); ks_handle_map.emplace(ks, task_handle); } @@ -133,6 +137,7 @@ SchemaSyncService::~SchemaSyncService() auto task_handle = iter.second; background_pool.removeTask(task_handle); } + LOG_INFO(log, "SchemaSyncService stopped"); } bool SchemaSyncService::syncSchemas(KeyspaceID keyspace_id) From 3eb4714b79312caa2d0122d45df52565b7c9ad05 Mon Sep 17 00:00:00 2001 From: lidezhu <47731263+lidezhu@users.noreply.github.com> Date: Tue, 14 Mar 2023 17:00:39 +0800 Subject: [PATCH 07/18] Add FAP support (#6987) ref pingcap/tiflash#6827 --- contrib/tiflash-proxy-cmake/CMakeLists.txt | 10 +- dbms/src/Common/FailPoint.cpp | 1 + dbms/src/Debug/MockRaftStoreProxy.cpp | 33 ++ dbms/src/Debug/MockRaftStoreProxy.h | 4 + .../src/Flash/Disaggregated/S3LockService.cpp | 6 +- .../WNEstablishDisaggTaskHandler.cpp | 1 - .../Disaggregated/WNFetchPagesStreamWriter.h | 1 - .../tests/gtest_s3_lock_service.cpp | 3 +- dbms/src/Interpreters/Context.cpp | 34 +- dbms/src/Interpreters/Context.h | 1 + .../Interpreters/SharedContexts/Disagg.cpp | 6 + dbms/src/Interpreters/SharedContexts/Disagg.h | 6 + dbms/src/Server/BgStorageInit.cpp | 1 - dbms/src/Server/BgStorageInit.h | 1 - dbms/src/Server/Server.cpp | 1 + .../DeltaMerge/ColumnFile/ColumnFileBig.cpp | 60 ++- .../DeltaMerge/ColumnFile/ColumnFileBig.h | 7 + .../ColumnFile/ColumnFilePersisted.cpp | 25 + .../ColumnFile/ColumnFilePersisted.h | 17 + .../DeltaMerge/ColumnFile/ColumnFileTiny.cpp | 25 + .../DeltaMerge/ColumnFile/ColumnFileTiny.h | 2 + .../DeltaMerge/ColumnFile/ColumnFile_V3.cpp | 41 ++ dbms/src/Storages/DeltaMerge/DMContext.cpp | 1 - .../Delta/ColumnFilePersistedSet.cpp | 23 + .../DeltaMerge/Delta/ColumnFilePersistedSet.h | 8 + .../DeltaMerge/Delta/DeltaValueSpace.cpp | 12 + .../DeltaMerge/Delta/DeltaValueSpace.h | 8 + .../Storages/DeltaMerge/DeltaMergeStore.cpp | 2 - .../src/Storages/DeltaMerge/DeltaMergeStore.h | 46 ++ .../DeltaMerge/DeltaMergeStore_Ingest.cpp | 336 ++++++++++++ .../DeltaMergeStore_InternalSegment.cpp | 43 ++ dbms/src/Storages/DeltaMerge/File/DMFile.cpp | 6 + dbms/src/Storages/DeltaMerge/File/DMFile.h | 1 + .../File/DMFileBlockOutputStream.cpp | 1 - .../DeltaMerge/Remote/DataStore/DataStore.h | 10 +- .../Remote/DataStore/DataStoreS3.cpp | 15 +- .../DeltaMerge/Remote/DataStore/DataStoreS3.h | 8 +- .../Remote/WNDisaggSnapshotManager.cpp | 1 - .../Remote/WNDisaggSnapshotManager.h | 1 - .../Remote/WNDisaggSnapshotManager_fwd.h | 1 - dbms/src/Storages/DeltaMerge/Segment.cpp | 233 ++++++++- dbms/src/Storages/DeltaMerge/Segment.h | 33 ++ .../Storages/DeltaMerge/StableValueSpace.cpp | 82 ++- .../Storages/DeltaMerge/StableValueSpace.h | 7 + ...est_dm_delta_merge_store_fast_add_peer.cpp | 392 ++++++++++++++ .../V3/CheckpointFile/Proto/data_file.proto | 1 + .../CheckpointFile/Proto/manifest_file.proto | 1 + dbms/src/Storages/Page/V3/PageDirectory.cpp | 29 +- .../Storages/Page/V3/PageDirectoryFactory.cpp | 27 +- .../Page/V3/Universal/RaftDataReader.cpp | 11 + .../Page/V3/Universal/RaftDataReader.h | 2 + .../Page/V3/Universal/S3PageReader.cpp | 31 +- .../V3/Universal/UniversalPageIdFormatImpl.h | 9 +- .../Universal/UniversalPageStorageService.cpp | 17 +- .../Universal/UniversalPageStorageService.h | 8 + .../V3/Universal/UniversalWriteBatchImpl.h | 5 + .../V3/Universal/tests/gtest_checkpoint.cpp | 20 +- .../V3/Universal/tests/gtest_remote_read.cpp | 150 +++++- .../src/Storages/Page/WriteBatchWrapperImpl.h | 8 + dbms/src/Storages/S3/FileCache.cpp | 1 - dbms/src/Storages/S3/S3Filename.cpp | 31 ++ dbms/src/Storages/S3/S3Filename.h | 1 + .../Storages/S3/tests/gtest_s3gcmanager.cpp | 1 - dbms/src/Storages/StorageDeltaMerge.cpp | 12 + dbms/src/Storages/StorageDeltaMerge.h | 7 + .../Storages/Transaction/ApplySnapshot.cpp | 9 + .../src/Storages/Transaction/CheckpointInfo.h | 38 ++ dbms/src/Storages/Transaction/FastAddPeer.cpp | 479 ++++++++++++++++++ dbms/src/Storages/Transaction/FastAddPeer.h | 120 +++++ .../Transaction/FastAddPeerAsyncTasksImpl.h | 81 +++ dbms/src/Storages/Transaction/KVStore.h | 4 + dbms/src/Storages/Transaction/ProxyFFI.h | 2 + dbms/src/Storages/Transaction/Region.h | 2 + dbms/src/Storages/Transaction/RegionMeta.cpp | 6 + dbms/src/Storages/Transaction/RegionMeta.h | 1 + dbms/src/Storages/Transaction/RegionTable.cpp | 6 + dbms/src/Storages/Transaction/RegionTable.h | 20 + .../tests/gtest_kvstore_fast_add_peer.cpp | 259 ++++++++++ .../tests/gtest_region_persister.cpp | 2 + .../Transaction/tests/kvstore_helper.h | 1 + .../src/TestUtils/TiFlashStorageTestBasic.cpp | 1 - dbms/src/TestUtils/TiFlashTestEnv.cpp | 1 + 82 files changed, 2825 insertions(+), 135 deletions(-) create mode 100644 dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_merge_store_fast_add_peer.cpp create mode 100644 dbms/src/Storages/Transaction/CheckpointInfo.h create mode 100644 dbms/src/Storages/Transaction/FastAddPeer.cpp create mode 100644 dbms/src/Storages/Transaction/FastAddPeer.h create mode 100644 dbms/src/Storages/Transaction/FastAddPeerAsyncTasksImpl.h create mode 100644 dbms/src/Storages/Transaction/tests/gtest_kvstore_fast_add_peer.cpp diff --git a/contrib/tiflash-proxy-cmake/CMakeLists.txt b/contrib/tiflash-proxy-cmake/CMakeLists.txt index 0dca13f8b81..e440289019e 100644 --- a/contrib/tiflash-proxy-cmake/CMakeLists.txt +++ b/contrib/tiflash-proxy-cmake/CMakeLists.txt @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -option(ENABLE_UNI_PS_FFI "Enable write proxy data to uni ps" OFF) if (CMAKE_BUILD_TYPE_UC STREQUAL "DEBUG" OR SAN_DEBUG) set(_TIFLASH_PROXY_BUILD_PROFILE "debug") @@ -27,11 +26,6 @@ file(GLOB_RECURSE _TIFLASH_PROXY_SRCS "${_TIFLASH_PROXY_SOURCE_DIR}/*.rs") # Build in the build directory instead of the default source directory set(TIFLASH_RUST_ENV "CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}" ${TIFLASH_RUST_ENV}) -if(ENABLE_UNI_PS_FFI) - set(PROXY_ENABLE_FEATURES "ENABLE_FEATURES=raftstore-proxy/enable-pagestorage") -else() - set(PROXY_ENABLE_FEATURES "") -endif() # use `CFLAGS=-w CXXFLAGS=-w` to inhibit warning messages. if (TIFLASH_LLVM_TOOLCHAIN) @@ -62,12 +56,10 @@ if(TIFLASH_LLVM_TOOLCHAIN AND USE_LIBCXX) endif() message(STATUS "Using rust env for tiflash-proxy: ${TIFLASH_RUST_ENV}") -message(STATUS "Using rust features for tiflash-proxy: ${PROXY_ENABLE_FEATURES}") -message(STATUS "Using rust command for tiflash-proxy: ${_TIFLASH_PROXY_MAKE_COMMAND}") add_custom_command(OUTPUT ${_TIFLASH_PROXY_LIBRARY} COMMENT "Building TiFlash Proxy using ${_TIFLASH_PROXY_BUILD_PROFILE} profile" - COMMAND ${CMAKE_COMMAND} -E env ${TIFLASH_RUST_ENV} ${PROXY_ENABLE_FEATURES} ${_TIFLASH_PROXY_MAKE_COMMAND} + COMMAND ${CMAKE_COMMAND} -E env ${TIFLASH_RUST_ENV} ${_TIFLASH_PROXY_MAKE_COMMAND} VERBATIM USES_TERMINAL WORKING_DIRECTORY ${_TIFLASH_PROXY_SOURCE_DIR} diff --git a/dbms/src/Common/FailPoint.cpp b/dbms/src/Common/FailPoint.cpp index e35f618d9df..f83b1357026 100644 --- a/dbms/src/Common/FailPoint.cpp +++ b/dbms/src/Common/FailPoint.cpp @@ -96,6 +96,7 @@ namespace DB M(exception_in_merged_task_init) \ M(invalid_mpp_version) \ M(force_fail_in_flush_region_data) \ + M(force_use_dmfile_format_v3) \ M(force_set_mocked_s3_object_mtime) diff --git a/dbms/src/Debug/MockRaftStoreProxy.cpp b/dbms/src/Debug/MockRaftStoreProxy.cpp index 5263c361521..9558fd556ff 100644 --- a/dbms/src/Debug/MockRaftStoreProxy.cpp +++ b/dbms/src/Debug/MockRaftStoreProxy.cpp @@ -207,6 +207,39 @@ MockProxyRegion::MockProxyRegion(uint64_t id_) state.mutable_region()->set_id(id); } +UniversalWriteBatch MockProxyRegion::persistMeta() +{ + auto _ = genLockGuard(); + auto wb = UniversalWriteBatch(); + + auto region_key = UniversalPageIdFormat::toRegionLocalStateKeyInKVEngine(this->id); + auto region_local_state = this->state.SerializeAsString(); + MemoryWriteBuffer buf(0, region_local_state.size()); + buf.write(region_local_state.data(), region_local_state.size()); + wb.putPage(UniversalPageId(region_key.data(), region_key.size()), 0, buf.tryGetReadBuffer(), region_local_state.size()); + + auto apply_key = UniversalPageIdFormat::toRaftApplyStateKeyInKVEngine(this->id); + auto raft_apply_state = this->apply.SerializeAsString(); + MemoryWriteBuffer buf2(0, raft_apply_state.size()); + buf2.write(raft_apply_state.data(), raft_apply_state.size()); + wb.putPage(UniversalPageId(apply_key.data(), apply_key.size()), 0, buf2.tryGetReadBuffer(), raft_apply_state.size()); + + raft_serverpb::RegionLocalState restored_region_state; + raft_serverpb::RaftApplyState restored_apply_state; + restored_region_state.ParseFromArray(region_local_state.data(), region_local_state.size()); + restored_apply_state.ParseFromArray(raft_apply_state.data(), raft_apply_state.size()); + return wb; +} + +void MockProxyRegion::addPeer(uint64_t store_id, uint64_t peer_id, metapb::PeerRole role) +{ + auto _ = genLockGuard(); + auto & peer = *state.mutable_region()->mutable_peers()->Add(); + peer.set_store_id(store_id); + peer.set_id(peer_id); + peer.set_role(role); +} + std::optional RawMockReadIndexTask::poll(std::shared_ptr waker) { auto _ = genLockGuard(); diff --git a/dbms/src/Debug/MockRaftStoreProxy.h b/dbms/src/Debug/MockRaftStoreProxy.h index 6207e7e8b17..97d76c332bd 100644 --- a/dbms/src/Debug/MockRaftStoreProxy.h +++ b/dbms/src/Debug/MockRaftStoreProxy.h @@ -14,6 +14,7 @@ #pragma once +#include #include #include #include @@ -36,6 +37,9 @@ struct MockProxyRegion : MutexLockWrap void updateCommitIndex(uint64_t index); void setSate(raft_serverpb::RegionLocalState); explicit MockProxyRegion(uint64_t id); + UniversalWriteBatch persistMeta(); + void addPeer(uint64_t store_id, uint64_t peer_id, metapb::PeerRole role); + struct RawWrite { std::vector keys; diff --git a/dbms/src/Flash/Disaggregated/S3LockService.cpp b/dbms/src/Flash/Disaggregated/S3LockService.cpp index b636951a7c9..825f57f2d54 100644 --- a/dbms/src/Flash/Disaggregated/S3LockService.cpp +++ b/dbms/src/Flash/Disaggregated/S3LockService.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -39,8 +40,6 @@ extern const Metric S3LockServiceNumLatches; namespace DB::S3 { - - S3LockService::S3LockService(Context & context_) : S3LockService( context_.getGlobalContext().getTMTContext().getS3GCOwnerManager()) @@ -200,7 +199,8 @@ bool S3LockService::tryAddLockImpl( auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); // make sure data file exists - if (!DB::S3::objectExists(*s3_client, s3_client->bucket(), data_file_key)) + auto object_key = key_view.isDMFile() ? fmt::format("{}/{}", data_file_key, DM::DMFile::metav2FileName()) : data_file_key; + if (!DB::S3::objectExists(*s3_client, s3_client->bucket(), object_key)) { auto * e = response->mutable_result()->mutable_conflict(); e->set_reason(fmt::format("data file not exist, key={}", data_file_key)); diff --git a/dbms/src/Flash/Disaggregated/WNEstablishDisaggTaskHandler.cpp b/dbms/src/Flash/Disaggregated/WNEstablishDisaggTaskHandler.cpp index eb0ac531740..ddedace9e65 100644 --- a/dbms/src/Flash/Disaggregated/WNEstablishDisaggTaskHandler.cpp +++ b/dbms/src/Flash/Disaggregated/WNEstablishDisaggTaskHandler.cpp @@ -30,7 +30,6 @@ namespace DB { - namespace ErrorCodes { extern const int REGION_EPOCH_NOT_MATCH; diff --git a/dbms/src/Flash/Disaggregated/WNFetchPagesStreamWriter.h b/dbms/src/Flash/Disaggregated/WNFetchPagesStreamWriter.h index 260376bdf43..3e37383aab5 100644 --- a/dbms/src/Flash/Disaggregated/WNFetchPagesStreamWriter.h +++ b/dbms/src/Flash/Disaggregated/WNFetchPagesStreamWriter.h @@ -30,7 +30,6 @@ namespace DB { - using SyncPagePacketWriter = grpc::ServerWriter; class WNFetchPagesStreamWriter; diff --git a/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp b/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp index 3b2ddd18d6d..594a6a0529b 100644 --- a/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp +++ b/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -65,7 +66,7 @@ class S3LockServiceTest for (size_t i = 1; i <= 5; ++i) { auto data_filename = S3Filename::fromDMFileOID(DMFileOID{.store_id = store_id, .table_id = physical_table_id, .file_id = dm_file_id}); - DB::S3::uploadEmptyFile(*s3_client, s3_client->bucket(), data_filename.toFullKey()); + DB::S3::uploadEmptyFile(*s3_client, s3_client->bucket(), fmt::format("{}/{}", data_filename.toFullKey(), DM::DMFile::metav2FileName())); ++dm_file_id; } } diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 0ebc700a8a6..9c1e4e77b4d 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -1713,12 +1713,7 @@ void Context::initializeWriteNodePageStorageIfNeed(const PathPool & path_pool) auto lock = getLock(); if (shared->storage_run_mode == PageStorageRunMode::UNI_PS) { - if (shared->ps_write) - { - // GlobalStoragePool may be initialized many times in some test cases for restore. - LOG_WARNING(shared->log, "GlobalUniversalPageStorage(WriteNode) has already been initialized."); - shared->ps_write->shutdown(); - } + RUNTIME_CHECK(shared->ps_write == nullptr); try { PageStorageConfig config; @@ -1755,6 +1750,33 @@ UniversalPageStoragePtr Context::getWriteNodePageStorage() const } } +// In some unit tests, we may want to reinitialize WriteNodePageStorage multiple times to mock restart. +// And we need to release old one before creating new one. +// And we must do it explicitly. Because if we do it implicitly in `initializeWriteNodePageStorageIfNeed`, there is a potential deadlock here. +// Thread A: +// Get lock on SharedContext -> call UniversalPageStorageService::shutdown -> remove background tasks -> try get rwlock on the task +// Thread B: +// Get rwlock on task -> call a method on Context to get some object -> try to get lock on SharedContext +void Context::tryReleaseWriteNodePageStorageForTest() +{ + UniversalPageStorageServicePtr ps_write; + { + auto lock = getLock(); + if (shared->ps_write) + { + LOG_WARNING(shared->log, "Release GlobalUniversalPageStorage(WriteNode)."); + ps_write = shared->ps_write; + shared->ps_write = nullptr; + } + } + if (ps_write) + { + // call shutdown without lock + ps_write->shutdown(); + ps_write = nullptr; + } +} + SharedContextDisaggPtr Context::getSharedContextDisagg() const { RUNTIME_CHECK(shared->ctx_disagg != nullptr); // We always initialize the shared context in createGlobal() diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 7961ca1e364..3d83faf71d0 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -429,6 +429,7 @@ class Context void initializeWriteNodePageStorageIfNeed(const PathPool & path_pool); UniversalPageStoragePtr getWriteNodePageStorage() const; + void tryReleaseWriteNodePageStorageForTest(); SharedContextDisaggPtr getSharedContextDisagg() const; diff --git a/dbms/src/Interpreters/SharedContexts/Disagg.cpp b/dbms/src/Interpreters/SharedContexts/Disagg.cpp index edfd6dd5c5b..072fac88aa4 100644 --- a/dbms/src/Interpreters/SharedContexts/Disagg.cpp +++ b/dbms/src/Interpreters/SharedContexts/Disagg.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace DB { @@ -91,4 +92,9 @@ void SharedContextDisagg::initRemoteDataStore(const FileProviderPtr & file_provi remote_data_store = std::make_shared(file_provider); } +void SharedContextDisagg::initFastAddPeerContext() +{ + fap_context = std::make_shared(); +} + } // namespace DB diff --git a/dbms/src/Interpreters/SharedContexts/Disagg.h b/dbms/src/Interpreters/SharedContexts/Disagg.h index 91daab20d0b..f809cbefe17 100644 --- a/dbms/src/Interpreters/SharedContexts/Disagg.h +++ b/dbms/src/Interpreters/SharedContexts/Disagg.h @@ -29,6 +29,8 @@ namespace DB { +class FastAddPeerContext; +using FastAddPeerContextPtr = std::shared_ptr; /** * A shared context containing disaggregated mode related things. @@ -50,6 +52,8 @@ struct SharedContextDisagg : private boost::noncopyable /// For both read node (downloading) and write node (uploading). DM::Remote::IDataStorePtr remote_data_store; + FastAddPeerContextPtr fap_context; + /// Only for write node. DM::Remote::WNDisaggSnapshotManagerPtr wn_snapshot_manager; @@ -81,6 +85,8 @@ struct SharedContextDisagg : private boost::noncopyable void initRemoteDataStore(const FileProviderPtr & file_provider, bool s3_enabled); + void initFastAddPeerContext(); + bool isDisaggregatedComputeMode() const { return disaggregated_mode == DisaggregatedMode::Compute; diff --git a/dbms/src/Server/BgStorageInit.cpp b/dbms/src/Server/BgStorageInit.cpp index 2fa8a53a94a..c53953cf25a 100644 --- a/dbms/src/Server/BgStorageInit.cpp +++ b/dbms/src/Server/BgStorageInit.cpp @@ -24,7 +24,6 @@ namespace DB { - void BgStorageInitHolder::waitUntilFinish() { if (need_join) diff --git a/dbms/src/Server/BgStorageInit.h b/dbms/src/Server/BgStorageInit.h index 66036fae09a..0449d8e48f0 100644 --- a/dbms/src/Server/BgStorageInit.h +++ b/dbms/src/Server/BgStorageInit.h @@ -21,7 +21,6 @@ namespace DB { - struct BgStorageInitHolder { bool need_join = false; diff --git a/dbms/src/Server/Server.cpp b/dbms/src/Server/Server.cpp index cc687f20f55..761f55755f1 100644 --- a/dbms/src/Server/Server.cpp +++ b/dbms/src/Server/Server.cpp @@ -1181,6 +1181,7 @@ int Server::main(const std::vector & /*args*/) if (global_context->getSharedContextDisagg()->isDisaggregatedStorageMode()) { global_context->getSharedContextDisagg()->initWriteNodeSnapManager(); + global_context->getSharedContextDisagg()->initFastAddPeerContext(); } if (global_context->getSharedContextDisagg()->isDisaggregatedComputeMode()) diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.cpp b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.cpp index c3394816765..83a48b20a14 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.cpp +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.cpp @@ -17,12 +17,14 @@ #include #include #include +#include #include #include #include #include #include + namespace DB { namespace DM @@ -89,25 +91,75 @@ ColumnFilePersistedPtr ColumnFileBig::deserializeMetadata(const DMContext & cont auto file_id = context.storage_pool->dataReader()->getNormalPageId(file_page_id); String file_parent_path; - if (context.db_context.getSharedContextDisagg()->remote_data_store) + DMFilePtr dmfile; + auto remote_data_store = context.db_context.getSharedContextDisagg()->remote_data_store; + if (remote_data_store) { auto wn_ps = context.db_context.getWriteNodePageStorage(); auto full_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Data, context.storage_pool->getNamespaceId()), file_page_id); auto remote_data_location = wn_ps->getCheckpointLocation(full_page_id); const auto & lock_key_view = S3::S3FilenameView::fromKey(*(remote_data_location->data_file_id)); - file_parent_path = S3::S3Filename::fromTableID(lock_key_view.store_id, context.storage_pool->getNamespaceId()).toFullKeyWithPrefix(); + auto dtfile_key = lock_key_view.asDataFile(); + auto file_oid = dtfile_key.getDMFileOID(); + auto prepared = remote_data_store->prepareDMFile(file_oid, file_page_id); + dmfile = prepared->restore(DMFile::ReadMetaMode::all()); } else { file_parent_path = context.path_pool->getStableDiskDelegator().getDTFilePath(file_id); + dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, file_page_id, file_parent_path, DMFile::ReadMetaMode::all()); } - auto dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, file_page_id, file_parent_path, DMFile::ReadMetaMode::all()); - auto * dp_file = new ColumnFileBig(dmfile, valid_rows, valid_bytes, segment_range); return std::shared_ptr(dp_file); } +ColumnFilePersistedPtr ColumnFileBig::createFromCheckpoint(DMContext & context, // + const RowKeyRange & target_range, + ReadBuffer & buf, + UniversalPageStoragePtr temp_ps, + TableID ns_id, + WriteBatches & wbs) +{ + UInt64 file_page_id; + size_t valid_rows, valid_bytes; + + readIntBinary(file_page_id, buf); + readIntBinary(valid_rows, buf); + readIntBinary(valid_bytes, buf); + + // get target dtfile s3 key + auto remote_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Data, ns_id), file_page_id); + auto remote_data_location = temp_ps->getCheckpointLocation(remote_page_id); + auto remote_file_id = temp_ps->getNormalPageId(remote_page_id); + auto file_id = UniversalPageIdFormat::getU64ID(remote_file_id); + + const auto & lock_key_view = S3::S3FilenameView::fromKey(*(remote_data_location->data_file_id)); + S3::DMFileOID file_oid{ + .store_id = lock_key_view.store_id, + .table_id = ns_id, + .file_id = file_id}; + RUNTIME_CHECK(lock_key_view.asDataFile().toFullKey() == S3::S3Filename::fromDMFileOID(file_oid).toFullKey()); + + auto data_key = S3::S3Filename::fromDMFileOID(file_oid).toFullKey(); + auto delegator = context.path_pool->getStableDiskDelegator(); + auto & storage_pool = context.storage_pool; + auto new_local_page_id = storage_pool->newDataPageIdForDTFile(delegator, __PRETTY_FUNCTION__); + PS::V3::CheckpointLocation loc{ + .data_file_id = std::make_shared(data_key), + .offset_in_file = 0, + .size_in_file = 0, + }; + wbs.data.putRemoteExternal(new_local_page_id, loc); + + auto parent_path = S3::S3Filename::fromTableID(lock_key_view.store_id, ns_id).toFullKeyWithPrefix(); + auto new_dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, new_local_page_id, parent_path, DMFile::ReadMetaMode::all()); + wbs.writeLogAndData(); + new_dmfile->enableGC(); + auto * dp_file = new ColumnFileBig(new_dmfile, valid_rows, valid_bytes, target_range); + return std::shared_ptr(dp_file); +} + void ColumnFileBigReader::initStream() { if (file_stream) diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.h b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.h index 9b4293296c9..cf0c8080626 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.h +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.h @@ -88,6 +88,13 @@ class ColumnFileBig : public ColumnFilePersisted const RowKeyRange & segment_range, ReadBuffer & buf); + static ColumnFilePersistedPtr createFromCheckpoint(DMContext & context, // + const RowKeyRange & target_range, + ReadBuffer & buf, + UniversalPageStoragePtr temp_ps, + TableID ns_id, + WriteBatches & wbs); + String toString() const override { String s = "{big_file,rows:" + DB::toString(getRows()) // diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFilePersisted.cpp b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFilePersisted.cpp index f575d4c4418..e9a22a28eaf 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFilePersisted.cpp +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFilePersisted.cpp @@ -131,5 +131,30 @@ ColumnFilePersisteds deserializeSavedColumnFiles(const DMContext & context, cons } return column_files; } + +ColumnFilePersisteds createColumnFilesFromCheckpoint( // + DMContext & context, + const RowKeyRange & segment_range, + ReadBuffer & buf, + UniversalPageStoragePtr temp_ps, + TableID ns_id, + WriteBatches & wbs) +{ + // Check binary version + DeltaFormat::Version version; + readIntBinary(version, buf); + + ColumnFilePersisteds column_files; + switch (version) + { + case DeltaFormat::V3: + column_files = createColumnFilesInV3FormatFromCheckpoint(context, segment_range, buf, temp_ps, ns_id, wbs); + break; + default: + throw Exception("Unexpected delta value version: " + DB::toString(version) + ", latest version: " + DB::toString(DeltaFormat::V3), + ErrorCodes::LOGICAL_ERROR); + } + return column_files; +} } // namespace DM } // namespace DB diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFilePersisted.h b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFilePersisted.h index 241ab351c4f..43707e178ea 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFilePersisted.h +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFilePersisted.h @@ -19,6 +19,8 @@ namespace DB { +class UniversalPageStorage; +using UniversalPageStoragePtr = std::shared_ptr; namespace DM { struct WriteBatches; @@ -48,11 +50,26 @@ void serializeSavedColumnFiles(WriteBuffer & buf, const ColumnFilePersisteds & c /// Recreate column file instances from buf. ColumnFilePersisteds deserializeSavedColumnFiles(const DMContext & context, const RowKeyRange & segment_range, ReadBuffer & buf); +ColumnFilePersisteds createColumnFilesFromCheckpoint( // + DMContext & context, + const RowKeyRange & segment_range, + ReadBuffer & buf, + UniversalPageStoragePtr temp_ps, + TableID ns_id, + WriteBatches & wbs); + void serializeSavedColumnFilesInV2Format(WriteBuffer & buf, const ColumnFilePersisteds & column_files); ColumnFilePersisteds deserializeSavedColumnFilesInV2Format(const DMContext & context, ReadBuffer & buf, UInt64 version); void serializeSavedColumnFilesInV3Format(WriteBuffer & buf, const ColumnFilePersisteds & column_files); ColumnFilePersisteds deserializeSavedColumnFilesInV3Format(const DMContext & context, const RowKeyRange & segment_range, ReadBuffer & buf); +ColumnFilePersisteds createColumnFilesInV3FormatFromCheckpoint( // + DMContext & context, + const RowKeyRange & segment_range, + ReadBuffer & buf, + UniversalPageStoragePtr temp_ps, + TableID ns_id, + WriteBatches & wbs); } // namespace DM } // namespace DB diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.cpp b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.cpp index 5b93a5f61a5..6608a501cf7 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.cpp +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -174,6 +175,30 @@ ColumnFilePersistedPtr ColumnFileTiny::deserializeMetadata(const DMContext & con return std::make_shared(schema, rows, bytes, data_page_id); } +std::tuple ColumnFileTiny::createFromCheckpoint(const DMContext & context, ReadBuffer & buf, UniversalPageStoragePtr temp_ps, const BlockPtr & last_schema, TableID ns_id, WriteBatches & wbs) +{ + auto schema = deserializeSchema(buf); + if (!schema) + schema = last_schema; + RUNTIME_CHECK(schema != nullptr); + + PageIdU64 data_page_id; + size_t rows, bytes; + + readIntBinary(data_page_id, buf); + readIntBinary(rows, buf); + readIntBinary(bytes, buf); + auto new_cf_id = context.storage_pool->newLogPageId(); + auto remote_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Log, ns_id), data_page_id); + auto remote_data_location = temp_ps->getCheckpointLocation(remote_page_id); + RUNTIME_CHECK(remote_data_location.has_value()); + auto entry = temp_ps->getEntry(remote_page_id); + wbs.log.putRemotePage(new_cf_id, 0, *remote_data_location, std::move(entry.field_offsets)); + + auto column_file_schema = std::make_shared(*schema); + return {std::make_shared(column_file_schema, rows, bytes, new_cf_id), std::move(schema)}; +} + Block ColumnFileTiny::readBlockForMinorCompaction(const PageReader & page_reader) const { if (cache) diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.h b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.h index 5013518e760..164c81f8ef2 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.h +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.h @@ -119,6 +119,8 @@ class ColumnFileTiny : public ColumnFilePersisted static ColumnFilePersistedPtr deserializeMetadata(const DMContext & context, ReadBuffer & buf, ColumnFileSchemaPtr & last_schema); + static std::tuple createFromCheckpoint(const DMContext & context, ReadBuffer & buf, UniversalPageStoragePtr temp_ps, const BlockPtr & last_schema, TableID ns_id, WriteBatches & wbs); + bool mayBeFlushedFrom(ColumnFile * from_file) const override { // The current ColumnFileTiny may come from a ColumnFileInMemory (which contains data in memory) diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile_V3.cpp b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile_V3.cpp index cb7378c5d24..29dfb0f9229 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile_V3.cpp +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile_V3.cpp @@ -97,5 +97,46 @@ ColumnFilePersisteds deserializeSavedColumnFilesInV3Format(const DMContext & con return column_files; } +ColumnFilePersisteds createColumnFilesInV3FormatFromCheckpoint( // + DMContext & context, + const RowKeyRange & segment_range, + ReadBuffer & buf, + UniversalPageStoragePtr temp_ps, + TableID ns_id, + WriteBatches & wbs) +{ + size_t column_file_count; + readIntBinary(column_file_count, buf); + ColumnFilePersisteds column_files; + column_files.reserve(column_file_count); + BlockPtr last_schema; + for (size_t i = 0; i < column_file_count; ++i) + { + std::underlying_type::type column_file_type; + readIntBinary(column_file_type, buf); + ColumnFilePersistedPtr column_file; + switch (column_file_type) + { + case ColumnFile::Type::DELETE_RANGE: + column_file = ColumnFileDeleteRange::deserializeMetadata(buf); + break; + case ColumnFile::Type::TINY_FILE: + { + std::tie(column_file, last_schema) = ColumnFileTiny::createFromCheckpoint(context, buf, temp_ps, last_schema, ns_id, wbs); + break; + } + case ColumnFile::Type::BIG_FILE: + { + column_file = ColumnFileBig::createFromCheckpoint(context, segment_range, buf, temp_ps, ns_id, wbs); + break; + } + default: + throw Exception("Unexpected column file type: " + DB::toString(column_file_type), ErrorCodes::LOGICAL_ERROR); + } + column_files.emplace_back(std::move(column_file)); + } + return column_files; +} + } // namespace DM } // namespace DB diff --git a/dbms/src/Storages/DeltaMerge/DMContext.cpp b/dbms/src/Storages/DeltaMerge/DMContext.cpp index e33746c046e..2a5a4fa876d 100644 --- a/dbms/src/Storages/DeltaMerge/DMContext.cpp +++ b/dbms/src/Storages/DeltaMerge/DMContext.cpp @@ -17,7 +17,6 @@ namespace DB::DM { - WriteLimiterPtr DMContext::getWriteLimiter() const { return db_context.getWriteLimiter(); diff --git a/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.cpp b/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.cpp index 5fd66750d75..9fae9f45200 100644 --- a/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.cpp +++ b/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -96,6 +97,28 @@ ColumnFilePersistedSetPtr ColumnFilePersistedSet::restore( // return std::make_shared(id, column_files); } +ColumnFilePersistedSetPtr ColumnFilePersistedSet::createFromCheckpoint( // + DMContext & context, + UniversalPageStoragePtr temp_ps, + const RowKeyRange & segment_range, + NamespaceId ns_id, + PageIdU64 delta_id, + WriteBatches & wbs) +{ + auto delta_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Meta, ns_id), delta_id); + auto meta_page = temp_ps->read(delta_page_id); + ReadBufferFromMemory meta_buf(meta_page.data.begin(), meta_page.data.size()); + auto column_files = createColumnFilesFromCheckpoint( + context, + segment_range, + meta_buf, + temp_ps, + ns_id, + wbs); + auto new_persisted_set = std::make_shared(delta_id, column_files); + return new_persisted_set; +} + void ColumnFilePersistedSet::saveMeta(WriteBatches & wbs) const { serializeColumnFilePersisteds(wbs, metadata_id, persisted_files); diff --git a/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.h b/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.h index aa5f8a86b7d..5e60ecec05d 100644 --- a/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.h +++ b/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.h @@ -75,6 +75,14 @@ class ColumnFilePersistedSet : public std::enable_shared_from_this(std::move(persisted_file_set)); } +DeltaValueSpacePtr DeltaValueSpace::createFromCheckpoint( // + DMContext & context, + UniversalPageStoragePtr temp_ps, + const RowKeyRange & segment_range, + NamespaceId ns_id, + PageIdU64 delta_id, + WriteBatches & wbs) +{ + auto persisted_file_set = ColumnFilePersistedSet::createFromCheckpoint(context, temp_ps, segment_range, ns_id, delta_id, wbs); + return std::make_shared(std::move(persisted_file_set)); +} + void DeltaValueSpace::saveMeta(WriteBatches & wbs) const { persisted_file_set->saveMeta(wbs); diff --git a/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.h b/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.h index 0b80d552779..71e54836129 100644 --- a/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.h +++ b/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.h @@ -111,6 +111,14 @@ class DeltaValueSpace /// Only called after reboot. static DeltaValueSpacePtr restore(DMContext & context, const RowKeyRange & segment_range, PageIdU64 id); + static DeltaValueSpacePtr createFromCheckpoint( // + DMContext & context, + UniversalPageStoragePtr temp_ps, + const RowKeyRange & segment_range, + NamespaceId ns_id, + PageIdU64 delta_id, + WriteBatches & wbs); + /** * Resets the logger by using the one from the segment. * Segment_log is not available when constructing, because usually diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp index 617b359b5db..14aca60cead 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp @@ -42,8 +42,6 @@ #include #include #include -#include -#include #include #include diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h index fc371c44936..327d52721e1 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,8 @@ namespace DB class Logger; using LoggerPtr = std::shared_ptr; +struct CheckpointInfo; +using CheckpointInfoPtr = std::shared_ptr; class StoragePathPool; @@ -298,6 +301,29 @@ class DeltaMergeStore : private boost::noncopyable return ingestFiles(dm_context, range, external_files, clear_data_in_range); } + std::vector ingestSegmentsUsingSplit( + const DMContextPtr & dm_context, + const RowKeyRange & ingest_range, + const std::vector & target_segments); + + bool ingestSegmentDataIntoSegmentUsingSplit( + DMContext & dm_context, + const SegmentPtr & segment, + const SegmentPtr & segment_to_ingest); + + void ingestSegmentsFromCheckpointInfo(const DMContextPtr & dm_context, + const DM::RowKeyRange & range, + CheckpointInfoPtr checkpoint_info); + + void ingestSegmentsFromCheckpointInfo(const Context & db_context, + const DB::Settings & db_settings, + const DM::RowKeyRange & range, + CheckpointInfoPtr checkpoint_info) + { + auto dm_context = newDMContext(db_context, db_settings); + return ingestSegmentsFromCheckpointInfo(dm_context, range, checkpoint_info); + } + /// Read all rows without MVCC filtering BlockInputStreams readRaw(const Context & db_context, const DB::Settings & db_settings, @@ -574,6 +600,26 @@ class DeltaMergeStore : private boost::noncopyable const DMFilePtr & data_file, bool clear_all_data_in_segment); + /** + * Discard all data in the segment, and use the specified DMFile as the stable instead. + * The specified DMFile is safe to be shared for multiple segments. + * + * Note 1: This function will not enable GC for the new_stable_file for you, in case of you may want to share the same + * stable file for multiple segments. It is your own duty to enable GC later. + * + * Note 2: You must ensure the specified new_stable_file has been managed by the storage pool, and has been written + * to the PageStorage's data. Otherwise there will be exceptions. + * + * Note 3: This API is subjected to be changed in future, as it relies on the knowledge that all current data + * in this segment is useless, which is a pretty tough requirement. + * TODO: use `segmentIngestData` to replace this api + */ + SegmentPtr segmentDangerouslyReplaceDataFromCheckpoint( + DMContext & dm_context, + const SegmentPtr & segment, + const DMFilePtr & data_file, + const ColumnFilePersisteds & column_file_persisteds); + // isSegmentValid should be protected by lock on `read_write_mutex` bool isSegmentValid(const std::shared_lock &, const SegmentPtr & segment) { diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore_Ingest.cpp b/dbms/src/Storages/DeltaMerge/DeltaMergeStore_Ingest.cpp index 8023c8f5299..7f7971b580f 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore_Ingest.cpp +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore_Ingest.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -710,5 +712,339 @@ void DeltaMergeStore::ingestFiles( checkSegmentUpdate(dm_context, segment, ThreadType::Write); } +std::vector DeltaMergeStore::ingestSegmentsUsingSplit( + const DMContextPtr & dm_context, + const RowKeyRange & ingest_range, + const std::vector & target_segments) +{ + std::set updated_segments; + + // First phase (DeleteRange Phase): + // Write DeleteRange to the covered segments to ensure that all data in the `ingest_range` is cleared. + { + RowKeyRange remaining_delete_range = ingest_range; + LOG_INFO( + log, + "Table ingest checkpoint using split - delete range phase - begin, remaining_delete_range={}", + remaining_delete_range.toDebugString()); + + while (!remaining_delete_range.none()) + { + SegmentPtr segment; + { + std::shared_lock lock(read_write_mutex); + + auto segment_it = segments.upper_bound(remaining_delete_range.getStart()); + RUNTIME_CHECK(segment_it != segments.end(), remaining_delete_range.toDebugString()); + segment = segment_it->second; + } + + const auto delete_range = remaining_delete_range.shrink(segment->getRowKeyRange()); + RUNTIME_CHECK( + !delete_range.none(), // as remaining_delete_range is not none, we expect the shrinked range to be not none. + delete_range.toDebugString(), + segment->simpleInfo(), + remaining_delete_range.toDebugString()); + LOG_DEBUG( + log, + "Table ingest checkpoint using split - delete range phase - Try to delete range in segment, delete_range={} segment={} remaining_delete_range={} updated_segments_n={}", + delete_range.toDebugString(), + segment->simpleInfo(), + remaining_delete_range.toDebugString(), + updated_segments.size()); + + const bool succeeded = segment->write(*dm_context, delete_range); + if (succeeded) + { + updated_segments.insert(segment); + RUNTIME_CHECK(compare(delete_range.getEnd(), remaining_delete_range.getStart()) >= 0); + remaining_delete_range.setStart(delete_range.end); // We always move forward + } + else + { + // segment may be abandoned, retry current range by finding the segment again. + } + } + } + + LOG_DEBUG( + log, + "Table ingest checkpoint using split - delete range phase - finished, updated_segments_n={}", + updated_segments.size()); + + /* + * In second phase (SplitIngest Phase), + * we will try to ingest DMFile one by one into the segments in order. + * + * Consider the following case: + * -Inf +Inf + * │ │--------------- Ingest Range ---------------│ │ + * │ │-- DMFile --│- DMFile --│---- DMFile ----│- DMFile --│ │ + * │- Segment --│-- Seg --│------- Segment -----│- Seg -│------- Segment --------│ + * + * This is what we will ingest: + * Iterate 0: + * -Inf +Inf + * │ │--------------- Ingest Range ---------------│ │ + * │ │-- DMFile --│ │ + * │ │-- Seg --│------- Segment -----│ │ + * ↑ ↑ The segment we ingest DMFile into + * + * Iterate 1: + * -Inf +Inf + * │ │--------------- Ingest Range ---------------│ │ + * │ │************│- DMFile --│ │ + * │ │------- Segment -----│ │ + * ↑ The segment we ingest DMFile into + */ + + LOG_DEBUG( + log, + "Table ingest checkpoint using split - split ingest phase - begin, ingest_range={}, files_n={}", + ingest_range.toDebugString(), + target_segments.size()); + + for (size_t file_idx = 0; file_idx < target_segments.size(); file_idx++) + { + // This should not happen. Just check to be confident. + // Even if it happened, we could handle it gracefully here. (but it really means somewhere else is broken) + if (target_segments[file_idx]->getEstimatedRows() == 0) + { + LOG_WARNING( + log, + "Table ingest checkpoint using split - split ingest phase - Unexpected empty DMFile, skipped. ingest_range={} file_idx={}", + ingest_range.toDebugString(), + file_idx); + continue; + } + + /** + * Each DMFile (bounded by the ingest range) may overlap with multiple segments, like: + * -Inf +Inf + * │ │--------------- Ingest Range ---------------│ │ + * │ │-- DMFile --│ │ + * │ │-- Seg --│------- Segment -----│ │ + * We will try to ingest it into all overlapped segments. + */ + auto file_ingest_range = target_segments[file_idx]->getRowKeyRange(); + while (!file_ingest_range.none()) // This DMFile has remaining data to ingest + { + SegmentPtr segment; + { + std::shared_lock lock(read_write_mutex); + auto segment_it = segments.upper_bound(file_ingest_range.getStart()); + RUNTIME_CHECK(segment_it != segments.end()); + segment = segment_it->second; + } + + if (segment->hasAbandoned()) + continue; // retry with current range and file + + /** + * -Inf +Inf + * │ │--------------- Ingest Range ---------------│ │ + * │ │-- DMFile --│ │ + * │ │-- Seg --│------- Segment -----│ │ + * ^^^^^^^^ segment_ingest_range + */ + const auto segment_ingest_range = file_ingest_range.shrink(segment->getRowKeyRange()); + RUNTIME_CHECK(!segment_ingest_range.none()); + + LOG_INFO( + log, + "Table ingest checkpoint using split - split ingest phase - Try to ingest file into segment, segment_idx={} segment_id={} segment_ingest_range={} segment={} segment_ingest_range={}", + file_idx, + target_segments[file_idx]->segmentId(), + file_ingest_range.toDebugString(), + segment->simpleInfo(), + segment_ingest_range.toDebugString()); + + const bool succeeded = ingestSegmentDataIntoSegmentUsingSplit(*dm_context, segment, target_segments[file_idx]); + if (succeeded) + { + updated_segments.insert(segment); + // We have ingested (DTFileRange ∪ ThisSegmentRange), let's try with next overlapped segment. + RUNTIME_CHECK(compare(segment_ingest_range.getEnd(), file_ingest_range.getStart()) > 0); + file_ingest_range.setStart(segment_ingest_range.end); + } + else + { + // this segment is abandoned, or may be split into multiples. + // retry with current range and file and find segment again. + } + } + } + + LOG_DEBUG( + log, + "Table ingest checkpoint using split - split ingest phase - finished, updated_segments_n={}", + updated_segments.size()); + + return std::vector( + updated_segments.begin(), + updated_segments.end()); +} + +bool DeltaMergeStore::ingestSegmentDataIntoSegmentUsingSplit( + DMContext & dm_context, + const SegmentPtr & segment, + const SegmentPtr & segment_to_ingest) +{ + const auto & segment_range = segment->getRowKeyRange(); + const auto & ingest_range = segment_to_ingest->getRowKeyRange(); + + // The ingest_range must fall in segment's range. + RUNTIME_CHECK( + !ingest_range.none(), + ingest_range.toDebugString()); + RUNTIME_CHECK( + compare(segment_range.getStart(), ingest_range.getStart()) <= 0, + segment_range.toDebugString(), + ingest_range.toDebugString()); + RUNTIME_CHECK( + compare(segment_range.getEnd(), ingest_range.getEnd()) >= 0, + segment_range.toDebugString(), + ingest_range.toDebugString()); + + const bool is_start_matching = (compare(segment_range.getStart(), ingest_range.getStart()) == 0); + const bool is_end_matching = (compare(segment_range.getEnd(), ingest_range.getEnd()) == 0); + + if (is_start_matching && is_end_matching) + { + /* + * The segment and the ingest range is perfectly matched. We can + * simply replace all of the data from this segment. + * + * Example: + * │----------- Segment ----------│ + * │-------- Ingest Range --------│ + */ + WriteBatches wbs{*dm_context.storage_pool}; + auto dm_files = segment_to_ingest->getStable()->getDMFiles(); + auto [in_memory_files, column_file_persisteds] = segment_to_ingest->getDelta()->cloneAllColumnFiles( + segment_to_ingest->mustGetUpdateLock(), + dm_context, + ingest_range, + wbs); + wbs.writeLogAndData(); + RUNTIME_CHECK(in_memory_files.empty()); + RUNTIME_CHECK(dm_files.size() == 1); + const auto new_segment_or_null = segmentDangerouslyReplaceDataFromCheckpoint(dm_context, segment, dm_files[0], column_file_persisteds); + const bool succeeded = new_segment_or_null != nullptr; + if (!succeeded) + { + wbs.rollbackWrittenLogAndData(); + } + return succeeded; + } + else if (is_start_matching) + { + /* + * Example: + * │--------------- Segment ---------------│ + * │-------- Ingest Range --------│ + * + * We will logical split the segment to form a perfect matching segment: + * │--------------- Segment ------│--------│ + * │-------- Ingest Range --------│ + */ + const auto [left, right] = segmentSplit(dm_context, segment, SegmentSplitReason::ForIngest, ingest_range.end, SegmentSplitMode::Logical); + if (left == nullptr || right == nullptr) + { + // Split failed, likely caused by snapshot failed. + // Sleep awhile and retry. + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + } + // Always returning false, because we need to retry to get a new segment (as the old segment is abandoned) + // even when split succeeded. + return false; + } + else if (is_end_matching) + { + /* + * Example: + * │--------------- Segment ---------------│ + * │-------- Ingest Range --------│ + * + * We will logical split the segment to form a perfect matching segment: + * │--------│------ Segment ---------------│ + * │-------- Ingest Range --------│ + */ + const auto [left, right] = segmentSplit(dm_context, segment, SegmentSplitReason::ForIngest, ingest_range.start, SegmentSplitMode::Logical); + if (left == nullptr || right == nullptr) + { + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + } + return false; + } + else + { + /* + * Example: + * │--------------- Segment ---------------│ + * │-------- Ingest Range --------│ + * + * We invoke a logical split first: + * │---│----------- Segment ---------------│ + * │-------- Ingest Range --------│ + */ + const auto [left, right] = segmentSplit(dm_context, segment, SegmentSplitReason::ForIngest, ingest_range.start, SegmentSplitMode::Logical); + if (left == nullptr || right == nullptr) + { + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + } + return false; + } +} + +void DeltaMergeStore::ingestSegmentsFromCheckpointInfo( + const DMContextPtr & dm_context, + const DM::RowKeyRange & range, + CheckpointInfoPtr checkpoint_info) +{ + if (unlikely(shutdown_called.load(std::memory_order_relaxed))) + { + const auto msg = fmt::format("Try to ingest files into a shutdown table, store={}", log->identifier()); + LOG_WARNING(log, "{}", msg); + throw Exception(msg); + } + LOG_INFO(log, "Ingest checkpoint from store {}", checkpoint_info->remote_store_id); + + auto segment_meta_infos = Segment::readAllSegmentsMetaInfoInRange(*dm_context, checkpoint_info->remote_store_id, physical_table_id, range, checkpoint_info->temp_ps); + LOG_INFO(log, "Ingest checkpoint segments num {}", segment_meta_infos.size()); + WriteBatches wbs{*dm_context->storage_pool}; + auto restored_segments = Segment::createTargetSegmentsFromCheckpoint( // + log, + *dm_context, + checkpoint_info->remote_store_id, + physical_table_id, + segment_meta_infos, + range, + checkpoint_info->temp_ps, + wbs); + + if (restored_segments.empty()) + { + LOG_DEBUG(log, "No segments to ingest."); + return; + } + wbs.writeLogAndData(); + + auto updated_segments = ingestSegmentsUsingSplit(dm_context, range, restored_segments); + LOG_INFO(log, "Ingest checkpoint from store {} done", checkpoint_info->remote_store_id); + + for (auto & segment : restored_segments) + { + auto delta = segment->getDelta(); + auto stable = segment->getStable(); + delta->recordRemoveColumnFilesPages(wbs); + stable->recordRemovePacksPages(wbs); + wbs.writeRemoves(); + } + + for (auto & segment : updated_segments) + checkSegmentUpdate(dm_context, segment, ThreadType::Write); +} + } // namespace DM } // namespace DB diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore_InternalSegment.cpp b/dbms/src/Storages/DeltaMerge/DeltaMergeStore_InternalSegment.cpp index b7f81100ea7..f1f39ec6c72 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore_InternalSegment.cpp +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore_InternalSegment.cpp @@ -587,6 +587,49 @@ SegmentPtr DeltaMergeStore::segmentIngestData( return new_segment; } +SegmentPtr DeltaMergeStore::segmentDangerouslyReplaceDataFromCheckpoint( + DMContext & dm_context, + const SegmentPtr & segment, + const DMFilePtr & data_file, + const ColumnFilePersisteds & column_file_persisteds) +{ + LOG_INFO(log, "ReplaceData - Begin, segment={} data_file={} column_files_num={}", segment->info(), data_file->path(), column_file_persisteds.size()); + + WriteBatches wbs(*storage_pool, dm_context.getWriteLimiter()); + + SegmentPtr new_segment; + { + std::unique_lock lock(read_write_mutex); + if (!isSegmentValid(lock, segment)) + { + LOG_DEBUG(log, "ReplaceData - Give up segment replace data because segment not valid, segment={} data_file={}", segment->simpleInfo(), data_file->path()); + return {}; + } + + auto segment_lock = segment->mustGetUpdateLock(); + new_segment = segment->dangerouslyReplaceDataFromCheckpoint(segment_lock, dm_context, data_file, wbs, column_file_persisteds); + + RUNTIME_CHECK(compare(segment->getRowKeyRange().getEnd(), new_segment->getRowKeyRange().getEnd()) == 0, segment->info(), new_segment->info()); + RUNTIME_CHECK(segment->segmentId() == new_segment->segmentId(), segment->info(), new_segment->info()); + + wbs.writeLogAndData(); + wbs.writeMeta(); + + segment->abandon(dm_context); + segments[segment->getRowKeyRange().getEnd()] = new_segment; + id_to_segment[segment->segmentId()] = new_segment; + + LOG_INFO(log, "ReplaceData - Finish, old_segment={} new_segment={}", segment->info(), new_segment->info()); + } + + wbs.writeRemoves(); + + if constexpr (DM_RUN_CHECK) + check(dm_context.db_context); + + return new_segment; +} + bool DeltaMergeStore::doIsSegmentValid(const SegmentPtr & segment) { if (segment->hasAbandoned()) diff --git a/dbms/src/Storages/DeltaMerge/File/DMFile.cpp b/dbms/src/Storages/DeltaMerge/File/DMFile.cpp index e165889e859..06a599300c0 100644 --- a/dbms/src/Storages/DeltaMerge/File/DMFile.cpp +++ b/dbms/src/Storages/DeltaMerge/File/DMFile.cpp @@ -49,6 +49,7 @@ namespace FailPoints { extern const char exception_before_dmfile_remove_encryption[]; extern const char exception_before_dmfile_remove_from_disk[]; +extern const char force_use_dmfile_format_v3[]; } // namespace FailPoints namespace DM @@ -110,6 +111,11 @@ String DMFile::ngcPath() const DMFilePtr DMFile::create(UInt64 file_id, const String & parent_path, DMConfigurationOpt configuration, DMFileFormat::Version version) { + fiu_do_on(FailPoints::force_use_dmfile_format_v3, { + // some unit test we need mock upload DMFile to S3, which only support DMFileFormat::V3 + version = DMFileFormat::V3; + LOG_WARNING(Logger::get(), "!!!force use DMFileFormat::V3!!!"); + }); // On create, ref_id is the same as file_id. DMFilePtr new_dmfile(new DMFile(file_id, file_id, diff --git a/dbms/src/Storages/DeltaMerge/File/DMFile.h b/dbms/src/Storages/DeltaMerge/File/DMFile.h index 5f5e28b49cf..9bc8b72d4b2 100644 --- a/dbms/src/Storages/DeltaMerge/File/DMFile.h +++ b/dbms/src/Storages/DeltaMerge/File/DMFile.h @@ -475,6 +475,7 @@ class DMFile : private boost::noncopyable DMFileFormat::Version version; friend class DMFileWriter; + friend class DMFileWriterRemote; friend class DMFileReader; friend class DMFilePackFilter; friend class DMFileBlockInputStreamBuilder; diff --git a/dbms/src/Storages/DeltaMerge/File/DMFileBlockOutputStream.cpp b/dbms/src/Storages/DeltaMerge/File/DMFileBlockOutputStream.cpp index 0dffeb280c6..4c15c44418e 100644 --- a/dbms/src/Storages/DeltaMerge/File/DMFileBlockOutputStream.cpp +++ b/dbms/src/Storages/DeltaMerge/File/DMFileBlockOutputStream.cpp @@ -17,7 +17,6 @@ namespace DB::DM { - DMFileBlockOutputStream::DMFileBlockOutputStream(const Context & context, const DMFilePtr & dmfile, const ColumnDefines & write_columns) diff --git a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStore.h b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStore.h index 6e2a30dbe86..0e31960c5b0 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStore.h +++ b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStore.h @@ -38,10 +38,12 @@ class IPreparedDMFileToken : boost::noncopyable // These should be the required information for any kind of DataStore. const FileProviderPtr file_provider; const S3::DMFileOID oid; + UInt64 page_id; - IPreparedDMFileToken(const FileProviderPtr & file_provider_, const S3::DMFileOID & oid_) + IPreparedDMFileToken(const FileProviderPtr & file_provider_, const S3::DMFileOID & oid_, UInt64 page_id_) : file_provider(file_provider_) , oid(oid_) + , page_id(page_id_ == 0 ? oid.file_id : page_id_) {} }; @@ -56,8 +58,6 @@ class IDataStore : boost::noncopyable */ virtual void putDMFile(DMFilePtr local_dm_file, const S3::DMFileOID & oid, bool remove_local) = 0; - virtual void copyDMFileMetaToLocalPath(const S3::DMFileOID & remote_oid, const String & local_path) = 0; - /** * Blocks until a DMFile in the remote data store is successfully prepared in a local cache. * If the DMFile exists in the local cache, it will not be prepared again. @@ -65,9 +65,9 @@ class IDataStore : boost::noncopyable * Returns a "token", which can be used to rebuild the `DMFile` object. * The DMFile in the local cache may be invalidated if you deconstructs the token. * - * Should be used by a read node. + * When page_id is 0, will use its file_id as page_id.(Used by WN, RN can just use default value) */ - virtual IPreparedDMFileTokenPtr prepareDMFile(const S3::DMFileOID & oid) = 0; + virtual IPreparedDMFileTokenPtr prepareDMFile(const S3::DMFileOID & oid, UInt64 page_id = 0) = 0; /** * Blocks until all checkpoint files are successfully put in the remote data store. diff --git a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp index 05115f56223..2e141d08186 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp +++ b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp @@ -73,14 +73,6 @@ void DataStoreS3::putDMFile(DMFilePtr local_dmfile, const S3::DMFileOID & oid, b LOG_INFO(log, "Upload DMFile finished, key={}, cost={}ms", remote_dir, sw.elapsedMilliseconds()); } -void DataStoreS3::copyDMFileMetaToLocalPath(const S3::DMFileOID & remote_oid, const String & local_dir) -{ - Stopwatch sw; - std::vector target_fnames = {DMFile::metav2FileName(), IDataType::getFileNameForStream(DB::toString(-1), {}) + ".idx"}; - copyToLocal(remote_oid, target_fnames, local_dir); - LOG_DEBUG(log, "copyDMFileMetaToLocalPath finished. Local_dir={} cost={}ms", local_dir, sw.elapsedMilliseconds()); -} - bool DataStoreS3::putCheckpointFiles(const PS::V3::LocalCheckpointFiles & local_files, StoreID store_id, UInt64 upload_seq) { auto s3_client = S3::ClientFactory::instance().sharedClient(); @@ -141,9 +133,10 @@ void DataStoreS3::copyToLocal(const S3::DMFileOID & remote_oid, const std::vecto } } -IPreparedDMFileTokenPtr DataStoreS3::prepareDMFile(const S3::DMFileOID & oid) + +IPreparedDMFileTokenPtr DataStoreS3::prepareDMFile(const S3::DMFileOID & oid, UInt64 page_id) { - return std::make_shared(file_provider, oid); + return std::make_shared(file_provider, oid, page_id); } DMFilePtr S3PreparedDMFileToken::restore(DMFile::ReadMetaMode read_mode) @@ -151,7 +144,7 @@ DMFilePtr S3PreparedDMFileToken::restore(DMFile::ReadMetaMode read_mode) return DMFile::restore( file_provider, oid.file_id, - oid.file_id, + page_id, S3::S3Filename::fromTableID(oid.store_id, oid.table_id).toFullKeyWithPrefix(), read_mode); } diff --git a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.h b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.h index e61a03eccd7..00288f227d9 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.h +++ b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.h @@ -36,8 +36,6 @@ class DataStoreS3 final : public IDataStore */ void putDMFile(DMFilePtr local_dmfile, const S3::DMFileOID & oid, bool remove_local) override; - void copyDMFileMetaToLocalPath(const S3::DMFileOID & remote_oid, const String & local_dir) override; - /** * Blocks until a DMFile in the remote data store is successfully prepared in a local cache. * If the DMFile exists in the local cache, it will not be prepared again. @@ -47,7 +45,7 @@ class DataStoreS3 final : public IDataStore * * Should be used by a read node. */ - IPreparedDMFileTokenPtr prepareDMFile(const S3::DMFileOID & oid) override; + IPreparedDMFileTokenPtr prepareDMFile(const S3::DMFileOID & oid, UInt64 page_id) override; bool putCheckpointFiles(const PS::V3::LocalCheckpointFiles & local_files, StoreID store_id, UInt64 upload_seq) override; @@ -66,8 +64,8 @@ class DataStoreS3 final : public IDataStore class S3PreparedDMFileToken : public IPreparedDMFileToken { public: - S3PreparedDMFileToken(const FileProviderPtr & file_provider_, const S3::DMFileOID & oid_) - : IPreparedDMFileToken::IPreparedDMFileToken(file_provider_, oid_) + S3PreparedDMFileToken(const FileProviderPtr & file_provider_, const S3::DMFileOID & oid_, UInt64 page_id) + : IPreparedDMFileToken::IPreparedDMFileToken(file_provider_, oid_, page_id) {} ~S3PreparedDMFileToken() override = default; diff --git a/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.cpp b/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.cpp index 7f0f22a2032..ee9bce370c6 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.cpp +++ b/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.cpp @@ -17,7 +17,6 @@ namespace DB::DM::Remote { - WNDisaggSnapshotManager::WNDisaggSnapshotManager(BackgroundProcessingPool & bg_pool) : pool(bg_pool) , log(Logger::get()) diff --git a/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.h b/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.h index b8a3f3bb73d..f6be59f08e0 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.h +++ b/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.h @@ -31,7 +31,6 @@ namespace DB::DM::Remote { - /** * WNDisaggSnapshotManager holds all snapshots for disaggregated read tasks * in the write node. It's a single instance for each TiFlash node. diff --git a/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager_fwd.h b/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager_fwd.h index bf78c0f59a4..54597a32a6c 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager_fwd.h +++ b/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager_fwd.h @@ -18,7 +18,6 @@ namespace DB::DM::Remote { - class WNDisaggSnapshotManager; using WNDisaggSnapshotManagerPtr = std::shared_ptr; diff --git a/dbms/src/Storages/DeltaMerge/Segment.cpp b/dbms/src/Storages/DeltaMerge/Segment.cpp index 4f236fd293c..96c72404531 100644 --- a/dbms/src/Storages/DeltaMerge/Segment.cpp +++ b/dbms/src/Storages/DeltaMerge/Segment.cpp @@ -41,9 +41,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -189,6 +191,7 @@ StableValueSpacePtr createNewStable( // if (auto data_store = context.db_context.getSharedContextDisagg()->remote_data_store; !data_store) { wbs.data.putExternal(dtfile_id, 0); + delegator.addDTFile(dtfile_id, dtfile->getBytesOnDisk(), store_path); } else { @@ -202,7 +205,6 @@ StableValueSpacePtr createNewStable( // }; wbs.data.putRemoteExternal(dtfile_id, loc); } - delegator.addDTFile(dtfile_id, dtfile->getBytesOnDisk(), store_path); return stable; } @@ -283,53 +285,141 @@ SegmentPtr Segment::newSegment( // context.storage_pool->newMetaPageId()); } -SegmentPtr Segment::restoreSegment( // - const LoggerPtr & parent_log, - DMContext & context, - PageIdU64 segment_id) +inline void readSegmentMetaInfo(ReadBuffer & buf, Segment::SegmentMetaInfo & segment_info) { - Page page = context.storage_pool->metaReader()->read(segment_id); // not limit restore - - ReadBufferFromMemory buf(page.data.begin(), page.data.size()); - SegmentFormat::Version version; - - readIntBinary(version, buf); - UInt64 epoch; - RowKeyRange rowkey_range; - PageIdU64 next_segment_id, delta_id, stable_id; - - readIntBinary(epoch, buf); + readIntBinary(segment_info.version, buf); + readIntBinary(segment_info.epoch, buf); - switch (version) + switch (segment_info.version) { case SegmentFormat::V1: { HandleRange range; readIntBinary(range.start, buf); readIntBinary(range.end, buf); - rowkey_range = RowKeyRange::fromHandleRange(range); + segment_info.range = RowKeyRange::fromHandleRange(range); break; } case SegmentFormat::V2: { - rowkey_range = RowKeyRange::deserialize(buf); + segment_info.range = RowKeyRange::deserialize(buf); break; } default: - throw Exception(fmt::format("Illegal version: {}", version), ErrorCodes::LOGICAL_ERROR); + throw Exception(fmt::format("Illegal version: {}", segment_info.version), ErrorCodes::LOGICAL_ERROR); } - readIntBinary(next_segment_id, buf); - readIntBinary(delta_id, buf); - readIntBinary(stable_id, buf); + readIntBinary(segment_info.next_segment_id, buf); + readIntBinary(segment_info.delta_id, buf); + readIntBinary(segment_info.stable_id, buf); +} + +SegmentPtr Segment::restoreSegment( // + const LoggerPtr & parent_log, + DMContext & context, + PageIdU64 segment_id) +{ + Page page = context.storage_pool->metaReader()->read(segment_id); // not limit restore + + ReadBufferFromMemory buf(page.data.begin(), page.data.size()); + Segment::SegmentMetaInfo segment_info; + readSegmentMetaInfo(buf, segment_info); - auto delta = DeltaValueSpace::restore(context, rowkey_range, delta_id); - auto stable = StableValueSpace::restore(context, stable_id); - auto segment = std::make_shared(parent_log, epoch, rowkey_range, segment_id, next_segment_id, delta, stable); + auto delta = DeltaValueSpace::restore(context, segment_info.range, segment_info.delta_id); + auto stable = StableValueSpace::restore(context, segment_info.stable_id); + auto segment = std::make_shared(parent_log, segment_info.epoch, segment_info.range, segment_id, segment_info.next_segment_id, delta, stable); return segment; } +Segment::SegmentMetaInfos Segment::readAllSegmentsMetaInfoInRange( // + DMContext & context, + UInt64 remote_store_id, + NamespaceId ns_id, + const RowKeyRange & target_range, + UniversalPageStoragePtr temp_ps) +{ + PageIdU64 current_segment_id = 1; // DELTA_MERGE_FIRST_SEGMENT_ID + SegmentMetaInfos segment_infos; + auto fap_context = context.db_context.getSharedContextDisagg()->fap_context; + TableIdentifier identifier{ + .key_space_id = 0, + .store_id = remote_store_id, + .table_id = ns_id, + }; + auto first_segment_id = fap_context->getSegmentIdContainingKey(identifier, target_range.getStart().toRowKeyValue()); + if (first_segment_id != 0) + { + bool hit = false; + auto target_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Meta, ns_id), first_segment_id); + auto page = temp_ps->read(target_id, /*read_limiter*/ nullptr, {}, /*throw_on_not_exist*/ false); + if (page.isValid()) + { + Segment::SegmentMetaInfo segment_info; + segment_info.segment_id = first_segment_id; + ReadBufferFromMemory buf(page.data.begin(), page.data.size()); + readSegmentMetaInfo(buf, segment_info); + if (segment_info.range.check(target_range.getStart())) + { + segment_infos.push_back(segment_info); + current_segment_id = segment_info.next_segment_id; + hit = true; + } + } + if (!hit) + { + fap_context->invalidateCache(identifier); + } + } + std::vector> end_key_and_segment_ids; + LOG_DEBUG(Logger::get(), "Read segment meta info from segment {}", current_segment_id); + while (current_segment_id != 0) + { + Segment::SegmentMetaInfo segment_info; + auto target_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Meta, ns_id), current_segment_id); + auto page = temp_ps->read(target_id); + segment_info.segment_id = current_segment_id; + ReadBufferFromMemory buf(page.data.begin(), page.data.size()); + readSegmentMetaInfo(buf, segment_info); + end_key_and_segment_ids.emplace_back(segment_info.range.getEnd().toRowKeyValue(), segment_info.segment_id); + current_segment_id = segment_info.next_segment_id; + if (!(segment_info.range.shrink(target_range).none())) + { + segment_infos.emplace_back(segment_info); + } + if (segment_info.range.end.value->compare(*target_range.end.value) >= 0) + { + break; + } + } + fap_context->insertSegmentEndKeyInfoToCache(identifier, end_key_and_segment_ids); + return segment_infos; +} + +Segments Segment::createTargetSegmentsFromCheckpoint( // + const LoggerPtr & parent_log, + DMContext & context, + UInt64 remote_store_id, + NamespaceId ns_id, + const SegmentMetaInfos & meta_infos, + const RowKeyRange & range, + UniversalPageStoragePtr temp_ps, + WriteBatches & wbs) +{ + UNUSED(remote_store_id); + Segments segments; + for (const auto & segment_info : meta_infos) + { + LOG_DEBUG(parent_log, "Create segment begin. Delta id {} stable id {} range {} epoch {} next_segment_id {}", segment_info.delta_id, segment_info.stable_id, segment_info.range.toDebugString(), segment_info.epoch, segment_info.next_segment_id); + auto stable = StableValueSpace::createFromCheckpoint(context, temp_ps, ns_id, segment_info.stable_id, wbs); + auto delta = DeltaValueSpace::createFromCheckpoint(context, temp_ps, segment_info.range, ns_id, segment_info.delta_id, wbs); + auto segment = std::make_shared(Logger::get("Checkpoint"), segment_info.epoch, segment_info.range.shrink(range), segment_info.segment_id, segment_info.next_segment_id, delta, stable); + segments.push_back(segment); + LOG_DEBUG(parent_log, "Create segment end. Delta id {} stable id {} range {} epoch {} next_segment_id {}", segment_info.delta_id, segment_info.stable_id, segment_info.range.toDebugString(), segment_info.epoch, segment_info.next_segment_id); + } + return segments; +} + void Segment::serialize(WriteBatchWrapper & wb) { MemoryWriteBuffer buf(0, SEGMENT_BUFFER_SIZE); @@ -1059,6 +1149,97 @@ SegmentPtr Segment::replaceData(const Segment::Lock & lock, // return new_me; } +SegmentPtr Segment::dangerouslyReplaceDataFromCheckpoint(const Segment::Lock &, // + DMContext & dm_context, + const DMFilePtr & data_file, + WriteBatches & wbs, + const ColumnFilePersisteds & column_file_persisteds) const +{ + LOG_DEBUG(log, "ReplaceData - Begin, data_file={}, column_files_num={}", data_file->path(), column_file_persisteds.size()); + + auto & storage_pool = dm_context.storage_pool; + auto delegate = dm_context.path_pool->getStableDiskDelegator(); + + // Always create a ref to the file to allow `data_file` being shared. + auto new_page_id = storage_pool->newDataPageIdForDTFile(delegate, __PRETTY_FUNCTION__); + auto ref_file = DMFile::restore( + dm_context.db_context.getFileProvider(), + data_file->fileId(), + new_page_id, + data_file->parentPath(), + DMFile::ReadMetaMode::all()); + wbs.data.putRefPage(new_page_id, data_file->pageId()); + + auto new_stable = std::make_shared(stable->getId()); + new_stable->setFiles({ref_file}, rowkey_range, &dm_context); + new_stable->saveMeta(wbs.meta); + + ColumnFilePersisteds new_column_file_persisteds; + for (const auto & column_file : column_file_persisteds) + { + if (auto * t = column_file->tryToTinyFile(); t) + { + // This column file may be ingested into multiple segments, so we cannot reuse its page id here. + auto new_cf_id = storage_pool->newLogPageId(); + wbs.log.putRefPage(new_cf_id, t->getDataPageId()); + new_column_file_persisteds.push_back(t->cloneWith(new_cf_id)); + } + else if (auto * d = column_file->tryToDeleteRange(); d) + { + new_column_file_persisteds.push_back(column_file); + } + else if (auto * b = column_file->tryToBigFile(); b) + { + auto new_file_id = storage_pool->newDataPageIdForDTFile(delegate, __PRETTY_FUNCTION__); + auto old_page_id = b->getDataPageId(); + wbs.data.putRefPage(new_file_id, old_page_id); + auto old_file_id = b->getFile()->fileId(); + String file_parent_path; + if (dm_context.db_context.getSharedContextDisagg()->remote_data_store) + { + auto wn_ps = dm_context.db_context.getWriteNodePageStorage(); + auto full_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Data, dm_context.storage_pool->getNamespaceId()), old_page_id); + auto remote_data_location = wn_ps->getCheckpointLocation(full_page_id); + const auto & lock_key_view = S3::S3FilenameView::fromKey(*(remote_data_location->data_file_id)); + file_parent_path = S3::S3Filename::fromTableID(lock_key_view.store_id, dm_context.storage_pool->getNamespaceId()).toFullKeyWithPrefix(); + } + else + { + file_parent_path = delegate.getDTFilePath(old_file_id); + } + auto new_dmfile = DMFile::restore(dm_context.db_context.getFileProvider(), old_file_id, new_file_id, file_parent_path, DMFile::ReadMetaMode::all()); + auto new_column_file = b->cloneWith(dm_context, new_dmfile, rowkey_range); + new_column_file_persisteds.push_back(new_column_file); + } + else + { + RUNTIME_CHECK(false); + } + } + + auto new_delta = std::make_shared( + delta->getId(), + new_column_file_persisteds); + new_delta->saveMeta(wbs); + + auto new_me = std::make_shared( // + parent_log, + epoch + 1, + rowkey_range, + segment_id, + next_segment_id, + new_delta, + new_stable); + new_me->serialize(wbs.meta); + + delta->recordRemoveColumnFilesPages(wbs); + stable->recordRemovePacksPages(wbs); + + LOG_DEBUG(log, "ReplaceData - Finish, old_me={} new_me={}", info(), new_me->info()); + + return new_me; +} + SegmentPair Segment::split(DMContext & dm_context, const ColumnDefinesPtr & schema_snap, std::optional opt_split_at, SplitMode opt_split_mode) const { WriteBatches wbs(*dm_context.storage_pool, dm_context.getWriteLimiter()); diff --git a/dbms/src/Storages/DeltaMerge/Segment.h b/dbms/src/Storages/DeltaMerge/Segment.h index 91f92d14c49..c420368d1bb 100644 --- a/dbms/src/Storages/DeltaMerge/Segment.h +++ b/dbms/src/Storages/DeltaMerge/Segment.h @@ -142,6 +142,37 @@ class Segment static SegmentPtr restoreSegment(const LoggerPtr & parent_log, DMContext & context, PageIdU64 segment_id); + struct SegmentMetaInfo + { + SegmentFormat::Version version; + UInt64 epoch; + RowKeyRange range; + PageIdU64 segment_id; + PageIdU64 next_segment_id; + PageIdU64 delta_id; + PageIdU64 stable_id; + }; + + using SegmentMetaInfos = std::vector; + static SegmentMetaInfos readAllSegmentsMetaInfoInRange( // + DMContext & context, + UInt64 remote_store_id, + NamespaceId ns_id, + const RowKeyRange & target_range, + UniversalPageStoragePtr temp_ps); + + // Create a list of temp segments from checkpoint. + // The data of these temp segments will be included in `wbs`. + static Segments createTargetSegmentsFromCheckpoint( // + const LoggerPtr & parent_log, + DMContext & context, + UInt64 remote_store_id, + NamespaceId ns_id, + const SegmentMetaInfos & meta_infos, + const RowKeyRange & range, + UniversalPageStoragePtr temp_ps, + WriteBatches & wbs); + void serialize(WriteBatchWrapper & wb); /// Attach a new ColumnFile into the Segment. The ColumnFile will be added to MemFileSet and flushed to disk later. @@ -437,6 +468,8 @@ class Segment */ [[nodiscard]] SegmentPtr replaceData(const Lock &, DMContext & dm_context, const DMFilePtr & data_file, SegmentSnapshotPtr segment_snap_opt = nullptr) const; + [[nodiscard]] SegmentPtr dangerouslyReplaceDataFromCheckpoint(const Lock &, DMContext & dm_context, const DMFilePtr & data_file, WriteBatches & wbs, const ColumnFilePersisteds & column_file_persisteds) const; + [[nodiscard]] SegmentPtr dropNextSegment(WriteBatches & wbs, const RowKeyRange & next_segment_range); /** diff --git a/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp b/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp index 94b2020eef1..b3464e2621b 100644 --- a/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp +++ b/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,7 @@ #include #include #include + namespace DB { namespace ErrorCodes @@ -104,31 +106,95 @@ StableValueSpacePtr StableValueSpace::restore(DMContext & context, PageIdU64 id) readIntBinary(valid_bytes, buf); readIntBinary(size, buf); UInt64 page_id; - bool restore_from_s3 = context.db_context.getSharedContextDisagg()->remote_data_store != nullptr; + auto remote_data_store = context.db_context.getSharedContextDisagg()->remote_data_store; for (size_t i = 0; i < size; ++i) { readIntBinary(page_id, buf); - auto file_id = context.storage_pool->dataReader()->getNormalPageId(page_id); - if (restore_from_s3) + + DMFilePtr dmfile; + if (remote_data_store) { auto wn_ps = context.db_context.getWriteNodePageStorage(); auto full_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Data, context.storage_pool->getNamespaceId()), page_id); auto remote_data_location = wn_ps->getCheckpointLocation(full_page_id); const auto & lock_key_view = S3::S3FilenameView::fromKey(*(remote_data_location->data_file_id)); - auto file_parent_path = S3::S3Filename::fromTableID(lock_key_view.store_id, context.storage_pool->getNamespaceId()).toFullKeyWithPrefix(); - auto dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, page_id, file_parent_path, DMFile::ReadMetaMode::all()); - stable->files.push_back(dmfile); + auto dtfile_key = lock_key_view.asDataFile(); + auto file_oid = dtfile_key.getDMFileOID(); + RUNTIME_CHECK(file_oid.table_id == context.physical_table_id); + auto prepared = remote_data_store->prepareDMFile(file_oid, page_id); + dmfile = prepared->restore(DMFile::ReadMetaMode::all()); } else { auto path_delegate = context.path_pool->getStableDiskDelegator(); auto file_parent_path = path_delegate.getDTFilePath(file_id); - auto dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, page_id, file_parent_path, DMFile::ReadMetaMode::all()); + dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, page_id, file_parent_path, DMFile::ReadMetaMode::all()); auto res = path_delegate.updateDTFileSize(file_id, dmfile->getBytesOnDisk()); RUNTIME_CHECK_MSG(res, "update dt file size failed, path={}", dmfile->path()); - stable->files.push_back(dmfile); } + stable->files.push_back(dmfile); + } + + stable->valid_rows = valid_rows; + stable->valid_bytes = valid_bytes; + + return stable; +} + +StableValueSpacePtr StableValueSpace::createFromCheckpoint( // + DMContext & context, + UniversalPageStoragePtr temp_ps, + TableID ns_id, + PageIdU64 stable_id, + WriteBatches & wbs) +{ + auto stable = std::make_shared(stable_id); + + auto stable_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Meta, ns_id), stable_id); + auto page = temp_ps->read(stable_page_id); + ReadBufferFromMemory buf(page.data.begin(), page.data.size()); + + // read stable meta info + UInt64 version, valid_rows, valid_bytes, size; + { + readIntBinary(version, buf); + if (version != StableFormat::V1) + throw Exception("Unexpected version: " + DB::toString(version)); + + readIntBinary(valid_rows, buf); + readIntBinary(valid_bytes, buf); + readIntBinary(size, buf); + } + + for (size_t i = 0; i < size; ++i) + { + UInt64 page_id; + readIntBinary(page_id, buf); + auto remote_page_id = UniversalPageIdFormat::toFullPageId(UniversalPageIdFormat::toFullPrefix(StorageType::Data, ns_id), page_id); + auto remote_file_id = temp_ps->getNormalPageId(remote_page_id); + auto file_id = UniversalPageIdFormat::getU64ID(remote_file_id); + auto remote_data_location = temp_ps->getCheckpointLocation(remote_page_id); + const auto & lock_key_view = S3::S3FilenameView::fromKey(*(remote_data_location->data_file_id)); + S3::DMFileOID file_oid{ + .store_id = lock_key_view.store_id, + .table_id = ns_id, + .file_id = file_id}; + RUNTIME_CHECK(lock_key_view.asDataFile().toFullKey() == S3::S3Filename::fromDMFileOID(file_oid).toFullKey()); + auto data_key = S3::S3Filename::fromDMFileOID(file_oid).toFullKey(); + auto delegator = context.path_pool->getStableDiskDelegator(); + auto new_local_page_id = context.storage_pool->newDataPageIdForDTFile(delegator, __PRETTY_FUNCTION__); + PS::V3::CheckpointLocation loc{ + .data_file_id = std::make_shared(data_key), + .offset_in_file = 0, + .size_in_file = 0, + }; + wbs.data.putRemoteExternal(new_local_page_id, loc); + + auto parent_path = S3::S3Filename::fromTableID(lock_key_view.store_id, ns_id).toFullKeyWithPrefix(); + auto new_dmfile = DMFile::restore(context.db_context.getFileProvider(), file_id, new_local_page_id, parent_path, DMFile::ReadMetaMode::all()); + wbs.writeLogAndData(); + stable->files.push_back(new_dmfile); } stable->valid_rows = valid_rows; diff --git a/dbms/src/Storages/DeltaMerge/StableValueSpace.h b/dbms/src/Storages/DeltaMerge/StableValueSpace.h index ba0bd2ae411..8eb0ef37cff 100644 --- a/dbms/src/Storages/DeltaMerge/StableValueSpace.h +++ b/dbms/src/Storages/DeltaMerge/StableValueSpace.h @@ -46,6 +46,13 @@ class StableValueSpace : public std::enable_shared_from_this static StableValueSpacePtr restore(DMContext & context, PageIdU64 id); + static StableValueSpacePtr createFromCheckpoint( // + DMContext & context, + UniversalPageStoragePtr temp_ps, + TableID ns_id, + PageIdU64 stable_id, + WriteBatches & wbs); + /** * Resets the logger by using the one from the segment. * Segment_log is not available when constructing, because usually diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_merge_store_fast_add_peer.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_merge_store_fast_add_peer.cpp new file mode 100644 index 00000000000..fc2c3648a7c --- /dev/null +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_merge_store_fast_add_peer.cpp @@ -0,0 +1,392 @@ +// Copyright 2022 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DataStreams/OneBlockInputStream.h" + + +namespace DB +{ +namespace FailPoints +{ +extern const char force_use_dmfile_format_v3[]; +} // namespace FailPoints +namespace DM +{ +extern DMFilePtr writeIntoNewDMFile(DMContext & dm_context, + const ColumnDefinesPtr & schema_snap, + const BlockInputStreamPtr & input_stream, + UInt64 file_id, + const String & parent_path); +namespace tests +{ +// Simple test suit for DeltaMergeStoreTestFastAddPeer. +class DeltaMergeStoreTestFastAddPeer : public DB::base::TiFlashStorageTestBasic +{ +public: + void SetUp() override + { + FailPointHelper::enableFailPoint(FailPoints::force_use_dmfile_format_v3); + ASSERT_TRUE(createBucketIfNotExist()); + TiFlashStorageTestBasic::SetUp(); + auto & global_context = TiFlashTestEnv::getGlobalContext(); + if (global_context.getSharedContextDisagg()->remote_data_store == nullptr) + { + already_initialize_data_store = false; + global_context.getSharedContextDisagg()->initRemoteDataStore(global_context.getFileProvider(), /*s3_enabled*/ true); + ASSERT_TRUE(global_context.getSharedContextDisagg()->remote_data_store != nullptr); + } + else + { + already_initialize_data_store = true; + } + if (global_context.getWriteNodePageStorage() == nullptr) + { + already_initialize_write_ps = false; + orig_mode = global_context.getPageStorageRunMode(); + global_context.setPageStorageRunMode(PageStorageRunMode::UNI_PS); + global_context.tryReleaseWriteNodePageStorageForTest(); + global_context.initializeWriteNodePageStorageIfNeed(global_context.getPathPool()); + } + else + { + already_initialize_write_ps = true; + } + auto kvstore = db_context->getTMTContext().getKVStore(); + { + auto meta_store = metapb::Store{}; + meta_store.set_id(store_id); + kvstore->setStore(meta_store); + } + global_context.getSharedContextDisagg()->initFastAddPeerContext(); + } + + void TearDown() override + { + FailPointHelper::disableFailPoint(FailPoints::force_use_dmfile_format_v3); + auto & global_context = TiFlashTestEnv::getGlobalContext(); + if (!already_initialize_data_store) + { + global_context.getSharedContextDisagg()->remote_data_store = nullptr; + } + if (!already_initialize_write_ps) + { + global_context.setPageStorageRunMode(orig_mode); + } + } + + DeltaMergeStorePtr + reload(const ColumnDefinesPtr & pre_define_columns = {}, bool is_common_handle = false, size_t rowkey_column_size = 1) + { + TiFlashStorageTestBasic::reload(); + if (auto ps = DB::tests::TiFlashTestEnv::getGlobalContext().getWriteNodePageStorage(); ps) + { + auto mock_s3lock_client = std::make_shared(DB::S3::ClientFactory::instance().sharedTiFlashClient()); + ps->initLocksLocalManager(store_id, mock_s3lock_client); + } + ColumnDefinesPtr cols; + if (!pre_define_columns) + cols = DMTestEnv::getDefaultColumns(is_common_handle ? DMTestEnv::PkType::CommonHandle : DMTestEnv::PkType::HiddenTiDBRowID); + else + cols = pre_define_columns; + + ColumnDefine handle_column_define = (*cols)[0]; + + DeltaMergeStorePtr s = std::make_shared(*db_context, + false, + "test", + "t_100", + 100, + true, + *cols, + handle_column_define, + is_common_handle, + rowkey_column_size, + DeltaMergeStore::Settings()); + return s; + } + +protected: + std::pair> genDMFile(DMContext & context, const Block & block) + { + auto input_stream = std::make_shared(block); + auto [store_path, file_id] = store->preAllocateIngestFile(); + + auto dmfile = writeIntoNewDMFile( + context, + std::make_shared(store->getTableColumns()), + input_stream, + file_id, + store_path); + + store->preIngestFile(store_path, file_id, dmfile->getBytesOnDisk()); + + const auto & pk_column = block.getByPosition(0).column; + auto min_pk = pk_column->getInt(0); + auto max_pk = pk_column->getInt(block.rows() - 1); + HandleRange range(min_pk, max_pk + 1); + auto handle_range = RowKeyRange::fromHandleRange(range); + auto external_file = ExternalDTFileInfo{.id = file_id, .range = handle_range}; + return {handle_range, {external_file}}; // There are some duplicated info. This is to minimize the change to our test code. + } + + bool createBucketIfNotExist() + { + auto s3_client = S3::ClientFactory::instance().sharedClient(); + auto bucket = S3::ClientFactory::instance().bucket(); + Aws::S3::Model::CreateBucketRequest request; + request.SetBucket(bucket); + auto outcome = s3_client->CreateBucket(request); + if (outcome.IsSuccess()) + { + LOG_DEBUG(Logger::get(), "Created bucket {}", bucket); + } + else if (outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou") + { + LOG_DEBUG(Logger::get(), "Bucket {} already exist", bucket); + } + else + { + const auto & err = outcome.GetError(); + LOG_ERROR(Logger::get(), "CreateBucket: {}:{}", err.GetExceptionName(), err.GetMessage()); + } + return outcome.IsSuccess() || outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou"; + } + + void dumpCheckpoint() + { + auto temp_dir = getTemporaryPath() + "/"; + auto page_storage = db_context->getWriteNodePageStorage(); + auto wi = PS::V3::CheckpointProto::WriterInfo(); + { + wi.set_store_id(store_id); + } + + + auto remote_store = db_context->getSharedContextDisagg()->remote_data_store; + assert(remote_store != nullptr); + UniversalPageStorage::DumpCheckpointOptions opts{ + .data_file_id_pattern = S3::S3Filename::newCheckpointDataNameTemplate(store_id, upload_sequence), + .data_file_path_pattern = temp_dir + "dat_{seq}_{index}", + .manifest_file_id_pattern = S3::S3Filename::newCheckpointManifestNameTemplate(store_id), + .manifest_file_path_pattern = temp_dir + "mf_{seq}", + .writer_info = wi, + .must_locked_files = {}, + .persist_checkpoint = CheckpointUploadFunctor{ + .store_id = store_id, + // Note that we use `upload_sequence` but not `snapshot.sequence` for + // the S3 key. + .sequence = upload_sequence, + .remote_store = remote_store, + }, + .override_sequence = upload_sequence, // override by upload_sequence + }; + page_storage->dumpIncrementalCheckpoint(opts); + } + + void clearData() + { + // clear data + store->clearData(); + auto table_column_defines = DMTestEnv::getDefaultColumns(); + store = reload(table_column_defines); + store->deleteRange(*db_context, db_context->getSettingsRef(), RowKeyRange::newAll(false, 1)); + store->flushCache(*db_context, RowKeyRange::newAll(false, 1), true); + store->mergeDeltaAll(*db_context); + } + + void verifyRows(const RowKeyRange & range, size_t rows) + { + const auto & columns = store->getTableColumns(); + BlockInputStreamPtr in = store->read(*db_context, + db_context->getSettingsRef(), + columns, + {range}, + /* num_streams= */ 1, + /* max_version= */ std::numeric_limits::max(), + EMPTY_FILTER, + TRACING_NAME, + /* keep_order= */ false, + /* is_fast_scan= */ false, + /* expected_block_size= */ 1024)[0]; + ASSERT_INPUTSTREAM_NROWS(in, rows); + } + +protected: + DeltaMergeStorePtr store; + UInt64 store_id = 100; + UInt64 upload_sequence = 1000; + bool already_initialize_data_store = false; + bool already_initialize_write_ps = false; + DB::PageStorageRunMode orig_mode; + + constexpr static const char * TRACING_NAME = "DeltaMergeStoreTestFastAddPeer"; +}; + +TEST_F(DeltaMergeStoreTestFastAddPeer, SimpleWriteReadAfterRestoreFromCheckPoint) +try +{ + { + auto table_column_defines = DMTestEnv::getDefaultColumns(); + + store = reload(table_column_defines); + } + + const size_t num_rows_write = 128; + // write DMFile + { + Block block = DMTestEnv::prepareSimpleWriteBlock(0, num_rows_write, false); + store->write(*db_context, db_context->getSettingsRef(), block); + store->flushCache(*db_context, RowKeyRange::newAll(false, 1), true); + store->mergeDeltaAll(*db_context); + } + + // Write ColumnFileTiny + { + Block block = DMTestEnv::prepareSimpleWriteBlock(num_rows_write, num_rows_write + num_rows_write, false); + store->write(*db_context, db_context->getSettingsRef(), block); + store->flushCache(*db_context, RowKeyRange::newAll(false, 1), true); + } + + // write ColumnFileDeleteRange + { + HandleRange handle_range(0, num_rows_write / 2); + store->deleteRange(*db_context, db_context->getSettingsRef(), RowKeyRange::fromHandleRange(handle_range)); + store->flushCache(*db_context, RowKeyRange::newAll(false, 1), true); + } + + // write ColumnFileBig + { + Block block = DMTestEnv::prepareSimpleWriteBlock(num_rows_write + num_rows_write, num_rows_write + 2 * num_rows_write, false); + auto dm_context = store->newDMContext(*db_context, db_context->getSettingsRef()); + auto [range, file_ids] = genDMFile(*dm_context, block); + store->ingestFiles(dm_context, range, file_ids, false); + store->flushCache(*db_context, RowKeyRange::newAll(false, 1), true); + } + + dumpCheckpoint(); + + clearData(); + + verifyRows(RowKeyRange::newAll(store->isCommonHandle(), store->getRowKeyColumnSize()), 0); + + const auto manifest_key = S3::S3Filename::newCheckpointManifest(store_id, upload_sequence).toFullKey(); + auto checkpoint_info = std::make_shared(); + checkpoint_info->remote_store_id = store_id; + checkpoint_info->temp_ps_wrapper = createTempPageStorage(*db_context, manifest_key, /*dir_seq*/ 100); + checkpoint_info->temp_ps = checkpoint_info->temp_ps_wrapper->temp_ps; + store->ingestSegmentsFromCheckpointInfo(*db_context, db_context->getSettingsRef(), RowKeyRange::newAll(false, 1), checkpoint_info); + + verifyRows(RowKeyRange::newAll(store->isCommonHandle(), store->getRowKeyColumnSize()), num_rows_write / 2 + 2 * num_rows_write); + + reload(); + + verifyRows(RowKeyRange::newAll(store->isCommonHandle(), store->getRowKeyColumnSize()), num_rows_write / 2 + 2 * num_rows_write); +} +CATCH + +TEST_F(DeltaMergeStoreTestFastAddPeer, SimpleWriteReadAfterRestoreFromCheckPointWithSplit) +try +{ + auto & global_settings = TiFlashTestEnv::getGlobalContext().getSettingsRef(); + // store the old value to restore global_context settings after the test finish to avoid influence other tests + auto old_global_settings = global_settings; + + // change the settings to make it easier to trigger splitting segments + Settings settings; + settings.dt_segment_limit_rows = 11; + settings.dt_segment_limit_size = 20; + settings.dt_segment_delta_limit_rows = 7; + settings.dt_segment_delta_limit_size = 20; + settings.dt_segment_force_split_size = 100; + settings.dt_segment_delta_cache_limit_size = 20; + + // we need change the settings in both the ctx we get just below and the global_context above. + // because when processing write request, `DeltaMergeStore` will call `checkSegmentUpdate` with the context we just get below. + // and when initialize `DeltaMergeStore`, it will call `checkSegmentUpdate` with the global_context above. + // so we need to make the settings in these two contexts consistent. + global_settings = settings; + auto old_db_context = std::move(db_context); + db_context = DMTestEnv::getContext(settings); + SCOPE_EXIT({ + global_settings = old_global_settings; + db_context = std::move(old_db_context); + }); + { + auto table_column_defines = DMTestEnv::getDefaultColumns(); + + store = reload(table_column_defines); + } + + size_t num_rows_write = 0; + size_t num_rows_write_per_batch = 128; + // write until split and use a big enough finite for loop to make sure the test won't hang forever + for (size_t i = 0; i < 100000; i++) + { + // write to store + Block block = DMTestEnv::prepareSimpleWriteBlock(num_rows_write, num_rows_write + num_rows_write_per_batch, false); + store->write(*db_context, settings, block); + store->flushCache(*db_context, RowKeyRange::newAll(false, 1), true); + num_rows_write += num_rows_write_per_batch; + if (store->getSegmentsStats().size() > 1) + break; + } + { + ASSERT_GT(store->getSegmentsStats().size(), 1); + } + store->mergeDeltaAll(*db_context); + + dumpCheckpoint(); + + clearData(); + + verifyRows(RowKeyRange::newAll(store->isCommonHandle(), store->getRowKeyColumnSize()), 0); + + const auto manifest_key = S3::S3Filename::newCheckpointManifest(store_id, upload_sequence).toFullKey(); + auto checkpoint_info = std::make_shared(); + checkpoint_info->remote_store_id = store_id; + checkpoint_info->temp_ps_wrapper = createTempPageStorage(*db_context, manifest_key, /*dir_seq*/ 100); + checkpoint_info->temp_ps = checkpoint_info->temp_ps_wrapper->temp_ps; + store->ingestSegmentsFromCheckpointInfo(*db_context, db_context->getSettingsRef(), RowKeyRange::fromHandleRange(HandleRange(0, num_rows_write / 2)), checkpoint_info); + verifyRows(RowKeyRange::newAll(store->isCommonHandle(), store->getRowKeyColumnSize()), num_rows_write / 2); + + store->ingestSegmentsFromCheckpointInfo(*db_context, db_context->getSettingsRef(), RowKeyRange::fromHandleRange(HandleRange(num_rows_write / 2, num_rows_write)), checkpoint_info); + verifyRows(RowKeyRange::newAll(store->isCommonHandle(), store->getRowKeyColumnSize()), num_rows_write); +} +CATCH +} // namespace tests +} // namespace DM +} // namespace DB diff --git a/dbms/src/Storages/Page/V3/CheckpointFile/Proto/data_file.proto b/dbms/src/Storages/Page/V3/CheckpointFile/Proto/data_file.proto index d9740982316..37d29d0e0cd 100644 --- a/dbms/src/Storages/Page/V3/CheckpointFile/Proto/data_file.proto +++ b/dbms/src/Storages/Page/V3/CheckpointFile/Proto/data_file.proto @@ -54,6 +54,7 @@ message DataFileSuffix { } message EntryEditRecord { + // Note page_id are not valid utf-8 string. Don't use string type. bytes page_id = 1; uint64 version_sequence = 2; uint64 version_epoch = 3; diff --git a/dbms/src/Storages/Page/V3/CheckpointFile/Proto/manifest_file.proto b/dbms/src/Storages/Page/V3/CheckpointFile/Proto/manifest_file.proto index dd9cdd20b88..23e28e2e7bc 100644 --- a/dbms/src/Storages/Page/V3/CheckpointFile/Proto/manifest_file.proto +++ b/dbms/src/Storages/Page/V3/CheckpointFile/Proto/manifest_file.proto @@ -68,6 +68,7 @@ message EntryDataLocation { message EditRecord { EditType type = 1; + // Note page_id are not valid utf-8 string. Don't use string type. bytes page_id = 2; bytes ori_page_id = 3; uint64 version_sequence = 4; diff --git a/dbms/src/Storages/Page/V3/PageDirectory.cpp b/dbms/src/Storages/Page/V3/PageDirectory.cpp index de030559a59..d327f765ecc 100644 --- a/dbms/src/Storages/Page/V3/PageDirectory.cpp +++ b/dbms/src/Storages/Page/V3/PageDirectory.cpp @@ -1551,12 +1551,31 @@ typename PageDirectory::PageEntries PageDirectory::updateLocalCach for (const auto & r : edit.getRecords()) { - auto iter = mvcc_table_directory.lower_bound(r.page_id); - assert(iter != mvcc_table_directory.end()); - auto & version_list = iter->second; - if (!version_list->updateLocalCacheForRemotePage(PageVersion(seq, 0), r.entry)) + auto id_to_resolve = r.page_id; + auto sequence_to_resolve = seq; + while (true) { - ignored_entries.push_back(r.entry); + auto iter = mvcc_table_directory.lower_bound(id_to_resolve); + assert(iter != mvcc_table_directory.end()); + auto & version_list = iter->second; + auto [resolve_state, next_id_to_resolve, next_ver_to_resolve] = version_list->resolveToPageId(sequence_to_resolve, /*ignore_delete=*/id_to_resolve != r.page_id, nullptr); + if (resolve_state == ResolveResult::TO_NORMAL) + { + if (!version_list->updateLocalCacheForRemotePage(PageVersion(sequence_to_resolve, 0), r.entry)) + { + ignored_entries.push_back(r.entry); + } + break; + } + else if (resolve_state == ResolveResult::TO_REF) + { + id_to_resolve = next_id_to_resolve; + sequence_to_resolve = next_ver_to_resolve.sequence; + } + else + { + RUNTIME_CHECK(false); + } } } } diff --git a/dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp b/dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp index d8b953c656a..fb75d4a123c 100644 --- a/dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp +++ b/dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp @@ -215,8 +215,33 @@ void PageDirectoryFactory::applyRecord( version_list->createNewEntry(restored_version, r.entry); break; case EditRecordType::UPDATE_DATA_FROM_REMOTE: - version_list->updateLocalCacheForRemotePage(restored_version, r.entry); + { + auto id_to_resolve = r.page_id; + auto sequence_to_resolve = restored_version.sequence; + auto version_list_iter = iter; + while (true) + { + const auto & current_version_list = version_list_iter->second; + auto [resolve_state, next_id_to_resolve, next_ver_to_resolve] = current_version_list->resolveToPageId(sequence_to_resolve, /*ignore_delete=*/id_to_resolve != r.page_id, nullptr); + if (resolve_state == ResolveResult::TO_NORMAL) + { + current_version_list->updateLocalCacheForRemotePage(PageVersion(sequence_to_resolve, 0), r.entry); + break; + } + else if (resolve_state == ResolveResult::TO_REF) + { + id_to_resolve = next_id_to_resolve; + sequence_to_resolve = next_ver_to_resolve.sequence; + } + else + { + RUNTIME_CHECK(false); + } + version_list_iter = dir->mvcc_table_directory.lower_bound(id_to_resolve); + assert(version_list_iter != dir->mvcc_table_directory.end()); + } break; + } case EditRecordType::DEL: case EditRecordType::VAR_DELETE: // nothing different from `DEL` version_list->createDelete(restored_version); diff --git a/dbms/src/Storages/Page/V3/Universal/RaftDataReader.cpp b/dbms/src/Storages/Page/V3/Universal/RaftDataReader.cpp index 052c678700a..3596f79f91c 100644 --- a/dbms/src/Storages/Page/V3/Universal/RaftDataReader.cpp +++ b/dbms/src/Storages/Page/V3/Universal/RaftDataReader.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include namespace DB { @@ -40,6 +41,16 @@ void RaftDataReader::traverse(const UniversalPageId & start, const UniversalPage } } +void RaftDataReader::traverseRaftLogForRegion(UInt64 region_id, const std::function & acceptor) +{ + auto start = UniversalPageIdFormat::toFullRaftLogPrefix(region_id); + auto end = UniversalPageIdFormat::toFullRaftLogPrefix(region_id + 1); + traverse(start, end, [&](const UniversalPageId & page_id, const DB::Page & page) { + if (page_id.hasPrefix(start)) + acceptor(page_id, page); + }); +} + std::optional RaftDataReader::getLowerBound(const UniversalPageId & page_id) { auto snapshot = uni_ps.getSnapshot(fmt::format("lower_bound_r_{}", page_id)); diff --git a/dbms/src/Storages/Page/V3/Universal/RaftDataReader.h b/dbms/src/Storages/Page/V3/Universal/RaftDataReader.h index 08bb1a25186..610c9670202 100644 --- a/dbms/src/Storages/Page/V3/Universal/RaftDataReader.h +++ b/dbms/src/Storages/Page/V3/Universal/RaftDataReader.h @@ -31,6 +31,8 @@ class RaftDataReader final // if end is empty, it will be transformed to a key larger than all raft data key void traverse(const UniversalPageId & start, const UniversalPageId & end, const std::function & acceptor); + void traverseRaftLogForRegion(UInt64 region_id, const std::function & acceptor); + // return the first id not less than `page_id` std::optional getLowerBound(const UniversalPageId & page_id); diff --git a/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp b/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp index a5f4c633227..64481acd322 100644 --- a/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp +++ b/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include #include #include #include +#include #include namespace DB::PS::V3 @@ -25,21 +26,33 @@ Page S3PageReader::read(const UniversalPageIdAndEntry & page_id_and_entry) const auto & page_entry = page_id_and_entry.second; RUNTIME_CHECK(page_entry.checkpoint_info.has_value()); auto location = page_entry.checkpoint_info.data_location; + const auto & remote_name = *location.data_file_id; + auto remote_name_view = S3::S3FilenameView::fromKey(remote_name); + RandomAccessFilePtr remote_file; auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); - S3::S3RandomAccessFile file(s3_client, s3_client->bucket(), *location.data_file_id); - file.seek(location.offset_in_file, SEEK_SET); +#ifdef DBMS_PUBLIC_GTEST + if (remote_name_view.isLockFile()) + { +#endif + remote_file = std::make_shared(s3_client, s3_client->bucket(), remote_name_view.asDataFile().toFullKey()); +#ifdef DBMS_PUBLIC_GTEST + } + else + { + // Just used in unit test which want to just focus on read write logic + remote_file = std::make_shared(s3_client, s3_client->bucket(), *location.data_file_id); + } +#endif + ReadBufferFromRandomAccessFile buf(remote_file); + + buf.seek(location.offset_in_file, SEEK_SET); auto buf_size = location.size_in_file; char * data_buf = static_cast(alloc(buf_size)); MemHolder mem_holder = createMemHolder(data_buf, [&, buf_size](char * p) { free(p, buf_size); }); // TODO: support checksum verification - size_t pos = 0; - while (pos < buf_size) - { - auto n = file.read(data_buf + pos, buf_size - pos); - pos += n; - } + buf.readStrict(data_buf, buf_size); Page page{UniversalPageIdFormat::getU64ID(page_id_and_entry.first)}; page.data = std::string_view(data_buf, buf_size); page.mem_holder = mem_holder; diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageIdFormatImpl.h b/dbms/src/Storages/Page/V3/Universal/UniversalPageIdFormatImpl.h index eb70a41dffc..64b8c262fda 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalPageIdFormatImpl.h +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageIdFormatImpl.h @@ -90,7 +90,12 @@ struct UniversalPageIdFormat return buff.releaseStr(); } - // data is in kv engine, so it is prepend by KV_PREFIX + static UniversalPageId toKVStoreKey(UInt64 region_id) + { + return toFullPageId(toSubPrefix(StorageType::KVStore), region_id); + } + + // data is in kv engine, so it is prepended by KV_PREFIX // KV_PREFIX LOCAL_PREFIX REGION_RAFT_PREFIX region_id APPLY_STATE_SUFFIX static UniversalPageId toRaftApplyStateKeyInKVEngine(UInt64 region_id) { @@ -103,7 +108,7 @@ struct UniversalPageIdFormat return buff.releaseStr(); } - // data is in kv engine, so it is prepend by KV_PREFIX + // data is in kv engine, so it is prepended by KV_PREFIX // KV_PREFIX LOCAL_PREFIX REGION_META_PREFIX region_id REGION_STATE_SUFFIX static UniversalPageId toRegionLocalStateKeyInKVEngine(UInt64 region_id) { diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp index 4916efc1695..d1a467fcabb 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp @@ -90,18 +90,11 @@ UniversalPageStorageService::createForTest( return service; } -struct CheckpointUploadFunctor +bool CheckpointUploadFunctor::operator()(const PS::V3::LocalCheckpointFiles & checkpoint) const { - const StoreID store_id; - const UInt64 sequence; - const DM::Remote::IDataStorePtr remote_store; - - bool operator()(const PS::V3::LocalCheckpointFiles & checkpoint) const - { - // Persist checkpoint to remote_source - return remote_store->putCheckpointFiles(checkpoint, store_id, sequence); - } -}; + // Persist checkpoint to remote_source + return remote_store->putCheckpointFiles(checkpoint, store_id, sequence); +} bool UniversalPageStorageService::uploadCheckpoint() { @@ -190,6 +183,8 @@ bool UniversalPageStorageService::uploadCheckpointImpl(const metapb::Store & sto }; uni_page_storage->dumpIncrementalCheckpoint(opts); + LOG_DEBUG(log, "Upload checkpoint with upload sequence {} success", upload_info.upload_sequence); + // the checkpoint is uploaded to remote data store, remove local temp files Poco::File(local_dir).remove(true); diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.h b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.h index c80ceb61113..f1e4d301a47 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.h +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.h @@ -26,6 +26,14 @@ using IDataStorePtr = std::shared_ptr; namespace DB { +struct CheckpointUploadFunctor +{ + const StoreID store_id; + const UInt64 sequence; + const DM::Remote::IDataStorePtr remote_store; + + bool operator()(const PS::V3::LocalCheckpointFiles & checkpoint) const; +}; // This is wrapper class for UniversalPageStorage. // It mainly manages background tasks like gc for UniversalPageStorage. diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalWriteBatchImpl.h b/dbms/src/Storages/Page/V3/Universal/UniversalWriteBatchImpl.h index 1fc14f639bb..31949fe9348 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalWriteBatchImpl.h +++ b/dbms/src/Storages/Page/V3/Universal/UniversalWriteBatchImpl.h @@ -58,6 +58,11 @@ class UniversalWriteBatch : private boost::noncopyable putPage(UniversalPageIdFormat::toFullPageId(prefix, page_id), tag, read_buffer, size, data_sizes); } + void putRemotePage(PageIdU64 page_id, UInt64 tag, const PS::V3::CheckpointLocation & data_location, PageFieldOffsetChecksums && offset_and_checksums) + { + putRemotePage(UniversalPageIdFormat::toFullPageId(prefix, page_id), tag, data_location, std::move(offset_and_checksums)); + } + void putExternal(PageIdU64 page_id, UInt64 tag) { putExternal(UniversalPageIdFormat::toFullPageId(prefix, page_id), tag); diff --git a/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp b/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp index c859540d891..538280dca1c 100644 --- a/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp +++ b/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp @@ -752,14 +752,14 @@ class UniversalPageStorageServiceCheckpointTest : public DB::base::TiFlashStorag auto path = getTemporaryPath(); auto delegator = std::make_shared(path); auto & global_context = DB::tests::TiFlashTestEnv::getGlobalContext(); - s3_client = S3::ClientFactory::instance().sharedClient(); - bucket = S3::ClientFactory::instance().bucket(); uni_ps_service = UniversalPageStorageService::createForTest( global_context, "test.t", delegator, PageStorageConfig{.blob_heavy_gc_valid_rate = 1.0}); log = Logger::get("UniversalPageStorageServiceCheckpointTest"); + s3_client = S3::ClientFactory::instance().sharedClient(); + bucket = S3::ClientFactory::instance().bucket(); ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket)); } @@ -864,7 +864,6 @@ try ASSERT_EQ("The flower carriage rocked", readData(iter->entry.checkpoint_info.data_location)); } // check the first manifest -#if 0 // Mock normal writes && FAP ingest remote page { UniversalWriteBatch batch; @@ -918,6 +917,20 @@ try ASSERT_EQ(EditRecordType::VAR_REF, iter->type); ASSERT_EQ("2", iter->page_id); + iter++; + ASSERT_EQ(EditRecordType::VAR_ENTRY, iter->type); + ASSERT_EQ("20", iter->page_id); + + iter++; + ASSERT_EQ(EditRecordType::VAR_ENTRY, iter->type); + ASSERT_EQ("21", iter->page_id); + ASSERT_EQ("lock/s99/dat_100_1.lock_s2_2", *iter->entry.checkpoint_info.data_location.data_file_id); // this is the lock key to CPDataFile + + iter++; + ASSERT_EQ(EditRecordType::VAR_EXTERNAL, iter->type); + ASSERT_EQ("22", iter->page_id); + ASSERT_EQ("lock/s99/t_50/dmf_999.lock_s2_2", *iter->entry.checkpoint_info.data_location.data_file_id); // this is the lock key to DMFile + iter++; ASSERT_EQ(EditRecordType::VAR_ENTRY, iter->type); ASSERT_EQ("3", iter->page_id); @@ -935,7 +948,6 @@ try ASSERT_EQ("lock/s2/dat_1_0.lock_s2_1", *iter->entry.checkpoint_info.data_location.data_file_id); // this is the lock key to CPDataFile ASSERT_EQ("The flower carriage rocked", readData(iter->entry.checkpoint_info.data_location)); } // check the first manifest -#endif } CATCH diff --git a/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp b/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp index 0b295400f27..9ba82585da2 100644 --- a/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp +++ b/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp @@ -76,6 +76,8 @@ class UniPageStorageRemoteReadTest : public DB::base::TiFlashStorageTestBasic delegator = std::make_shared(path); auto storage = UniversalPageStorage::create("test.t", delegator, config_, file_provider); storage->restore(); + auto mock_s3lock_client = std::make_shared(s3_client, bucket); + storage->initLocksLocalManager(100, mock_s3lock_client); return storage; } @@ -130,6 +132,7 @@ try { auto edits = PS::V3::universal::PageEntriesEdit{}; edits.appendRecord({.type = PS::V3::EditRecordType::VAR_ENTRY, .page_id = "aaabbb", .entry = {.size = 22, .offset = 10}}); + edits.appendRecord({.type = PS::V3::EditRecordType::VAR_REF, .page_id = "aaabbb2", .ori_page_id = "aaabbb"}); writer->writeEditsAndApplyCheckpointInfo(edits); } writer->writeSuffix(); @@ -146,12 +149,13 @@ try { auto edits_r = manifest_reader->readEdits(im); auto r = edits_r->getRecords(); - ASSERT_EQ(1, r.size()); + ASSERT_EQ(2, r.size()); UniversalWriteBatch wb; wb.disableRemoteLock(); wb.putPage(r[0].page_id, 0, "local data"); wb.putRemotePage(r[0].page_id, 0, r[0].entry.checkpoint_info.data_location, std::move(r[0].entry.field_offsets)); + wb.putRefPage(r[1].page_id, r[0].page_id); page_storage->write(std::move(wb)); } @@ -161,6 +165,12 @@ try ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); } + { + auto page = page_storage->read("aaabbb2"); + ASSERT_TRUE(page.isValid()); + ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); + } + // clear remote data and read again to make sure local cache exists deleteBucket(); @@ -169,6 +179,12 @@ try ASSERT_TRUE(page.isValid()); ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); } + + { + auto page = page_storage->read("aaabbb2"); + ASSERT_TRUE(page.isValid()); + ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); + } } CATCH @@ -224,13 +240,92 @@ try ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); } + reload(); + // clear remote data and read again to make sure local cache exists deleteBucket(); + { + auto page = page_storage->read("aaabbb"); + ASSERT_TRUE(page.isValid()); + ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); + } +} +CATCH + +TEST_F(UniPageStorageRemoteReadTest, WriteReadWithRef) +try +{ + auto writer = PS::V3::CPFilesWriter::create({ + .data_file_path = remote_dir + "/data_1", + .data_file_id = "data_1", + .manifest_file_path = remote_dir + "/manifest_foo", + .manifest_file_id = "manifest_foo", + .data_source = PS::V3::CPWriteDataSourceFixture::create({{10, "nahida opened her eyes"}}), + }); + + writer->writePrefix({ + .writer = {}, + .sequence = 5, + .last_sequence = 3, + }); + { + auto edits = PS::V3::universal::PageEntriesEdit{}; + edits.appendRecord({.type = PS::V3::EditRecordType::VAR_ENTRY, .page_id = "aaabbb", .entry = {.size = 22, .offset = 10}}); + writer->writeEditsAndApplyCheckpointInfo(edits); + } + writer->writeSuffix(); + writer.reset(); + uploadFile(remote_dir, "data_1"); + uploadFile(remote_dir, "manifest_foo"); + + auto manifest_file = PosixRandomAccessFile::create(remote_dir + "/manifest_foo"); + auto manifest_reader = PS::V3::CPManifestFileReader::create({ + .plain_file = manifest_file, + }); + manifest_reader->readPrefix(); + PS::V3::CheckpointProto::StringsInternMap im; + { + auto edits_r = manifest_reader->readEdits(im); + auto r = edits_r->getRecords(); + ASSERT_EQ(1, r.size()); + + UniversalWriteBatch wb; + wb.disableRemoteLock(); + wb.putPage(r[0].page_id, 0, "local data"); + wb.putRemotePage(r[0].page_id, 0, r[0].entry.checkpoint_info.data_location, std::move(r[0].entry.field_offsets)); + page_storage->write(std::move(wb)); + } + + { + UniversalWriteBatch wb; + wb.disableRemoteLock(); + wb.putRefPage("aaabbb2", "aaabbb"); + wb.delPage("aaabbb"); + page_storage->write(std::move(wb)); + } + + { + auto page = page_storage->read("aaabbb2"); + ASSERT_TRUE(page.isValid()); + ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); + } + + // clear remote data and read again to make sure local cache exists + deleteBucket(); + + { + auto page = page_storage->read("aaabbb2"); + ASSERT_TRUE(page.isValid()); + ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); + } + + // create an empty bucket because reload will try to read from S3 + ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket)); reload(); { - auto page = page_storage->read("aaabbb"); + auto page = page_storage->read("aaabbb2"); ASSERT_TRUE(page.isValid()); ASSERT_EQ("nahida opened her eyes", String(page.data.begin(), page.data.size())); } @@ -322,6 +417,7 @@ try auto blob_store_edits = blob_store.write(std::move(wb), nullptr); edits.appendRecord({.type = PS::V3::EditRecordType::VAR_ENTRY, .page_id = "page_foo", .entry = blob_store_edits.getRecords()[0].entry}); + edits.appendRecord({.type = PS::V3::EditRecordType::VAR_REF, .page_id = "page_foo2", .ori_page_id = "page_foo"}); } auto writer = PS::V3::CPFilesWriter::create({ @@ -351,19 +447,20 @@ try { auto edits_r = manifest_reader->readEdits(im); auto r = edits_r->getRecords(); - ASSERT_EQ(1, r.size()); + ASSERT_EQ(2, r.size()); UniversalWriteBatch wb; wb.disableRemoteLock(); wb.putRemotePage(r[0].page_id, 0, r[0].entry.checkpoint_info.data_location, std::move(r[0].entry.field_offsets)); + wb.putRefPage(r[1].page_id, r[0].page_id); page_storage->write(std::move(wb)); } - std::vector page_fields; - std::vector read_indices = {0, 2}; - UniversalPageStorage::PageReadFields read_fields = std::make_pair("page_foo", read_indices); - page_fields.emplace_back(read_fields); { + std::vector page_fields; + std::vector read_indices = {0, 2}; + UniversalPageStorage::PageReadFields read_fields = std::make_pair("page_foo", read_indices); + page_fields.emplace_back(read_fields); auto page_map = page_storage->read(page_fields); ASSERT_EQ(page_map.size(), 1); auto & page = page_map.at("page_foo"); @@ -375,13 +472,31 @@ try auto fields3_buf = page.getFieldData(2); ASSERT_EQ("riage rocked", String(fields3_buf.begin(), fields3_buf.size())); } + + { + std::vector page_fields; + std::vector read_indices = {0, 2}; + UniversalPageStorage::PageReadFields read_fields = std::make_pair("page_foo2", read_indices); + page_fields.emplace_back(read_fields); + auto page_map = page_storage->read(page_fields); + ASSERT_EQ(page_map.size(), 1); + auto & page = page_map.at("page_foo2"); + ASSERT_TRUE(page.isValid()); + ASSERT_EQ(page.field_offsets.size(), 2); + ASSERT_EQ(page.data.size(), 4 + 12); + auto fields0_buf = page.getFieldData(0); + ASSERT_EQ("The ", String(fields0_buf.begin(), fields0_buf.size())); + auto fields3_buf = page.getFieldData(2); + ASSERT_EQ("riage rocked", String(fields3_buf.begin(), fields3_buf.size())); + } } CATCH TEST_F(UniPageStorageRemoteReadTest, WriteReadExternal) try { - UniversalPageId page_id{"aaabbb"}; + UniversalPageId page_id1{"aaabbb"}; + UniversalPageId page_id2{"aaabbb2"}; { UniversalWriteBatch wb; wb.disableRemoteLock(); @@ -390,12 +505,19 @@ try .offset_in_file = 0, .size_in_file = 0, }; - wb.putRemoteExternal(page_id, data_location); + wb.putRemoteExternal(page_id1, data_location); + wb.putRefPage(page_id2, page_id1); page_storage->write(std::move(wb)); } { - auto location = page_storage->getCheckpointLocation(page_id); + auto location = page_storage->getCheckpointLocation(page_id1); + ASSERT_TRUE(location.has_value()); + ASSERT_EQ(*(location->data_file_id), "nahida opened her eyes"); + } + + { + auto location = page_storage->getCheckpointLocation(page_id2); ASSERT_TRUE(location.has_value()); ASSERT_EQ(*(location->data_file_id), "nahida opened her eyes"); } @@ -404,7 +526,13 @@ try reload(); { - auto location = page_storage->getCheckpointLocation(page_id); + auto location = page_storage->getCheckpointLocation(page_id1); + ASSERT_TRUE(location.has_value()); + ASSERT_EQ(*(location->data_file_id), "nahida opened her eyes"); + } + + { + auto location = page_storage->getCheckpointLocation(page_id2); ASSERT_TRUE(location.has_value()); ASSERT_EQ(*(location->data_file_id), "nahida opened her eyes"); } diff --git a/dbms/src/Storages/Page/WriteBatchWrapperImpl.h b/dbms/src/Storages/Page/WriteBatchWrapperImpl.h index 7f222d3a6c8..7fadc91bece 100644 --- a/dbms/src/Storages/Page/WriteBatchWrapperImpl.h +++ b/dbms/src/Storages/Page/WriteBatchWrapperImpl.h @@ -91,6 +91,14 @@ class WriteBatchWrapper : private boost::noncopyable putPage(page_id, tag, buffer_ptr, data.size()); } + void putRemotePage(PageIdU64 page_id, UInt64 tag, const PS::V3::CheckpointLocation & data_location, PageFieldOffsetChecksums && offset_and_checksums) + { + if (uwb) + uwb->putRemotePage(page_id, tag, data_location, std::move(offset_and_checksums)); + else + throw Exception(ErrorCodes::LOGICAL_ERROR, "try to put remote page with remote location with u64 id, page_id={}", page_id); + } + void putExternal(PageIdU64 page_id, UInt64 tag) { if (wb) diff --git a/dbms/src/Storages/S3/FileCache.cpp b/dbms/src/Storages/S3/FileCache.cpp index 532e9bbed42..2a9f23e5180 100644 --- a/dbms/src/Storages/S3/FileCache.cpp +++ b/dbms/src/Storages/S3/FileCache.cpp @@ -47,7 +47,6 @@ extern const int S3_ERROR; namespace DB { - using FileType = FileSegment::FileType; FileCache::FileCache(PathCapacityMetricsPtr capacity_metrics_, const StorageRemoteCacheConfig & config_) diff --git a/dbms/src/Storages/S3/S3Filename.cpp b/dbms/src/Storages/S3/S3Filename.cpp index 333cde27d79..df3f499c86c 100644 --- a/dbms/src/Storages/S3/S3Filename.cpp +++ b/dbms/src/Storages/S3/S3Filename.cpp @@ -41,6 +41,10 @@ const static re2::RE2 rgx_store_prefix("^s(?P[0-9]+)/$"); const static re2::RE2 rgx_data_or_manifest("^s(?P[0-9]+)/(data|manifest)/(?P.+)$"); const static re2::RE2 rgx_subpath_manifest("mf_(?P[0-9]+)"); +/// parsing DTFile +const static re2::RE2 rgx_subpath_dtfile("t_(?P[0-9]+)/dmf_(?P[0-9]+)"); +const static re2::RE2 rgx_subpath_keyspace_dtfile("ks_(?P[0-9]+)_t_(?P[0-9]+)/dmf_(?P[0-9]+)"); + constexpr static std::string_view DELMARK_SUFFIX = ".del"; // clang-format off @@ -101,6 +105,33 @@ bool S3FilenameView::isDMFile() const return (startsWith(data_subpath, "t_") || startsWith(data_subpath, "ks_")); } +DMFileOID S3FilenameView::getDMFileOID() const +{ + RUNTIME_CHECK(isDMFile()); + TableID table_id; + UInt64 file_id; + re2::StringPiece prefix_sp{data_subpath.data(), data_subpath.size()}; + if (startsWith(data_subpath, "t_")) + { + RUNTIME_CHECK(re2::RE2::FullMatch(prefix_sp, details::rgx_subpath_dtfile, &table_id, &file_id)); + return DMFileOID{ + .store_id = store_id, + .table_id = table_id, + .file_id = file_id, + }; + } + else + { + UInt64 keyspace_id; + RUNTIME_CHECK(re2::RE2::FullMatch(prefix_sp, details::rgx_subpath_keyspace_dtfile, &keyspace_id, &table_id, &file_id)); + return DMFileOID{ + .store_id = store_id, + .table_id = table_id, + .file_id = file_id, + }; + } +} + String S3FilenameView::toFullKey() const { return details::toFullKey(type, store_id, data_subpath); diff --git a/dbms/src/Storages/S3/S3Filename.h b/dbms/src/Storages/S3/S3Filename.h index bdec58c8409..4236aa38af3 100644 --- a/dbms/src/Storages/S3/S3Filename.h +++ b/dbms/src/Storages/S3/S3Filename.h @@ -80,6 +80,7 @@ struct S3FilenameView ALWAYS_INLINE bool isDataFile() const { return type == S3FilenameType::DataFile; } bool isDMFile() const; + DMFileOID getDMFileOID() const; // Return the lock key prefix for finding any locks on this data file through `S3::LIST` String getLockPrefix() const; // Return the lock key for writing lock file on S3 diff --git a/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp b/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp index 30b87aa8046..107ee4dc47e 100644 --- a/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp +++ b/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp @@ -44,7 +44,6 @@ extern const char force_set_mocked_s3_object_mtime[]; } // namespace DB::FailPoints namespace DB::S3::tests { - class S3GCManagerTest : public DB::base::TiFlashStorageTestBasic { public: diff --git a/dbms/src/Storages/StorageDeltaMerge.cpp b/dbms/src/Storages/StorageDeltaMerge.cpp index 5f245516973..5784c1b38d7 100644 --- a/dbms/src/Storages/StorageDeltaMerge.cpp +++ b/dbms/src/Storages/StorageDeltaMerge.cpp @@ -941,6 +941,18 @@ void StorageDeltaMerge::ingestFiles( clear_data_in_range); } +void StorageDeltaMerge::ingestSegmentsFromCheckpointInfo( + const DM::RowKeyRange & range, + CheckpointInfoPtr checkpoint_info, + const Settings & settings) +{ + return getAndMaybeInitStore()->ingestSegmentsFromCheckpointInfo( + global_context, + settings, + range, + checkpoint_info); +} + UInt64 StorageDeltaMerge::onSyncGc(Int64 limit, const GCOptions & gc_options) { if (storeInited()) diff --git a/dbms/src/Storages/StorageDeltaMerge.h b/dbms/src/Storages/StorageDeltaMerge.h index 1f618908230..a27435e8c26 100644 --- a/dbms/src/Storages/StorageDeltaMerge.h +++ b/dbms/src/Storages/StorageDeltaMerge.h @@ -31,6 +31,8 @@ namespace DB { +struct CheckpointInfo; +using CheckpointInfoPtr = std::shared_ptr; namespace DM { struct RowKeyRange; @@ -112,6 +114,11 @@ class StorageDeltaMerge bool clear_data_in_range, const Settings & settings); + void ingestSegmentsFromCheckpointInfo( + const DM::RowKeyRange & range, + CheckpointInfoPtr checkpoint_info, + const Settings & settings); + UInt64 onSyncGc(Int64, const DM::GCOptions &) override; void rename( diff --git a/dbms/src/Storages/Transaction/ApplySnapshot.cpp b/dbms/src/Storages/Transaction/ApplySnapshot.cpp index 6d7d88a1426..3a8a8df672d 100644 --- a/dbms/src/Storages/Transaction/ApplySnapshot.cpp +++ b/dbms/src/Storages/Transaction/ApplySnapshot.cpp @@ -180,6 +180,10 @@ void KVStore::onSnapshot(const RegionPtrWrap & new_region_wrap, RegionPtr old_re // Call `ingestFiles` to delete data for range and ingest external DTFiles. dm_storage->ingestFiles(new_key_range, new_region_wrap.external_files, /*clear_data_in_range=*/true, context.getSettingsRef()); } + else if constexpr (std::is_same_v) + { + dm_storage->ingestSegmentsFromCheckpointInfo(new_key_range, new_region_wrap.checkpoint_info, context.getSettingsRef()); + } else { // Call `deleteRange` to delete data for range @@ -478,6 +482,11 @@ void KVStore::handleApplySnapshot( applyPreHandledSnapshot(RegionPtrWithSnapshotFiles{new_region, std::move(external_files)}, tmt); } +void KVStore::handleIngestCheckpoint(CheckpointInfoPtr checkpoint_info, TMTContext & tmt) +{ + applyPreHandledSnapshot(RegionPtrWithCheckpointInfo{checkpoint_info}, tmt); +} + EngineStoreApplyRes KVStore::handleIngestSST(UInt64 region_id, const SSTViewVec snaps, UInt64 index, UInt64 term, TMTContext & tmt) { auto region_task_lock = region_manager.genRegionTaskLock(region_id); diff --git a/dbms/src/Storages/Transaction/CheckpointInfo.h b/dbms/src/Storages/Transaction/CheckpointInfo.h new file mode 100644 index 00000000000..b8e460089fe --- /dev/null +++ b/dbms/src/Storages/Transaction/CheckpointInfo.h @@ -0,0 +1,38 @@ +// Copyright 2022 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +using raft_serverpb::PeerState; +using raft_serverpb::RaftApplyState; +using raft_serverpb::RegionLocalState; + +namespace DB +{ +struct TempUniversalPageStorage; +using TempUniversalPageStoragePtr = std::shared_ptr; + +struct CheckpointInfo +{ + UInt64 remote_store_id; + RegionLocalState region_state; + RaftApplyState apply_state; + RegionPtr region; + TempUniversalPageStoragePtr temp_ps_wrapper; // a wrapper to protect the path of `temp_ps` to be deleted + UniversalPageStoragePtr temp_ps; +}; +using CheckpointInfoPtr = std::shared_ptr; +} // namespace DB \ No newline at end of file diff --git a/dbms/src/Storages/Transaction/FastAddPeer.cpp b/dbms/src/Storages/Transaction/FastAddPeer.cpp new file mode 100644 index 00000000000..f7833d309d9 --- /dev/null +++ b/dbms/src/Storages/Transaction/FastAddPeer.cpp @@ -0,0 +1,479 @@ +// Copyright 2022 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DB +{ + +FastAddPeerContext::FastAddPeerContext(uint64_t thread_count) +{ + if (thread_count == 0) + { + static constexpr int ffi_handle_sec = 5; + static constexpr int region_per_sec = 2; + thread_count = ffi_handle_sec * region_per_sec; + } + tasks_trace = std::make_shared(thread_count); +} + +TempUniversalPageStoragePtr FastAddPeerContext::getTempUniversalPageStorage(UInt64 store_id, UInt64 upload_seq) +{ + std::unique_lock lock(ps_cache_mu); + auto iter = temp_ps_cache.find(store_id); + if (iter != temp_ps_cache.end() && iter->second.first >= upload_seq) + { + return iter->second.second; + } + return nullptr; +} + +void FastAddPeerContext::updateTempUniversalPageStorage(UInt64 store_id, UInt64 upload_seq, TempUniversalPageStoragePtr temp_ps) +{ + std::unique_lock lock(ps_cache_mu); + auto iter = temp_ps_cache.find(store_id); + if (iter != temp_ps_cache.end() && iter->second.first >= upload_seq) + return; + + temp_ps_cache[store_id] = std::make_pair(upload_seq, temp_ps); +} + +void FastAddPeerContext::insertSegmentEndKeyInfoToCache(TableIdentifier table_identifier, const std::vector> & end_key_and_segment_ids) +{ + std::unique_lock lock(range_cache_mu); + auto & end_key_to_id_map = segment_range_cache[table_identifier]; + for (const auto & [end_key, segment_id] : end_key_and_segment_ids) + { + end_key_to_id_map[end_key] = segment_id; + } +} + +UInt64 FastAddPeerContext::getSegmentIdContainingKey(TableIdentifier table_identifier, const DM::RowKeyValue & key) +{ + std::unique_lock lock(range_cache_mu); + auto iter = segment_range_cache.find(table_identifier); + if (iter != segment_range_cache.end()) + { + auto & end_key_to_id_map = iter->second; + auto key_iter = end_key_to_id_map.lower_bound(key); + if (key_iter != end_key_to_id_map.end()) + { + return key_iter->second; + } + } + return 0; +} + +void FastAddPeerContext::invalidateCache(TableIdentifier table_identifier) +{ + std::unique_lock lock(range_cache_mu); + segment_range_cache.erase(table_identifier); +} + +FastAddPeerRes genFastAddPeerRes(FastAddPeerStatus status, std::string && apply_str, std::string && region_str) +{ + auto * apply = RawCppString::New(apply_str); + auto * region = RawCppString::New(region_str); + return FastAddPeerRes{ + .status = status, + .apply_state = CppStrWithView{.inner = GenRawCppPtr(apply, RawCppPtrTypeImpl::String), .view = BaseBuffView{apply->data(), apply->size()}}, + .region = CppStrWithView{.inner = GenRawCppPtr(region, RawCppPtrTypeImpl::String), .view = BaseBuffView{region->data(), region->size()}}, + }; +} + +TempUniversalPageStoragePtr createTempPageStorage(Context & context, const String & manifest_key, UInt64 dir_seq) +{ + auto file_provider = context.getFileProvider(); + PageStorageConfig config; + const auto dir_prefix = fmt::format("local_{}", dir_seq); + auto temp_ps_wrapper = std::make_shared(); + auto delegator = context.getPathPool().getPSDiskDelegatorGlobalMulti(dir_prefix); + for (const auto & path : delegator->listPaths()) + { + temp_ps_wrapper->paths.push_back(path); + auto file = Poco::File(path); + if (file.exists()) + { + LOG_WARNING(Logger::get("createTempPageStorage"), "Path {} already exists, removing it", path); + file.remove(true); + } + } + auto local_ps = UniversalPageStorage::create( // + dir_prefix, + delegator, + config, + file_provider); + local_ps->restore(); + temp_ps_wrapper->temp_ps = local_ps; + auto * log = &Poco::Logger::get("FastAddPeer"); + LOG_DEBUG(log, "Begin to create temp ps from {}", manifest_key); + + RandomAccessFilePtr manifest_file = S3::S3RandomAccessFile::create(manifest_key); + auto reader = PS::V3::CPManifestFileReader::create({ + .plain_file = manifest_file, + }); + auto im = PS::V3::CheckpointProto::StringsInternMap{}; + auto prefix = reader->readPrefix(); + UniversalWriteBatch wb; + wb.disableRemoteLock(); + // insert delete records at last + PS::V3::PageEntriesEdit::EditRecords ref_records; + PS::V3::PageEntriesEdit::EditRecords delete_records; + while (true) + { + auto edits = reader->readEdits(im); + if (!edits.has_value()) + break; + auto records = edits->getRecords(); + for (auto & record : records) + { + if (record.type == PS::V3::EditRecordType::VAR_ENTRY) + { + wb.putRemotePage(record.page_id, record.entry.tag, record.entry.checkpoint_info.data_location, std::move(record.entry.field_offsets)); + } + else if (record.type == PS::V3::EditRecordType::VAR_REF) + { + ref_records.emplace_back(record); + } + else if (record.type == PS::V3::EditRecordType::VAR_DELETE) + { + delete_records.emplace_back(record); + } + else if (record.type == PS::V3::EditRecordType::VAR_EXTERNAL) + { + RUNTIME_CHECK(record.entry.checkpoint_info.has_value()); + wb.putRemoteExternal(record.page_id, record.entry.checkpoint_info.data_location); + } + else + { + RUNTIME_CHECK(false); + } + } + } + + for (const auto & record : ref_records) + { + RUNTIME_CHECK(record.type == PS::V3::EditRecordType::VAR_REF); + wb.putRefPage(record.page_id, record.ori_page_id); + } + for (const auto & record : delete_records) + { + RUNTIME_CHECK(record.type == PS::V3::EditRecordType::VAR_DELETE); + wb.delPage(record.page_id); + } + local_ps->write(std::move(wb)); + return temp_ps_wrapper; +} + +TempUniversalPageStoragePtr reuseOrCreateTempPageStorage(Context & context, const String & manifest_key) +{ + auto fap_ctx = context.getSharedContextDisagg()->fap_context; + auto manifest_key_view = S3::S3FilenameView::fromKey(manifest_key); + auto upload_seq = manifest_key_view.getUploadSequence(); + auto temp_ps = fap_ctx->getTempUniversalPageStorage(manifest_key_view.store_id, upload_seq); + if (!temp_ps) + { + temp_ps = createTempPageStorage(context, manifest_key, fap_ctx->temp_ps_dir_sequence++); + fap_ctx->updateTempUniversalPageStorage(manifest_key_view.store_id, upload_seq, temp_ps); + } + return temp_ps; +} + +std::optional tryGetCheckpointInfo(Context & context, const String & manifest_key, uint64_t region_id, TiFlashRaftProxyHelper * proxy_helper) +{ + auto * log = &Poco::Logger::get("FastAddPeer"); + + auto checkpoint_info = std::make_shared(); + auto manifest_key_view = S3::S3FilenameView::fromKey(manifest_key); + checkpoint_info->remote_store_id = manifest_key_view.store_id; + checkpoint_info->temp_ps_wrapper = reuseOrCreateTempPageStorage(context, manifest_key); + checkpoint_info->temp_ps = checkpoint_info->temp_ps_wrapper->temp_ps; + + try + { + auto apply_state_key = UniversalPageIdFormat::toRaftApplyStateKeyInKVEngine(region_id); + auto page = checkpoint_info->temp_ps->read(apply_state_key); + checkpoint_info->apply_state.ParseFromArray(page.data.begin(), page.data.size()); + } + catch (...) + { + LOG_DEBUG(log, "Failed to find apply state key [region_id={}]", region_id); + return std::nullopt; + } + + try + { + auto local_state_key = UniversalPageIdFormat::toRegionLocalStateKeyInKVEngine(region_id); + auto page = checkpoint_info->temp_ps->read(local_state_key); + checkpoint_info->region_state.ParseFromArray(page.data.begin(), page.data.size()); + } + catch (...) + { + LOG_DEBUG(log, "Failed to find region local state key [region_id={}]", region_id); + return std::nullopt; + } + + try + { + auto region_key = UniversalPageIdFormat::toKVStoreKey(region_id); + auto page = checkpoint_info->temp_ps->read(region_key); + ReadBufferFromMemory buf(page.data.begin(), page.data.size()); + checkpoint_info->region = Region::deserialize(buf, proxy_helper); + } + catch (...) + { + LOG_DEBUG(log, "Failed to find region key [region_id={}]", region_id); + return std::nullopt; + } + + return checkpoint_info; +} + +std::vector getAllStoreIDsFromPD(TMTContext & tmt_context) +{ + auto pd_client = tmt_context.getPDClient(); + auto stores_from_pd = pd_client->getAllStores(/*exclude_tombstone*/ true); + std::vector store_ids; + store_ids.reserve(stores_from_pd.size()); + for (const auto & s : stores_from_pd) + { + store_ids.push_back(s.id()); + } + return store_ids; +} + +CheckpointInfoPtr selectCheckpointInfo(Context & context, uint64_t region_id, uint64_t new_peer_id, TiFlashRaftProxyHelper * proxy_helper) +{ + auto * log = &Poco::Logger::get("FastAddPeer"); + + std::vector candidates; + std::map reason; + std::map candidate_stat; + + auto & tmt_context = context.getTMTContext(); + std::vector all_store_ids = getAllStoreIDsFromPD(tmt_context); + auto current_store_id = tmt_context.getKVStore()->getStoreMeta().id(); + auto s3_client = S3::ClientFactory::instance().sharedClient(); + auto bucket = S3::ClientFactory::instance().bucket(); + for (const auto & store_id : all_store_ids) + { + if (store_id == current_store_id) + continue; + const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, bucket, store_id); + if (manifests.empty()) + { + LOG_DEBUG(log, "no manifest on this store, skip store_id={}", store_id); + continue; + } + const auto & latest_manifest_key = manifests.latestManifestKey(); + auto region_info = tryGetCheckpointInfo(context, latest_manifest_key, region_id, proxy_helper); + if (region_info.has_value()) + { + candidates.push_back(std::move(*region_info)); + } + } + + if (candidates.empty()) + { + LOG_INFO(log, "No candidate. [region_id={}]", region_id); + return nullptr; + } + + CheckpointInfoPtr winner = nullptr; + uint64_t largest_applied_index = 0; + for (const auto & candidate : candidates) + { + auto store_id = candidate->remote_store_id; + const auto & region_state = candidate->region_state; + const auto & apply_state = candidate->apply_state; + const auto & peers = region_state.region().peers(); + bool ok = false; + for (auto && pr : peers) + { + if (pr.id() == new_peer_id) + { + ok = true; + break; + } + } + if (!ok) + { + // Can't use this peer if it has no new_peer_id. + reason[store_id] = fmt::format("has no peer_id {}", region_state.ShortDebugString()); + continue; + } + auto peer_state = region_state.state(); + if (peer_state == PeerState::Tombstone || peer_state == PeerState::Applying) + { + // Can't use this peer in these states. + reason[store_id] = fmt::format("bad peer_state {}", region_state.ShortDebugString()); + continue; + } + auto applied_index = apply_state.applied_index(); + if (winner == nullptr || applied_index > largest_applied_index) + { + candidate_stat[store_id] = fmt::format("applied index {}", applied_index); + winner = candidate; + } + } + + if (winner != nullptr) + { + return winner; + } + else + { + FmtBuffer fmt_buf; + for (const auto & r : reason) + { + fmt_buf.fmtAppend("store {} reason {}, ", r.first, r.second); + } + std::string failed_reason = fmt_buf.toString(); + fmt_buf.clear(); + for (const auto & c : candidate_stat) + { + fmt_buf.fmtAppend("store {} stat {}, ", c.first, c.second); + } + std::string choice_stat = fmt_buf.toString(); + LOG_INFO(log, "Failed to find remote checkpoint [region_id={}] [new_peer_id={}] [total_candidates={}]; reason: {}; candidates_stat: {};", region_id, new_peer_id, candidates.size(), failed_reason, choice_stat); + return nullptr; + } +} + +void resetPeerIdInRegion(RegionPtr region, const RegionLocalState & region_state, uint64_t new_peer_id) +{ + for (auto && pr : region_state.region().peers()) + { + if (pr.id() == new_peer_id) + { + auto cpr = pr; + region->mutMeta().setPeer(std::move(cpr)); + return; + } + } + RUNTIME_CHECK(false); +} + +FastAddPeerRes FastAddPeerImpl(EngineStoreServerWrap * server, uint64_t region_id, uint64_t new_peer_id) +{ + try + { + auto * log = &Poco::Logger::get("FastAddPeer"); + auto kvstore = server->tmt->getKVStore(); + Stopwatch watch; + CheckpointInfoPtr checkpoint_info; + while (true) + { + checkpoint_info = selectCheckpointInfo(server->tmt->getContext(), region_id, new_peer_id, server->proxy_helper); + if (checkpoint_info == nullptr) + { + // TODO: make it a config + constexpr int wait_source_apply_timeout_seconds = 60; + if (watch.elapsedSeconds() >= wait_source_apply_timeout_seconds) + return genFastAddPeerRes(FastAddPeerStatus::NoSuitable, "", ""); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + else + break; + } + LOG_INFO(log, "Select checkpoint from store {} takes {} seconds; [region_id={}]", checkpoint_info->remote_store_id, watch.elapsedSeconds(), region_id); + + resetPeerIdInRegion(checkpoint_info->region, checkpoint_info->region_state, new_peer_id); + + kvstore->handleIngestCheckpoint(checkpoint_info, *server->tmt); + + // Write raft log to uni ps + UniversalWriteBatch wb; + RaftDataReader raft_data_reader(*(checkpoint_info->temp_ps)); + raft_data_reader.traverseRaftLogForRegion(region_id, [&](const UniversalPageId & page_id, DB::Page page) { + MemoryWriteBuffer buf; + buf.write(page.data.begin(), page.data.size()); + wb.putPage(page_id, 0, buf.tryGetReadBuffer(), page.data.size()); + }); + auto wn_ps = server->tmt->getContext().getWriteNodePageStorage(); + wn_ps->write(std::move(wb)); + + return genFastAddPeerRes(FastAddPeerStatus::Ok, checkpoint_info->apply_state.SerializeAsString(), checkpoint_info->region_state.region().SerializeAsString()); + } + catch (...) + { + DB::tryLogCurrentException("FastAddPeer", "Failed when try to restore from checkpoint"); + return genFastAddPeerRes(FastAddPeerStatus::BadData, "", ""); + } +} + +FastAddPeerRes FastAddPeer(EngineStoreServerWrap * server, uint64_t region_id, uint64_t new_peer_id) +{ + try + { + auto * log = &Poco::Logger::get("FastAddPeer"); + auto fap_ctx = server->tmt->getContext().getSharedContextDisagg()->fap_context; + RUNTIME_CHECK(fap_ctx != nullptr); + if (!fap_ctx->tasks_trace->isScheduled(region_id)) + { + // We need to schedule the task. + auto res = fap_ctx->tasks_trace->addTask(region_id, [server, region_id, new_peer_id]() { + return FastAddPeerImpl(server, region_id, new_peer_id); + }); + if (res) + { + LOG_INFO(log, "add new task [new_peer_id={}] [region_id={}]", new_peer_id, region_id); + } + else + { + LOG_INFO(log, "add new task fail(queue full) [new_peer_id={}] [region_id={}]", new_peer_id, region_id); + return genFastAddPeerRes(FastAddPeerStatus::WaitForData, "", ""); + } + } + + if (fap_ctx->tasks_trace->isReady(region_id)) + { + LOG_INFO(log, "fetch task result [new_peer_id={}] [region_id={}]", new_peer_id, region_id); + return fap_ctx->tasks_trace->fetchResult(region_id); + } + else + { + LOG_DEBUG(log, "the task is still pending [new_peer_id={}] [region_id={}]", new_peer_id, region_id); + return genFastAddPeerRes(FastAddPeerStatus::WaitForData, "", ""); + } + } + catch (...) + { + DB::tryLogCurrentException("FastAddPeer", fmt::format("Failed when try to restore from checkpoint {}", StackTrace().toString())); + return genFastAddPeerRes(FastAddPeerStatus::OtherError, "", ""); + } +} +} // namespace DB diff --git a/dbms/src/Storages/Transaction/FastAddPeer.h b/dbms/src/Storages/Transaction/FastAddPeer.h new file mode 100644 index 00000000000..1afad1b6757 --- /dev/null +++ b/dbms/src/Storages/Transaction/FastAddPeer.h @@ -0,0 +1,120 @@ +// Copyright 2022 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +#include + +namespace DB +{ +struct TableIdentifier +{ + UInt64 key_space_id; + UInt64 store_id; + DB::NamespaceId table_id; + + bool operator==(const TableIdentifier & other) const + { + return key_space_id == other.key_space_id && store_id == other.store_id && table_id == other.table_id; + } +}; +} // namespace DB + +namespace std +{ +template <> +struct hash +{ + size_t operator()(const DB::TableIdentifier & k) const + { + size_t seed = 0; + boost::hash_combine(seed, boost::hash_value(k.key_space_id)); + boost::hash_combine(seed, boost::hash_value(k.store_id)); + boost::hash_combine(seed, boost::hash_value(k.table_id)); + return seed; + } +}; +} // namespace std + +namespace DB +{ +class UniversalPageStorage; +using UniversalPageStoragePtr = std::shared_ptr; + +struct TempUniversalPageStorage +{ + UniversalPageStoragePtr temp_ps; + std::vector paths = {}; + + ~TempUniversalPageStorage() + { + for (const auto & path : paths) + { + Poco::File(path).remove(true); + } + } +}; +using TempUniversalPageStoragePtr = std::shared_ptr; + +struct AsyncTasks; + +class FastAddPeerContext +{ +public: + explicit FastAddPeerContext(uint64_t thread_count = 0); + + // return a TempUniversalPageStoragePtr which have sequence >= upload_seq + TempUniversalPageStoragePtr getTempUniversalPageStorage(UInt64 store_id, UInt64 upload_seq); + + void updateTempUniversalPageStorage(UInt64 store_id, UInt64 upload_seq, TempUniversalPageStoragePtr temp_ps); + + void insertSegmentEndKeyInfoToCache(TableIdentifier table_identifier, const std::vector> & end_key_and_segment_ids); + + // return the cached id of the segment which contains the target key + // return 0 means no cache info for the key + UInt64 getSegmentIdContainingKey(TableIdentifier table_identifier, const DM::RowKeyValue & key); + + // TODO: invalidate cache at segment level + void invalidateCache(TableIdentifier table_identifier); + +public: + std::shared_ptr tasks_trace; + std::atomic temp_ps_dir_sequence; + +private: + std::mutex ps_cache_mu; + // Store the latest manifest data for every store + // StoreId -> pair + std::unordered_map> temp_ps_cache; + + std::mutex range_cache_mu; + + struct KeyComparator : public std::binary_function + { + bool operator()(const DM::RowKeyValue & key1, const DM::RowKeyValue & key2) const + { + return compare(key1.toRowKeyValueRef(), key2.toRowKeyValueRef()); + } + }; + + // Store the mapping from end key to segment id for each table + // TableIdentifier -> (Segment Range End -> Segment ID) + std::unordered_map> segment_range_cache; +}; + +TempUniversalPageStoragePtr createTempPageStorage(Context & context, const String & manifest_key, UInt64 dir_seq); +} // namespace DB diff --git a/dbms/src/Storages/Transaction/FastAddPeerAsyncTasksImpl.h b/dbms/src/Storages/Transaction/FastAddPeerAsyncTasksImpl.h new file mode 100644 index 00000000000..f13023ccc77 --- /dev/null +++ b/dbms/src/Storages/Transaction/FastAddPeerAsyncTasksImpl.h @@ -0,0 +1,81 @@ +// Copyright 2022 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +#include + +namespace DB +{ +struct AsyncTasks +{ + using Key = uint64_t; + using Func = std::function; + + // We use a big queue to cache, to reduce ass task failures. + explicit AsyncTasks(uint64_t pool_size) + : thread_pool(std::make_unique(pool_size, pool_size, 300)) + {} + explicit AsyncTasks(uint64_t pool_size, uint64_t free_pool_size, uint64_t queue_size) + : thread_pool(std::make_unique(pool_size, free_pool_size, queue_size)) + {} + + bool addTask(Key k, Func f) + { + using P = std::packaged_task; + std::shared_ptr

p = std::make_shared

(P(f)); + + auto res = thread_pool->trySchedule([p]() { (*p)(); }, 0, 0); + if (res) + { + std::scoped_lock l(mtx); + futures[k] = p->get_future(); + } + return res; + } + + bool isScheduled(Key key) const + { + std::scoped_lock l(mtx); + return futures.count(key); + } + + bool isReady(Key key) const + { + using namespace std::chrono_literals; + std::scoped_lock l(mtx); + if (!futures.count(key)) + return false; + return futures.at(key).wait_for(0ms) == std::future_status::ready; + } + + FastAddPeerRes fetchResult(Key key) + { + std::unique_lock l(mtx); + auto it = futures.find(key); + auto fut = std::move(it->second); + futures.erase(it); + l.unlock(); + return fut.get(); + } + +protected: + std::map> futures; + std::unique_ptr thread_pool; + mutable std::mutex mtx; +}; +} // namespace DB \ No newline at end of file diff --git a/dbms/src/Storages/Transaction/KVStore.h b/dbms/src/Storages/Transaction/KVStore.h index ba43fd72566..e40954bfbd8 100644 --- a/dbms/src/Storages/Transaction/KVStore.h +++ b/dbms/src/Storages/Transaction/KVStore.h @@ -73,6 +73,8 @@ class ReadIndexStressTest; struct FileUsageStatistics; class PathPool; class RegionPersister; +struct CheckpointInfo; +using CheckpointInfoPtr = std::shared_ptr; /// TODO: brief design document. class KVStore final : private boost::noncopyable @@ -119,6 +121,8 @@ class KVStore final : private boost::noncopyable */ void handleApplySnapshot(metapb::Region && region, uint64_t peer_id, SSTViewVec, uint64_t index, uint64_t term, TMTContext & tmt); + void handleIngestCheckpoint(CheckpointInfoPtr checkpoint_info, TMTContext & tmt); + std::vector preHandleSnapshotToFiles( RegionPtr new_region, SSTViewVec, diff --git a/dbms/src/Storages/Transaction/ProxyFFI.h b/dbms/src/Storages/Transaction/ProxyFFI.h index bc71e47c529..f8d2658d60d 100644 --- a/dbms/src/Storages/Transaction/ProxyFFI.h +++ b/dbms/src/Storages/Transaction/ProxyFFI.h @@ -169,6 +169,7 @@ CppStrWithView GetConfig(EngineStoreServerWrap *, uint8_t full); void SetStore(EngineStoreServerWrap *, BaseBuffView); void SetPBMsByBytes(MsgPBType type, RawVoidPtr ptr, BaseBuffView view); void HandleSafeTSUpdate(EngineStoreServerWrap * server, uint64_t region_id, uint64_t self_safe_ts, uint64_t leader_safe_ts); +FastAddPeerRes FastAddPeer(EngineStoreServerWrap * server, uint64_t region_id, uint64_t new_peer_id); } inline EngineStoreServerHelper GetEngineStoreServerHelper( @@ -215,6 +216,7 @@ inline EngineStoreServerHelper GetEngineStoreServerHelper( .fn_set_store = SetStore, .fn_set_pb_msg_by_bytes = SetPBMsByBytes, .fn_handle_safe_ts_update = HandleSafeTSUpdate, + .fn_fast_add_peer = FastAddPeer, }; } diff --git a/dbms/src/Storages/Transaction/Region.h b/dbms/src/Storages/Transaction/Region.h index 869a2ca44fe..403c1b15f2a 100644 --- a/dbms/src/Storages/Transaction/Region.h +++ b/dbms/src/Storages/Transaction/Region.h @@ -203,6 +203,8 @@ class Region : public std::enable_shared_from_this std::pair getApproxMemCacheInfo() const; void cleanApproxMemCacheInfo() const; + RegionMeta & mutMeta() { return meta; } + private: Region() = delete; friend class RegionRaftCommandDelegate; diff --git a/dbms/src/Storages/Transaction/RegionMeta.cpp b/dbms/src/Storages/Transaction/RegionMeta.cpp index 13a20a39a9b..de9c0d042de 100644 --- a/dbms/src/Storages/Transaction/RegionMeta.cpp +++ b/dbms/src/Storages/Transaction/RegionMeta.cpp @@ -72,6 +72,12 @@ metapb::Peer RegionMeta::getPeer() const return peer; } +void RegionMeta::setPeer(metapb::Peer && p) +{ + std::lock_guard lock(mutex); + peer = p; +} + raft_serverpb::RaftApplyState RegionMeta::getApplyState() const { std::lock_guard lock(mutex); diff --git a/dbms/src/Storages/Transaction/RegionMeta.h b/dbms/src/Storages/Transaction/RegionMeta.h index 39616c1fa8d..08fed625c2a 100644 --- a/dbms/src/Storages/Transaction/RegionMeta.h +++ b/dbms/src/Storages/Transaction/RegionMeta.h @@ -75,6 +75,7 @@ class RegionMeta ImutRegionRangePtr getRange() const; metapb::Peer getPeer() const; + void setPeer(metapb::Peer &&); UInt64 version() const; diff --git a/dbms/src/Storages/Transaction/RegionTable.cpp b/dbms/src/Storages/Transaction/RegionTable.cpp index 18d34980247..c2078a8dc46 100644 --- a/dbms/src/Storages/Transaction/RegionTable.cpp +++ b/dbms/src/Storages/Transaction/RegionTable.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -501,6 +502,11 @@ RegionPtrWithSnapshotFiles::RegionPtrWithSnapshotFiles( , external_files(std::move(external_files_)) {} +RegionPtrWithCheckpointInfo::RegionPtrWithCheckpointInfo(CheckpointInfoPtr checkpoint_info_) + : base(checkpoint_info_->region) + , checkpoint_info(std::move(checkpoint_info_)) +{} + bool RegionTable::isSafeTSLag(UInt64 region_id, UInt64 * leader_safe_ts, UInt64 * self_safe_ts) { { diff --git a/dbms/src/Storages/Transaction/RegionTable.h b/dbms/src/Storages/Transaction/RegionTable.h index 03f60f1644f..0150a77edeb 100644 --- a/dbms/src/Storages/Transaction/RegionTable.h +++ b/dbms/src/Storages/Transaction/RegionTable.h @@ -55,6 +55,8 @@ struct RegionPtrWithBlock; struct RegionPtrWithSnapshotFiles; class RegionScanFilter; using RegionScanFilterPtr = std::shared_ptr; +struct CheckpointInfo; +using CheckpointInfoPtr = std::shared_ptr; using SafeTS = UInt64; enum : SafeTS @@ -298,4 +300,22 @@ struct RegionPtrWithSnapshotFiles const std::vector external_files; }; +// A wrap of RegionPtr, with checkpoint info to be ingested +struct RegionPtrWithCheckpointInfo +{ + using Base = RegionPtr; + + RegionPtrWithCheckpointInfo(CheckpointInfoPtr checkpoint_info_); + + /// to be compatible with usage as RegionPtr. + Base::element_type * operator->() const { return base.operator->(); } + const Base::element_type & operator*() const { return base.operator*(); } + + /// make it could be cast into RegionPtr implicitly. + operator const Base &() const { return base; } + + const Base & base; + CheckpointInfoPtr checkpoint_info; +}; + } // namespace DB diff --git a/dbms/src/Storages/Transaction/tests/gtest_kvstore_fast_add_peer.cpp b/dbms/src/Storages/Transaction/tests/gtest_kvstore_fast_add_peer.cpp new file mode 100644 index 00000000000..73e7025aae5 --- /dev/null +++ b/dbms/src/Storages/Transaction/tests/gtest_kvstore_fast_add_peer.cpp @@ -0,0 +1,259 @@ +// Copyright 2022 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using raft_serverpb::RaftApplyState; +using raft_serverpb::RegionLocalState; + +namespace DB +{ +FastAddPeerRes genFastAddPeerRes(FastAddPeerStatus status, std::string && apply_str, std::string && region_str); +TempUniversalPageStoragePtr reuseOrCreateTempPageStorage(Context & context, const String & manifest_key); + +namespace tests +{ +class RegionKVStoreTestFAP : public RegionKVStoreTest +{ +public: + void SetUp() override + { + auto & global_context = TiFlashTestEnv::getGlobalContext(); + if (global_context.getSharedContextDisagg()->remote_data_store == nullptr) + { + already_initialize_data_store = false; + global_context.getSharedContextDisagg()->initRemoteDataStore(global_context.getFileProvider(), /*s3_enabled*/ true); + ASSERT_TRUE(global_context.getSharedContextDisagg()->remote_data_store != nullptr); + } + else + { + already_initialize_data_store = true; + } + orig_mode = global_context.getPageStorageRunMode(); + global_context.setPageStorageRunMode(PageStorageRunMode::UNI_PS); + global_context.getSharedContextDisagg()->initFastAddPeerContext(); + RegionKVStoreTest::SetUp(); + } + + void TearDown() override + { + auto & global_context = TiFlashTestEnv::getGlobalContext(); + if (!already_initialize_data_store) + { + global_context.getSharedContextDisagg()->remote_data_store = nullptr; + } + global_context.setPageStorageRunMode(orig_mode); + } + +protected: + bool createBucketIfNotExist() + { + auto s3_client = S3::ClientFactory::instance().sharedClient(); + auto bucket = S3::ClientFactory::instance().bucket(); + Aws::S3::Model::CreateBucketRequest request; + request.SetBucket(bucket); + auto outcome = s3_client->CreateBucket(request); + if (outcome.IsSuccess()) + { + LOG_DEBUG(Logger::get(), "Created bucket {}", bucket); + } + else if (outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou") + { + LOG_DEBUG(Logger::get(), "Bucket {} already exist", bucket); + } + else + { + const auto & err = outcome.GetError(); + LOG_ERROR(Logger::get(), "CreateBucket: {}:{}", err.GetExceptionName(), err.GetMessage()); + } + return outcome.IsSuccess() || outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou"; + } + + void dumpCheckpoint() + { + auto & global_context = TiFlashTestEnv::getGlobalContext(); + auto temp_dir = TiFlashTestEnv::getTemporaryPath() + "/"; + auto page_storage = global_context.getWriteNodePageStorage(); + KVStore & kvs = getKVS(); + auto store_id = kvs.getStore().store_id.load(); + auto wi = PS::V3::CheckpointProto::WriterInfo(); + { + wi.set_store_id(store_id); + } + + auto remote_store = global_context.getSharedContextDisagg()->remote_data_store; + assert(remote_store != nullptr); + UniversalPageStorage::DumpCheckpointOptions opts{ + .data_file_id_pattern = S3::S3Filename::newCheckpointDataNameTemplate(store_id, upload_sequence), + .data_file_path_pattern = temp_dir + "dat_{seq}_{index}", + .manifest_file_id_pattern = S3::S3Filename::newCheckpointManifestNameTemplate(store_id), + .manifest_file_path_pattern = temp_dir + "mf_{seq}", + .writer_info = wi, + .must_locked_files = {}, + .persist_checkpoint = CheckpointUploadFunctor{ + .store_id = store_id, + // Note that we use `upload_sequence` but not `snapshot.sequence` for + // the S3 key. + .sequence = upload_sequence, + .remote_store = remote_store, + }, + .override_sequence = upload_sequence, // override by upload_sequence + }; + page_storage->dumpIncrementalCheckpoint(opts); + } + +protected: + UInt64 upload_sequence = 1000; + +private: + ContextPtr context; + bool already_initialize_data_store = false; + DB::PageStorageRunMode orig_mode; +}; + +TEST_F(RegionKVStoreTestFAP, FAPThreadPool) +try +{ + auto * log = &Poco::Logger::get("RegionKVStoreTest"); + using namespace std::chrono_literals; + auto fap_context = std::make_shared(1); + auto async_tasks = fap_context->tasks_trace; + + int total = 5; + std::vector f(total, false); + while (true) + { + auto count = std::accumulate(f.begin(), f.end(), 0, [&](int a, bool b) -> int { + return a + int(b); + }); + if (count >= total) + { + break; + } + else + { + LOG_DEBUG(log, "finished {}/{}", count, total); + } + for (int i = 0; i < total; i++) + { + if (!async_tasks->isScheduled(i)) + { + auto res = async_tasks->addTask(i, []() { + std::this_thread::sleep_for(1000ms); + return genFastAddPeerRes(FastAddPeerStatus::WaitForData, "", ""); + }); + UNUSED(res); + } + } + + for (int i = 0; i < total; i++) + { + if (!f[i]) + { + if (async_tasks->isReady(i)) + { + auto r = async_tasks->fetchResult(i); + UNUSED(r); + f[i] = true; + } + } + } + std::this_thread::sleep_for(1000ms); + } +} +CATCH + +void persistAfterWrite(Context & ctx, KVStore & kvs, std::unique_ptr & proxy_instance, UniversalPageStoragePtr page_storage, uint64_t region_id, uint64_t index) +{ + MockRaftStoreProxy::FailCond cond; + proxy_instance->doApply(kvs, ctx.getTMTContext(), cond, region_id, index); + auto region = proxy_instance->getRegion(region_id); + auto wb = region->persistMeta(); + page_storage->write(std::move(wb), nullptr); + // There shall be data to flush. + ASSERT_EQ(kvs.needFlushRegionData(region_id, ctx.getTMTContext()), true); + ASSERT_EQ(kvs.tryFlushRegionData(region_id, false, false, ctx.getTMTContext(), 0, 0), true); +} + +TEST_F(RegionKVStoreTestFAP, RestoreRaftState) +try +{ + auto & global_context = TiFlashTestEnv::getGlobalContext(); + uint64_t region_id = 1; + auto peer_id = 1; + KVStore & kvs = getKVS(); + auto page_storage = global_context.getWriteNodePageStorage(); + + proxy_instance->bootstrap(kvs, global_context.getTMTContext(), region_id); + auto region = proxy_instance->getRegion(region_id); + auto store_id = kvs.getStore().store_id.load(); + region->addPeer(store_id, peer_id, metapb::PeerRole::Learner); + + // Write some data, and persist meta. + auto [index, term] = proxy_instance->normalWrite(region_id, {34}, {"v2"}, {WriteCmdType::Put}, {ColumnFamilyType::Default}); + persistAfterWrite(global_context, kvs, proxy_instance, page_storage, region_id, index); + + ASSERT_TRUE(createBucketIfNotExist()); + dumpCheckpoint(); + + std::optional checkpoint_info; + auto s3_client = S3::ClientFactory::instance().sharedClient(); + auto bucket = S3::ClientFactory::instance().bucket(); + const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, bucket, store_id); + ASSERT_TRUE(!manifests.empty()); + const auto & latest_manifest_key = manifests.latestManifestKey(); + auto temp_ps_wrapper = reuseOrCreateTempPageStorage(global_context, latest_manifest_key); + + RaftApplyState apply_state; + { + auto apply_state_key = UniversalPageIdFormat::toRaftApplyStateKeyInKVEngine(region_id); + auto page = temp_ps_wrapper->temp_ps->read(apply_state_key); + apply_state.ParseFromArray(page.data.begin(), page.data.size()); + } + + RegionLocalState region_state; + { + auto local_state_key = UniversalPageIdFormat::toRegionLocalStateKeyInKVEngine(region_id); + auto page = temp_ps_wrapper->temp_ps->read(local_state_key); + region_state.ParseFromArray(page.data.begin(), page.data.size()); + } + + ASSERT_TRUE(apply_state == region->getApply()); + ASSERT_TRUE(region_state == region->getState()); + + auto fap_context = global_context.getSharedContextDisagg()->fap_context; + ASSERT_TRUE(fap_context->getTempUniversalPageStorage(store_id, upload_sequence) != nullptr); + ASSERT_TRUE(fap_context->getTempUniversalPageStorage(store_id, upload_sequence - 1) != nullptr); + ASSERT_TRUE(fap_context->getTempUniversalPageStorage(store_id, upload_sequence + 1) == nullptr); +} +CATCH +} // namespace tests +} // namespace DB diff --git a/dbms/src/Storages/Transaction/tests/gtest_region_persister.cpp b/dbms/src/Storages/Transaction/tests/gtest_region_persister.cpp index ca4dbbe0565..3c850e5bf76 100644 --- a/dbms/src/Storages/Transaction/tests/gtest_region_persister.cpp +++ b/dbms/src/Storages/Transaction/tests/gtest_region_persister.cpp @@ -227,12 +227,14 @@ class RegionPersisterTest /*kvstore_paths=*/Strings{}, path_capacity, provider); + global_ctx.tryReleaseWriteNodePageStorageForTest(); global_ctx.initializeWriteNodePageStorageIfNeed(*mocked_path_pool); } void reload() { auto & global_ctx = DB::tests::TiFlashTestEnv::getGlobalContext(); + global_ctx.tryReleaseWriteNodePageStorageForTest(); global_ctx.initializeWriteNodePageStorageIfNeed(*mocked_path_pool); } diff --git a/dbms/src/Storages/Transaction/tests/kvstore_helper.h b/dbms/src/Storages/Transaction/tests/kvstore_helper.h index 79593bd1020..8b191d462c5 100644 --- a/dbms/src/Storages/Transaction/tests/kvstore_helper.h +++ b/dbms/src/Storages/Transaction/tests/kvstore_helper.h @@ -101,6 +101,7 @@ class RegionKVStoreTest : public ::testing::Test { kvstore.reset(); auto & global_ctx = TiFlashTestEnv::getGlobalContext(); + global_ctx.tryReleaseWriteNodePageStorageForTest(); global_ctx.initializeWriteNodePageStorageIfNeed(*path_pool); kvstore = std::make_unique(global_ctx); // only recreate kvstore and restore data from disk, don't recreate proxy instance diff --git a/dbms/src/TestUtils/TiFlashStorageTestBasic.cpp b/dbms/src/TestUtils/TiFlashStorageTestBasic.cpp index f3a00259617..2a5798b0123 100644 --- a/dbms/src/TestUtils/TiFlashStorageTestBasic.cpp +++ b/dbms/src/TestUtils/TiFlashStorageTestBasic.cpp @@ -17,7 +17,6 @@ namespace DB::base { - void TiFlashStorageTestBasic::reload() { reload({}); diff --git a/dbms/src/TestUtils/TiFlashTestEnv.cpp b/dbms/src/TestUtils/TiFlashTestEnv.cpp index 670e9b65a5a..59d77829f4f 100644 --- a/dbms/src/TestUtils/TiFlashTestEnv.cpp +++ b/dbms/src/TestUtils/TiFlashTestEnv.cpp @@ -183,6 +183,7 @@ ContextPtr TiFlashTestEnv::getContext(const DB::Settings & settings, Strings tes auto paths = getPathPool(testdata_path); context.setPathPool(paths.first, paths.second, Strings{}, context.getPathCapacity(), context.getFileProvider()); global_contexts[0]->initializeGlobalStoragePoolIfNeed(context.getPathPool()); + global_contexts[0]->tryReleaseWriteNodePageStorageForTest(); global_contexts[0]->initializeWriteNodePageStorageIfNeed(context.getPathPool()); context.getSettingsRef() = settings; return std::make_shared(context); From 3d64533c94e60dbb729aaeb705827b99d4943455 Mon Sep 17 00:00:00 2001 From: jinhelin Date: Tue, 14 Mar 2023 17:50:39 +0800 Subject: [PATCH 08/18] Storage: File size of DMFile's subfiles can be zero. (#7069) ref pingcap/tiflash#6827 --- dbms/src/Storages/S3/FileCache.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dbms/src/Storages/S3/FileCache.cpp b/dbms/src/Storages/S3/FileCache.cpp index 2a9f23e5180..cdd7b072450 100644 --- a/dbms/src/Storages/S3/FileCache.cpp +++ b/dbms/src/Storages/S3/FileCache.cpp @@ -391,7 +391,7 @@ void FileCache::downloadImpl(const String & s3_key, FileSegmentPtr & file_seg) } auto & result = outcome.GetResult(); auto content_length = result.GetContentLength(); - RUNTIME_CHECK_MSG(content_length > 0, "s3_key={}, content_length={}", s3_key, content_length); + RUNTIME_CHECK(content_length >= 0, s3_key, content_length); ProfileEvents::increment(ProfileEvents::S3ReadBytes, content_length); GET_METRIC(tiflash_storage_s3_request_seconds, type_get_object).Observe(sw.elapsedSeconds()); if (!finalizeReservedSize(file_seg->getFileType(), file_seg->getSize(), content_length)) @@ -407,9 +407,13 @@ void FileCache::downloadImpl(const String & s3_key, FileSegmentPtr & file_seg) { Aws::OFStream ostr(temp_fname, std::ios_base::out | std::ios_base::binary); RUNTIME_CHECK_MSG(ostr.is_open(), "Open {} failed: {}", temp_fname, strerror(errno)); - ostr << result.GetBody().rdbuf(); - RUNTIME_CHECK_MSG(ostr.good(), "Write {} failed: {}", temp_fname, strerror(errno)); - ostr.flush(); + if (content_length > 0) + { + ostr << result.GetBody().rdbuf(); + // If content_length == 0, ostr.good() is false. Does not know the reason. + RUNTIME_CHECK_MSG(ostr.good(), "Write {} content_length {} failed: {}", temp_fname, content_length, strerror(errno)); + ostr.flush(); + } } std::filesystem::rename(temp_fname, local_fname); auto fsize = std::filesystem::file_size(local_fname); From 1c181a2b613097ea3864e78e2e7eb7eca6a9098a Mon Sep 17 00:00:00 2001 From: Wenxuan Date: Tue, 14 Mar 2023 22:36:39 +0800 Subject: [PATCH 09/18] Fix disaggregated read deadlock (#7066) ref pingcap/tiflash#6827 --- dbms/src/Common/UniThreadPool.cpp | 11 ++- dbms/src/Common/UniThreadPool.h | 52 +++++++------ .../Flash/Disaggregated/RNPagePreparer.cpp | 4 +- .../Flash/Disaggregated/RNPageReceiver.cpp | 2 +- .../Disaggregated/RNPageReceiverContext.cpp | 2 +- .../Disaggregated/RNPageReceiverContext.h | 2 +- dbms/src/IO/IOThreadPool.h | 23 ++++-- .../IO/{IOThreadPool.cpp => IOThreadPools.h} | 40 +++++----- dbms/src/Server/Server.cpp | 78 +++++++++++++++---- .../Remote/DataStore/DataStoreS3.cpp | 8 +- .../DeltaMerge/Remote/RNRemoteReadTask.cpp | 4 +- .../DeltaMerge/workload/MainEntry.cpp | 5 -- dbms/src/Storages/S3/FileCache.cpp | 8 +- .../src/Storages/S3/tests/gtest_filecache.cpp | 6 +- .../Storages/StorageDisaggregatedRemote.cpp | 2 +- dbms/src/Storages/Transaction/FastAddPeer.h | 2 +- dbms/src/TestUtils/gtests_dbms_main.cpp | 9 ++- 17 files changed, 161 insertions(+), 97 deletions(-) rename dbms/src/IO/{IOThreadPool.cpp => IOThreadPools.h} (50%) diff --git a/dbms/src/Common/UniThreadPool.cpp b/dbms/src/Common/UniThreadPool.cpp index 1056445ac69..96aa0848c71 100644 --- a/dbms/src/Common/UniThreadPool.cpp +++ b/dbms/src/Common/UniThreadPool.cpp @@ -337,7 +337,6 @@ void ThreadPoolImpl::worker(typename std::list::iterator thread_ } } - template class ThreadPoolImpl; template class ThreadPoolImpl>; template class ThreadFromGlobalPoolImpl; @@ -355,6 +354,11 @@ void GlobalThreadPool::initialize(size_t max_threads, size_t max_free_threads, s the_instance.reset(new GlobalThreadPool(max_threads, max_free_threads, queue_size, false /*shutdown_on_exception*/)); } +void GlobalThreadPool::registerFinalizer(std::function fn) +{ + finalize_fns.push_back(fn); +} + GlobalThreadPool & GlobalThreadPool::instance() { if (!the_instance) @@ -369,9 +373,8 @@ GlobalThreadPool & GlobalThreadPool::instance() GlobalThreadPool::~GlobalThreadPool() noexcept { - // We must make sure IOThread is released before GlobalThreadPool runs - // `finalize`. Or the threads in GlobalThreadPool never ends. - IOThreadPool::shutdown(); + for (auto & fn : finalize_fns) + fn(); } } // namespace DB diff --git a/dbms/src/Common/UniThreadPool.h b/dbms/src/Common/UniThreadPool.h index 10c817205e3..8f302dfcb05 100644 --- a/dbms/src/Common/UniThreadPool.h +++ b/dbms/src/Common/UniThreadPool.h @@ -161,9 +161,14 @@ class GlobalThreadPool : public FreeThreadPool : FreeThreadPool(max_threads_, max_free_threads_, queue_size_, shutdown_on_exception_) {} + std::vector> finalize_fns; + public: static void initialize(size_t max_threads = 10000, size_t max_free_threads = 1000, size_t queue_size = 10000); static GlobalThreadPool & instance(); + + void registerFinalizer(std::function); + ~GlobalThreadPool() noexcept; }; @@ -187,29 +192,30 @@ class ThreadFromGlobalPoolImpl : boost::noncopyable /// NOTE: /// - If this will throw an exception, the destructor won't be called /// - this pointer cannot be passed in the lambda, since after detach() it will not be valid - GlobalThreadPool::instance().scheduleOrThrow([state = state, - func = std::forward(func), - args = std::make_tuple(std::forward(args)...)]() mutable /// mutable is needed to destroy capture - { - SCOPE_EXIT( - state->thread_id = std::thread::id(); - state->event.set();); - - state->thread_id = std::this_thread::get_id(); - - /// This moves are needed to destroy function and arguments before exit. - /// It will guarantee that after ThreadFromGlobalPool::join all captured params are destroyed. - auto function = std::move(func); - auto arguments = std::move(args); - - /// Thread status holds raw pointer on query context, thus it always must be destroyed - /// before sending signal that permits to join this thread. - // DB::ThreadStatus thread_status; - std::apply(function, arguments); - }, - 0, // default priority - 0, // default wait_microseconds - propagate_opentelemetry_context); + GlobalThreadPool::instance().scheduleOrThrow( + [state = state, + func = std::forward(func), + args = std::make_tuple(std::forward(args)...)]() mutable /// mutable is needed to destroy capture + { + SCOPE_EXIT( + state->thread_id = std::thread::id(); + state->event.set();); + + state->thread_id = std::this_thread::get_id(); + + /// This moves are needed to destroy function and arguments before exit. + /// It will guarantee that after ThreadFromGlobalPool::join all captured params are destroyed. + auto function = std::move(func); + auto arguments = std::move(args); + + /// Thread status holds raw pointer on query context, thus it always must be destroyed + /// before sending signal that permits to join this thread. + // DB::ThreadStatus thread_status; + std::apply(function, arguments); + }, + 0, // default priority + 0, // default wait_microseconds + propagate_opentelemetry_context); } ThreadFromGlobalPoolImpl(ThreadFromGlobalPoolImpl && rhs) noexcept diff --git a/dbms/src/Flash/Disaggregated/RNPagePreparer.cpp b/dbms/src/Flash/Disaggregated/RNPagePreparer.cpp index e9db1ba5ab4..3934376b0c9 100644 --- a/dbms/src/Flash/Disaggregated/RNPagePreparer.cpp +++ b/dbms/src/Flash/Disaggregated/RNPagePreparer.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -65,7 +65,7 @@ RNPagePreparer::RNPagePreparer( }); persist_threads.emplace_back(task->get_future()); - IOThreadPool::get().scheduleOrThrowOnError([task] { (*task)(); }); + RNPagePreparerPool::get().scheduleOrThrowOnError([task] { (*task)(); }); } } catch (...) diff --git a/dbms/src/Flash/Disaggregated/RNPageReceiver.cpp b/dbms/src/Flash/Disaggregated/RNPageReceiver.cpp index 4739bb4c0e7..2f306c3c0a3 100644 --- a/dbms/src/Flash/Disaggregated/RNPageReceiver.cpp +++ b/dbms/src/Flash/Disaggregated/RNPageReceiver.cpp @@ -268,7 +268,7 @@ void RNPageReceiverBase::readLoop() // Keep popping segment fetch pages request to get the task ready while (!meet_error) { - auto req = rpc_context->popRequest(); + auto req = rpc_context->nextFetchPagesRequest(); if (!req.isValid()) break; try diff --git a/dbms/src/Flash/Disaggregated/RNPageReceiverContext.cpp b/dbms/src/Flash/Disaggregated/RNPageReceiverContext.cpp index eebbc5d2ef3..2cfb086631d 100644 --- a/dbms/src/Flash/Disaggregated/RNPageReceiverContext.cpp +++ b/dbms/src/Flash/Disaggregated/RNPageReceiverContext.cpp @@ -147,7 +147,7 @@ const String & FetchPagesRequest::address() const return seg_task->address; } -FetchPagesRequest GRPCPagesReceiverContext::popRequest() const +FetchPagesRequest GRPCPagesReceiverContext::nextFetchPagesRequest() const { auto seg_task = remote_read_tasks->nextFetchTask(); return FetchPagesRequest(std::move(seg_task)); diff --git a/dbms/src/Flash/Disaggregated/RNPageReceiverContext.h b/dbms/src/Flash/Disaggregated/RNPageReceiverContext.h index cb80b5a2566..03649b7126a 100644 --- a/dbms/src/Flash/Disaggregated/RNPageReceiverContext.h +++ b/dbms/src/Flash/Disaggregated/RNPageReceiverContext.h @@ -69,7 +69,7 @@ class GRPCPagesReceiverContext const DM::RNRemoteReadTaskPtr & remote_read_tasks, pingcap::kv::Cluster * cluster_); - FetchPagesRequest popRequest() const; + FetchPagesRequest nextFetchPagesRequest() const; FetchPagesResponseReaderPtr doRequest(const FetchPagesRequest & request) const; diff --git a/dbms/src/IO/IOThreadPool.h b/dbms/src/IO/IOThreadPool.h index ad323b23323..b8a8d021e40 100644 --- a/dbms/src/IO/IOThreadPool.h +++ b/dbms/src/IO/IOThreadPool.h @@ -14,24 +14,35 @@ #pragma once +#include #include namespace DB { struct Settings; -/* - * ThreadPool used for the IO. - */ +template class IOThreadPool { friend void adjustThreadPoolSize(const Settings & settings, size_t logical_cores); - static std::unique_ptr instance; + static inline std::unique_ptr instance; public: - static void initialize(size_t max_threads, size_t max_free_threads, size_t queue_size); - static ThreadPool & get(); + static void initialize(size_t max_threads, size_t max_free_threads, size_t queue_size) + { + RUNTIME_CHECK_MSG(!instance, "IO thread pool is initialized twice"); + instance = std::make_unique(max_threads, max_free_threads, queue_size, false /*shutdown_on_exception*/); + GlobalThreadPool::instance().registerFinalizer([] { + instance.reset(); + }); + } + + static ThreadPool & get() + { + RUNTIME_CHECK_MSG(instance, "IO thread pool is not initialized"); + return *instance; + } static void shutdown() noexcept { instance.reset(); } }; diff --git a/dbms/src/IO/IOThreadPool.cpp b/dbms/src/IO/IOThreadPools.h similarity index 50% rename from dbms/src/IO/IOThreadPool.cpp rename to dbms/src/IO/IOThreadPools.h index 761157546cf..5b68a444bfc 100644 --- a/dbms/src/IO/IOThreadPool.cpp +++ b/dbms/src/IO/IOThreadPools.h @@ -12,37 +12,39 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#pragma once + #include namespace DB { -namespace ErrorCodes +namespace io_pool_details { -extern const int LOGICAL_ERROR; -} -std::unique_ptr IOThreadPool::instance; +struct S3FileCacheTrait +{ +}; -void IOThreadPool::initialize(size_t max_threads, size_t max_free_threads, size_t queue_size) +struct DataStoreS3Trait { - if (instance) - { - throw Exception(ErrorCodes::LOGICAL_ERROR, "The IO thread pool is initialized twice"); - } +}; - instance = std::make_unique(max_threads, max_free_threads, queue_size, false /*shutdown_on_exception*/); -} +struct RemoteReadTaskTrait +{ +}; -ThreadPool & IOThreadPool::get() +struct RNPreparerTrait { - if (!instance) - { - throw Exception(ErrorCodes::LOGICAL_ERROR, "The IO thread pool is not initialized"); - } +}; + +} // namespace io_pool_details + +// TODO: Move these out. +using DataStoreS3Pool = IOThreadPool; +using S3FileCachePool = IOThreadPool; +using RNRemoteReadTaskPool = IOThreadPool; +using RNPagePreparerPool = IOThreadPool; - return *instance; -} } // namespace DB diff --git a/dbms/src/Server/Server.cpp b/dbms/src/Server/Server.cpp index 761f55755f1..fcbf8edda43 100644 --- a/dbms/src/Server/Server.cpp +++ b/dbms/src/Server/Server.cpp @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include #include @@ -797,32 +797,76 @@ class Server::TcpHttpServersHolder // By default init global thread pool by hardware_concurrency // Later we will adjust it by `adjustThreadPoolSize` -void initThreadPool() +void initThreadPool(Poco::Util::LayeredConfiguration & config) { size_t default_num_threads = std::max(4UL, 2 * std::thread::hardware_concurrency()); + + // Note: Global Thread Pool must be larger than sub thread pools. GlobalThreadPool::initialize( - /*max_threads*/ default_num_threads, - /*max_free_threads*/ default_num_threads / 2, - /*queue_size*/ default_num_threads * 2); - IOThreadPool::initialize( - /*max_threads*/ default_num_threads, - /*max_free_threads*/ default_num_threads / 2, - /*queue_size*/ default_num_threads * 2); + /*max_threads*/ default_num_threads * 20, + /*max_free_threads*/ default_num_threads, + /*queue_size*/ default_num_threads * 8); + + auto disaggregated_mode = getDisaggregatedMode(config); + if (disaggregated_mode == DisaggregatedMode::Compute) + { + RNPagePreparerPool::initialize( + /*max_threads*/ default_num_threads, + /*max_free_threads*/ default_num_threads / 2, + /*queue_size*/ default_num_threads * 2); + RNRemoteReadTaskPool::initialize( + /*max_threads*/ default_num_threads, + /*max_free_threads*/ default_num_threads / 2, + /*queue_size*/ default_num_threads * 2); + } + + if (disaggregated_mode == DisaggregatedMode::Compute || disaggregated_mode == DisaggregatedMode::Storage) + { + DataStoreS3Pool::initialize( + /*max_threads*/ default_num_threads, + /*max_free_threads*/ default_num_threads / 2, + /*queue_size*/ default_num_threads * 2); + S3FileCachePool::initialize( + /*max_threads*/ default_num_threads, + /*max_free_threads*/ default_num_threads / 2, + /*queue_size*/ default_num_threads * 2); + } } void adjustThreadPoolSize(const Settings & settings, size_t logical_cores) { // TODO: make BackgroundPool/BlockableBackgroundPool/DynamicThreadPool spawned from `GlobalThreadPool` size_t max_io_thread_count = std::ceil(settings.io_thread_count_scale * logical_cores); - // Currently, `GlobalThreadPool` is only used by `IOThreadPool`, so they have the same number of threads. - GlobalThreadPool::instance().setMaxThreads(max_io_thread_count); - GlobalThreadPool::instance().setMaxFreeThreads(max_io_thread_count / 2); - GlobalThreadPool::instance().setQueueSize(max_io_thread_count * 2); + // Note: Global Thread Pool must be larger than sub thread pools. + GlobalThreadPool::instance().setMaxThreads(max_io_thread_count * 20); + GlobalThreadPool::instance().setMaxFreeThreads(max_io_thread_count); + GlobalThreadPool::instance().setQueueSize(max_io_thread_count * 8); - IOThreadPool::instance->setMaxThreads(max_io_thread_count); - IOThreadPool::instance->setMaxFreeThreads(max_io_thread_count / 2); - IOThreadPool::instance->setQueueSize(max_io_thread_count * 2); + if (RNPagePreparerPool::instance) + { + RNPagePreparerPool::instance->setMaxThreads(max_io_thread_count); + RNPagePreparerPool::instance->setMaxFreeThreads(max_io_thread_count / 2); + RNPagePreparerPool::instance->setQueueSize(max_io_thread_count * 2); + } + if (RNRemoteReadTaskPool::instance) + { + RNRemoteReadTaskPool::instance->setMaxThreads(max_io_thread_count); + RNRemoteReadTaskPool::instance->setMaxFreeThreads(max_io_thread_count / 2); + RNRemoteReadTaskPool::instance->setQueueSize(max_io_thread_count * 2); + } + if (DataStoreS3Pool::instance) + { + DataStoreS3Pool::instance->setMaxThreads(max_io_thread_count); + DataStoreS3Pool::instance->setMaxFreeThreads(max_io_thread_count / 2); + DataStoreS3Pool::instance->setQueueSize(max_io_thread_count * 2); + } + if (S3FileCachePool::instance) + { + S3FileCachePool::instance->setMaxThreads(max_io_thread_count); + S3FileCachePool::instance->setMaxFreeThreads(max_io_thread_count / 2); + S3FileCachePool::instance->setQueueSize(max_io_thread_count * 2); + } } int Server::main(const std::vector & /*args*/) @@ -860,7 +904,7 @@ int Server::main(const std::vector & /*args*/) // Later we may create thread pool from GlobalThreadPool // init it before other components - initThreadPool(); + initThreadPool(config()); TiFlashErrorRegistry::instance(); // This invocation is for initializing diff --git a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp index 2e141d08186..be3ffbd87f3 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp +++ b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp @@ -13,7 +13,7 @@ // limitations under the License. #include -#include +#include #include #include #include @@ -54,7 +54,7 @@ void DataStoreS3::putDMFile(DMFilePtr local_dmfile, const S3::DMFileOID & oid, b S3::uploadFile(*s3_client, bucket, local_fname, remote_fname); }); upload_results.push_back(task->get_future()); - IOThreadPool::get().scheduleOrThrowOnError([task]() { (*task)(); }); + DataStoreS3Pool::get().scheduleOrThrowOnError([task]() { (*task)(); }); } for (auto & f : upload_results) { @@ -94,7 +94,7 @@ bool DataStoreS3::putCheckpointFiles(const PS::V3::LocalCheckpointFiles & local_ S3::uploadEmptyFile(*s3_client, bucket, lock_key); }); upload_results.push_back(task->get_future()); - IOThreadPool::get().scheduleOrThrowOnError([task] { (*task)(); }); + DataStoreS3Pool::get().scheduleOrThrowOnError([task] { (*task)(); }); } for (auto & f : upload_results) { @@ -125,7 +125,7 @@ void DataStoreS3::copyToLocal(const S3::DMFileOID & remote_oid, const std::vecto Poco::File(tmp_fname).renameTo(local_fname); }); results.push_back(task->get_future()); - IOThreadPool::get().scheduleOrThrowOnError([task]() { (*task)(); }); + DataStoreS3Pool::get().scheduleOrThrowOnError([task]() { (*task)(); }); } for (auto & f : results) { diff --git a/dbms/src/Storages/DeltaMerge/Remote/RNRemoteReadTask.cpp b/dbms/src/Storages/DeltaMerge/Remote/RNRemoteReadTask.cpp index c00b01165c6..1a934a56687 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/RNRemoteReadTask.cpp +++ b/dbms/src/Storages/DeltaMerge/Remote/RNRemoteReadTask.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -340,7 +340,7 @@ RNRemoteTableReadTaskPtr RNRemoteTableReadTask::buildFrom( }); futures.emplace_back(task->get_future()); - IOThreadPool::get().scheduleOrThrowOnError([task] { (*task)(); }); + RNRemoteReadTaskPool::get().scheduleOrThrowOnError([task] { (*task)(); }); } for (auto & f : futures) diff --git a/dbms/src/Storages/DeltaMerge/workload/MainEntry.cpp b/dbms/src/Storages/DeltaMerge/workload/MainEntry.cpp index 2d6620c2ebf..b34c28699bf 100644 --- a/dbms/src/Storages/DeltaMerge/workload/MainEntry.cpp +++ b/dbms/src/Storages/DeltaMerge/workload/MainEntry.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -69,10 +68,6 @@ void initThreadPool() /*max_threads*/ default_num_threads, /*max_free_threads*/ default_num_threads / 2, /*queue_size*/ default_num_threads * 2); - IOThreadPool::initialize( - /*max_threads*/ default_num_threads, - /*max_free_threads*/ default_num_threads / 2, - /*queue_size*/ default_num_threads * 2); } void initReadThread() diff --git a/dbms/src/Storages/S3/FileCache.cpp b/dbms/src/Storages/S3/FileCache.cpp index cdd7b072450..95bcb45e068 100644 --- a/dbms/src/Storages/S3/FileCache.cpp +++ b/dbms/src/Storages/S3/FileCache.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -304,7 +304,7 @@ bool FileCache::canCache(FileType file_type) const { return file_type != FileType::Unknow && static_cast(file_type) <= cache_level - && bg_downloading_count.load(std::memory_order_relaxed) < IOThreadPool::get().getMaxThreads(); + && bg_downloading_count.load(std::memory_order_relaxed) < S3FileCachePool::get().getMaxThreads(); } FileType FileCache::getFileTypeOfColData(const std::filesystem::path & p) @@ -452,7 +452,7 @@ void FileCache::bgDownload(const String & s3_key, FileSegmentPtr & file_seg) { bg_downloading_count.fetch_add(1, std::memory_order_relaxed); LOG_DEBUG(log, "downloading count {} => s3_key {} start", bg_downloading_count.load(std::memory_order_relaxed), s3_key); - IOThreadPool::get().scheduleOrThrowOnError( + S3FileCachePool::get().scheduleOrThrowOnError( [this, s3_key = s3_key, file_seg = file_seg]() mutable { download(s3_key, file_seg); }); @@ -599,4 +599,4 @@ void FileCache::updateConfig(Poco::Util::AbstractConfiguration & config_) } } -} // namespace DB \ No newline at end of file +} // namespace DB diff --git a/dbms/src/Storages/S3/tests/gtest_filecache.cpp b/dbms/src/Storages/S3/tests/gtest_filecache.cpp index 8d70d247f3b..81031c92b1a 100644 --- a/dbms/src/Storages/S3/tests/gtest_filecache.cpp +++ b/dbms/src/Storages/S3/tests/gtest_filecache.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include @@ -154,7 +154,7 @@ class FileCacheTest : public ::testing::Test writeFile(key, value, size, WriteSettings{}); }); upload_results.push_back(task->get_future()); - IOThreadPool::get().scheduleOrThrowOnError([task]() { (*task)(); }); + S3FileCachePool::get().scheduleOrThrowOnError([task]() { (*task)(); }); objects.emplace_back(ObjectInfo{.key = key, .value = value, .size = size}); } for (auto & f : upload_results) @@ -674,4 +674,4 @@ TEST_F(FileCacheTest, LRUFileTable) ASSERT_EQ(table.begin(), table.end()); } } -} // namespace DB::tests::S3 \ No newline at end of file +} // namespace DB::tests::S3 diff --git a/dbms/src/Storages/StorageDisaggregatedRemote.cpp b/dbms/src/Storages/StorageDisaggregatedRemote.cpp index adfe7343f10..156ad7b7308 100644 --- a/dbms/src/Storages/StorageDisaggregatedRemote.cpp +++ b/dbms/src/Storages/StorageDisaggregatedRemote.cpp @@ -62,7 +62,7 @@ struct RpcTypeTraits { using RequestType = disaggregated::EstablishDisaggTaskRequest; using ResultType = disaggregated::EstablishDisaggTaskResponse; - static const char * err_msg() { return "EstablishDisaggregatedTask Failed"; } // NOLINT(readability-identifier-naming) + static const char * err_msg() { return "EstablishDisaggTask Failed"; } // NOLINT(readability-identifier-naming) static ::grpc::Status doRPCCall( grpc::ClientContext * context, std::shared_ptr client, diff --git a/dbms/src/Storages/Transaction/FastAddPeer.h b/dbms/src/Storages/Transaction/FastAddPeer.h index 1afad1b6757..e59c5344df3 100644 --- a/dbms/src/Storages/Transaction/FastAddPeer.h +++ b/dbms/src/Storages/Transaction/FastAddPeer.h @@ -103,7 +103,7 @@ class FastAddPeerContext std::mutex range_cache_mu; - struct KeyComparator : public std::binary_function + struct KeyComparator { bool operator()(const DM::RowKeyValue & key1, const DM::RowKeyValue & key2) const { diff --git a/dbms/src/TestUtils/gtests_dbms_main.cpp b/dbms/src/TestUtils/gtests_dbms_main.cpp index 51a4b32462a..ad24ddb22b7 100644 --- a/dbms/src/TestUtils/gtests_dbms_main.cpp +++ b/dbms/src/TestUtils/gtests_dbms_main.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include @@ -77,8 +77,11 @@ int main(int argc, char ** argv) DB::tests::TiFlashTestEnv::getGlobalContext().getSettingsRef().dt_read_thread_count_scale); DB::DM::SegmentReadTaskScheduler::instance(); - DB::GlobalThreadPool::initialize(/*max_threads*/ 20, /*max_free_threds*/ 10, /*queue_size*/ 1000); - DB::IOThreadPool::initialize(/*max_threads*/ 20, /*max_free_threds*/ 10, /*queue_size*/ 1000); + DB::GlobalThreadPool::initialize(/*max_threads*/ 100, /*max_free_threds*/ 10, /*queue_size*/ 1000); + DB::S3FileCachePool::initialize(/*max_threads*/ 20, /*max_free_threds*/ 10, /*queue_size*/ 1000); + DB::DataStoreS3Pool::initialize(/*max_threads*/ 20, /*max_free_threds*/ 10, /*queue_size*/ 1000); + DB::RNRemoteReadTaskPool::initialize(/*max_threads*/ 20, /*max_free_threds*/ 10, /*queue_size*/ 1000); + DB::RNPagePreparerPool::initialize(/*max_threads*/ 20, /*max_free_threds*/ 10, /*queue_size*/ 1000); const auto s3_endpoint = Poco::Environment::get("S3_ENDPOINT", ""); const auto s3_bucket = Poco::Environment::get("S3_BUCKET", "mock_bucket"); const auto access_key_id = Poco::Environment::get("AWS_ACCESS_KEY_ID", ""); From 35e2f8dc3ed1d65cb4a6b61637aeb29823d132cf Mon Sep 17 00:00:00 2001 From: xufei Date: Wed, 15 Mar 2023 13:28:38 +0800 Subject: [PATCH 10/18] Add more spill tests and fix bug (#7073) ref pingcap/tiflash#6528 --- dbms/src/Columns/ColumnString.h | 15 +- dbms/src/Columns/IColumn.h | 2 + .../Flash/tests/gtest_spill_aggregation.cpp | 264 +++++++++++++++++- dbms/src/Flash/tests/gtest_spill_sort.cpp | 44 ++- dbms/src/Interpreters/Aggregator.cpp | 3 +- dbms/src/Interpreters/Aggregator.h | 24 +- dbms/src/TestUtils/mockExecutor.h | 1 + 7 files changed, 322 insertions(+), 31 deletions(-) diff --git a/dbms/src/Columns/ColumnString.h b/dbms/src/Columns/ColumnString.h index df40832142e..57eef31700b 100644 --- a/dbms/src/Columns/ColumnString.h +++ b/dbms/src/Columns/ColumnString.h @@ -249,20 +249,11 @@ class ColumnString final : public COWPtrHelper { const size_t string_size = *reinterpret_cast(pos); pos += sizeof(string_size); - - if (likely(collator)) - { - // https://github.com/pingcap/tiflash/pull/6135 - // - Generate empty string column - // - Make size of `offsets` as previous way for func `ColumnString::size()` - offsets.push_back(0); - return pos + string_size; - } + if (likely(collator != nullptr)) + insertData(pos, string_size); else - { insertDataWithTerminatingZero(pos, string_size); - return pos + string_size; - } + return pos + string_size; } void updateHashWithValue(size_t n, SipHash & hash, const TiDB::TiDBCollatorPtr & collator, String & sort_key_container) const override diff --git a/dbms/src/Columns/IColumn.h b/dbms/src/Columns/IColumn.h index 2d3762f40a9..f6a0be13f0f 100644 --- a/dbms/src/Columns/IColumn.h +++ b/dbms/src/Columns/IColumn.h @@ -201,6 +201,8 @@ class IColumn : public COWPtr * 2. The input parameter `collator` does not work well for complex columns(column tuple), * but it is only used by TiDB , which does not support complex columns, so just ignore * the complex column will be ok. + * 3. Even if the restored column will be discarded, deserializeAndInsertFromArena still need to + * insert the data because when spill happens, this column will be used during the merge agg stage. */ virtual const char * deserializeAndInsertFromArena(const char * pos, const TiDB::TiDBCollatorPtr & collator) = 0; const char * deserializeAndInsertFromArena(const char * pos) { return deserializeAndInsertFromArena(pos, nullptr); } diff --git a/dbms/src/Flash/tests/gtest_spill_aggregation.cpp b/dbms/src/Flash/tests/gtest_spill_aggregation.cpp index 42296055aec..417592a9353 100644 --- a/dbms/src/Flash/tests/gtest_spill_aggregation.cpp +++ b/dbms/src/Flash/tests/gtest_spill_aggregation.cpp @@ -21,7 +21,6 @@ namespace DB { namespace tests { - class SpillAggregationTestRunner : public DB::tests::ExecutorTest { public: @@ -96,5 +95,268 @@ try ASSERT_COLUMNS_EQ_UR(ref_columns, vstackBlocks(std::move(blocks)).getColumnsWithTypeAndName()); } CATCH + +TEST_F(SpillAggregationTestRunner, AggWithSpecialGroupKey) +try +{ + /// prepare data + size_t unique_rows = 3000; + DB::MockColumnInfoVec table_column_infos{{"key_8", TiDB::TP::TypeTiny, false}, {"key_16", TiDB::TP::TypeShort, false}, {"key_32", TiDB::TP::TypeLong, false}, {"key_64", TiDB::TP::TypeLongLong, false}, {"key_string_1", TiDB::TP::TypeString, false}, {"key_string_2", TiDB::TP::TypeString, false}, {"value", TiDB::TP::TypeLong, false}}; + ColumnsWithTypeAndName table_column_data; + for (const auto & column_info : mockColumnInfosToTiDBColumnInfos(table_column_infos)) + { + ColumnGeneratorOpts opts{unique_rows, getDataTypeByColumnInfoForComputingLayer(column_info)->getName(), RANDOM, column_info.name}; + table_column_data.push_back(ColumnGenerator::instance().generate(opts)); + } + for (auto & table_column : table_column_data) + { + if (table_column.name != "value") + table_column.column->assumeMutable()->insertRangeFrom(*table_column.column, 0, unique_rows / 2); + else + { + ColumnGeneratorOpts opts{unique_rows / 2, table_column.type->getName(), RANDOM, table_column.name}; + auto column = ColumnGenerator::instance().generate(opts); + table_column.column->assumeMutable()->insertRangeFrom(*column.column, 0, unique_rows / 2); + } + } + ColumnWithTypeAndName shuffle_column = ColumnGenerator::instance().generate({unique_rows + unique_rows / 2, "UInt64", RANDOM}); + IColumn::Permutation perm; + shuffle_column.column->getPermutation(false, 0, -1, perm); + for (auto & column : table_column_data) + { + column.column = column.column->permute(perm, 0); + } + + context.addMockTable("test_db", "agg_table_with_special_key", table_column_infos, table_column_data); + + size_t max_block_size = 800; + size_t max_bytes_before_external_agg = 100; + std::vector concurrences{1, 8}; + std::vector collators{TiDB::ITiDBCollator::UTF8MB4_BIN, TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI}; + std::vector> group_by_keys{ + /// fast path with one int and one string in bin collation + {"key_64", "key_string_1"}, + /// fast path with two string in bin collation + {"key_string_1", "key_string_2"}, + /// fast path with one string in bin collation + {"key_string_1"}, + /// keys need to be shuffled + {"key_8", "key_16", "key_32", "key_64"}, + }; + std::vector> agg_funcs{{Max(col("value"))}, {Max(col("value")), Min(col("value"))}}; + for (auto collator_id : collators) + { + for (const auto & keys : group_by_keys) + { + for (const auto & agg_func : agg_funcs) + { + context.setCollation(collator_id); + const auto * current_collator = TiDB::ITiDBCollator::getCollator(collator_id); + ASSERT_TRUE(current_collator != nullptr); + SortDescription sd; + bool has_string_key = false; + MockAstVec key_vec; + for (const auto & key : keys) + key_vec.push_back(col(key)); + auto request = context + .scan("test_db", "agg_table_with_special_key") + .aggregation(agg_func, key_vec) + .build(context); + /// use one level, no block split, no spill as the reference + context.context->setSetting("group_by_two_level_threshold_bytes", Field(static_cast(0))); + context.context->setSetting("max_bytes_before_external_group_by", Field(static_cast(0))); + context.context->setSetting("max_block_size", Field(static_cast(unique_rows * 2))); + /// here has to enable memory tracker otherwise the processList in the context is the last query's processList + /// and may cause segment fault, maybe a bug but should not happens in TiDB because all the tasks from tidb + /// enable memory tracker + auto reference = executeStreams(request, 1, true); + if (current_collator->isCI()) + { + /// for ci collation, need to sort and compare the result manually + for (const auto & result_col : reference) + { + if (!removeNullable(result_col.type)->isString()) + { + sd.push_back(SortColumnDescription(result_col.name, 1, 1, nullptr)); + } + else + { + sd.push_back(SortColumnDescription(result_col.name, 1, 1, current_collator)); + has_string_key = true; + } + } + /// don't run ci test if there is no string key + if (!has_string_key) + continue; + Block tmp_block(reference); + sortBlock(tmp_block, sd); + reference = tmp_block.getColumnsWithTypeAndName(); + } + for (auto concurrency : concurrences) + { + context.context->setSetting("group_by_two_level_threshold", Field(static_cast(1))); + context.context->setSetting("group_by_two_level_threshold_bytes", Field(static_cast(1))); + context.context->setSetting("max_bytes_before_external_group_by", Field(static_cast(max_bytes_before_external_agg))); + context.context->setSetting("max_block_size", Field(static_cast(max_block_size))); + auto blocks = getExecuteStreamsReturnBlocks(request, concurrency, true); + for (auto & block : blocks) + { + block.checkNumberOfRows(); + ASSERT(block.rows() <= max_block_size); + } + if (current_collator->isCI()) + { + auto merged_block = vstackBlocks(std::move(blocks)); + sortBlock(merged_block, sd); + auto merged_columns = merged_block.getColumnsWithTypeAndName(); + for (size_t col_index = 0; col_index < reference.size(); col_index++) + ASSERT_TRUE(columnEqual(reference[col_index].column, merged_columns[col_index].column, sd[col_index].collator)); + } + else + { + ASSERT_TRUE(columnsEqual(reference, vstackBlocks(std::move(blocks)).getColumnsWithTypeAndName(), false)); + } + } + } + } + } +} +CATCH + +TEST_F(SpillAggregationTestRunner, AggWithDistinctAggFunc) +try +{ + /// prepare data + size_t unique_rows = 3000; + DB::MockColumnInfoVec table_column_infos{ + {"key_8", TiDB::TP::TypeTiny, false}, + {"key_16", TiDB::TP::TypeShort, false}, + {"key_32", TiDB::TP::TypeLong, false}, + {"key_64", TiDB::TP::TypeLongLong, false}, + {"key_string_1", TiDB::TP::TypeString, false}, + {"key_string_2", TiDB::TP::TypeString, false}, + {"value_1", TiDB::TP::TypeString, false}, + {"value_2", TiDB::TP::TypeLong, false}, + }; + size_t key_column = 6; + ColumnsWithTypeAndName table_column_data; + for (const auto & column_info : mockColumnInfosToTiDBColumnInfos(table_column_infos)) + { + ColumnGeneratorOpts opts{unique_rows, getDataTypeByColumnInfoForComputingLayer(column_info)->getName(), RANDOM, column_info.name}; + table_column_data.push_back(ColumnGenerator::instance().generate(opts)); + } + for (size_t i = 0; i < key_column; i++) + table_column_data[i].column->assumeMutable()->insertRangeFrom(*table_column_data[i].column, 0, unique_rows / 2); + for (size_t i = key_column; i < table_column_data.size(); i++) + { + auto & table_column = table_column_data[i]; + ColumnGeneratorOpts opts{unique_rows / 2, table_column.type->getName(), RANDOM, table_column.name}; + auto column = ColumnGenerator::instance().generate(opts); + table_column.column->assumeMutable()->insertRangeFrom(*column.column, 0, unique_rows / 2); + } + + ColumnWithTypeAndName shuffle_column = ColumnGenerator::instance().generate({unique_rows + unique_rows / 2, "UInt64", RANDOM}); + IColumn::Permutation perm; + shuffle_column.column->getPermutation(false, 0, -1, perm); + for (auto & column : table_column_data) + { + column.column = column.column->permute(perm, 0); + } + + context.addMockTable("test_db", "agg_table_with_special_key", table_column_infos, table_column_data); + + size_t max_block_size = 800; + size_t max_bytes_before_external_agg = 100; + std::vector concurrences{1, 8}; + std::vector collators{TiDB::ITiDBCollator::UTF8MB4_BIN, TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI}; + std::vector> group_by_keys{ + /// fast path with one int and one string + {"key_64", "key_string_1"}, + /// fast path with two string + {"key_string_1", "key_string_2"}, + /// fast path with one string + {"key_string_1"}, + /// keys need to be shuffled + {"key_8", "key_16", "key_32", "key_64"}, + }; + std::vector> agg_funcs{{Max(col("value_1")), CountDistinct(col("value_2"))}, {CountDistinct(col("value_1")), CountDistinct(col("value_2"))}, {CountDistinct(col("value_1"))}}; + for (auto collator_id : collators) + { + for (const auto & keys : group_by_keys) + { + for (const auto & agg_func : agg_funcs) + { + context.setCollation(collator_id); + const auto * current_collator = TiDB::ITiDBCollator::getCollator(collator_id); + ASSERT_TRUE(current_collator != nullptr); + SortDescription sd; + bool has_string_key = false; + MockAstVec key_vec; + for (const auto & key : keys) + key_vec.push_back(col(key)); + auto request = context + .scan("test_db", "agg_table_with_special_key") + .aggregation(agg_func, key_vec) + .build(context); + /// use one level, no block split, no spill as the reference + context.context->setSetting("group_by_two_level_threshold_bytes", Field(static_cast(0))); + context.context->setSetting("max_bytes_before_external_group_by", Field(static_cast(0))); + context.context->setSetting("max_block_size", Field(static_cast(unique_rows * 2))); + /// here has to enable memory tracker otherwise the processList in the context is the last query's processList + /// and may cause segment fault, maybe a bug but should not happens in TiDB because all the tasks from tidb + /// enable memory tracker + auto reference = executeStreams(request, 1, true); + if (current_collator->isCI()) + { + /// for ci collation, need to sort and compare the result manually + for (const auto & result_col : reference) + { + if (!removeNullable(result_col.type)->isString()) + { + sd.push_back(SortColumnDescription(result_col.name, 1, 1, nullptr)); + } + else + { + sd.push_back(SortColumnDescription(result_col.name, 1, 1, current_collator)); + has_string_key = true; + } + } + /// don't run ci test if there is no string key + if (!has_string_key) + continue; + Block tmp_block(reference); + sortBlock(tmp_block, sd); + reference = tmp_block.getColumnsWithTypeAndName(); + } + for (auto concurrency : concurrences) + { + context.context->setSetting("group_by_two_level_threshold", Field(static_cast(1))); + context.context->setSetting("group_by_two_level_threshold_bytes", Field(static_cast(1))); + context.context->setSetting("max_bytes_before_external_group_by", Field(static_cast(max_bytes_before_external_agg))); + context.context->setSetting("max_block_size", Field(static_cast(max_block_size))); + auto blocks = getExecuteStreamsReturnBlocks(request, concurrency, true); + for (auto & block : blocks) + { + block.checkNumberOfRows(); + ASSERT(block.rows() <= max_block_size); + } + if (current_collator->isCI()) + { + auto merged_block = vstackBlocks(std::move(blocks)); + sortBlock(merged_block, sd); + auto merged_columns = merged_block.getColumnsWithTypeAndName(); + for (size_t col_index = 0; col_index < reference.size(); col_index++) + ASSERT_TRUE(columnEqual(reference[col_index].column, merged_columns[col_index].column, sd[col_index].collator)); + } + else + { + ASSERT_TRUE(columnsEqual(reference, vstackBlocks(std::move(blocks)).getColumnsWithTypeAndName(), false)); + } + } + } + } + } +} +CATCH } // namespace tests } // namespace DB diff --git a/dbms/src/Flash/tests/gtest_spill_sort.cpp b/dbms/src/Flash/tests/gtest_spill_sort.cpp index 4061ddf000c..95a910f4f83 100644 --- a/dbms/src/Flash/tests/gtest_spill_sort.cpp +++ b/dbms/src/Flash/tests/gtest_spill_sort.cpp @@ -21,7 +21,6 @@ namespace DB { namespace tests { - class SpillSortTestRunner : public DB::tests::ExecutorTest { public: @@ -70,5 +69,48 @@ try ASSERT_COLUMNS_EQ_UR(ref_columns, executeStreams(request, original_max_streams)); } CATCH + +TEST_F(SpillSortTestRunner, CollatorTest) +try +{ + DB::MockColumnInfoVec column_infos{{"a", TiDB::TP::TypeString, false}, {"b", TiDB::TP::TypeString, false}, {"c", TiDB::TP::TypeString, false}, {"d", TiDB::TP::TypeString, false}, {"e", TiDB::TP::TypeString, false}}; + ColumnsWithTypeAndName column_data; + size_t table_rows = 102400; + UInt64 max_block_size = 500; + size_t original_max_streams = 20; + size_t total_data_size = 0; + size_t limit_size = table_rows / 10 * 8; + for (const auto & column_info : mockColumnInfosToTiDBColumnInfos(column_infos)) + { + ColumnGeneratorOpts opts{table_rows, getDataTypeByColumnInfoForComputingLayer(column_info)->getName(), RANDOM, column_info.name, 5}; + column_data.push_back(ColumnGenerator::instance().generate(opts)); + total_data_size += column_data.back().column->byteSize(); + } + context.addMockTable("spill_sort_test", "collation_table", column_infos, column_data, 8); + + MockOrderByItemVec order_by_items{std::make_pair("a", true), std::make_pair("b", true), std::make_pair("c", true), std::make_pair("d", true), std::make_pair("e", true)}; + std::vector collators{TiDB::ITiDBCollator::UTF8MB4_BIN, TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI, TiDB::ITiDBCollator::UTF8MB4_UNICODE_CI}; + for (const auto & collator_id : collators) + { + context.setCollation(collator_id); + auto request = context + .scan("spill_sort_test", "collation_table") + .topN(order_by_items, limit_size) + .build(context); + context.context->setSetting("max_block_size", Field(static_cast(max_block_size))); + /// disable spill + context.context->setSetting("max_bytes_before_external_sort", Field(static_cast(0))); + auto ref_columns = executeStreams(request, original_max_streams); + /// enable spill + context.context->setSetting("max_bytes_before_external_sort", Field(static_cast(total_data_size / 10))); + // don't use `executeAndAssertColumnsEqual` since it takes too long to run + /// todo use ASSERT_COLUMNS_EQ_R once TiFlash support final TopN + ASSERT_COLUMNS_EQ_UR(ref_columns, executeStreams(request, original_max_streams)); + /// enable spill and use small max_cached_data_bytes_in_spiller + context.context->setSetting("max_cached_data_bytes_in_spiller", Field(static_cast(total_data_size / 100))); + ASSERT_COLUMNS_EQ_UR(ref_columns, executeStreams(request, original_max_streams)); + } +} +CATCH } // namespace tests } // namespace DB diff --git a/dbms/src/Interpreters/Aggregator.cpp b/dbms/src/Interpreters/Aggregator.cpp index c0b4d58a017..50d8a9c7e73 100644 --- a/dbms/src/Interpreters/Aggregator.cpp +++ b/dbms/src/Interpreters/Aggregator.cpp @@ -1766,7 +1766,8 @@ void NO_INLINE Aggregator::mergeStreamsImplCase( std::vector sort_key_containers; sort_key_containers.resize(params.keys_size, ""); - typename Method::State state(key_columns, key_sizes, params.collators); + /// in merge stage, don't need to care about the collator because the key is already the sort_key of original string + typename Method::State state(key_columns, key_sizes, {}); /// For all rows. size_t rows = block.rows(); diff --git a/dbms/src/Interpreters/Aggregator.h b/dbms/src/Interpreters/Aggregator.h index f8189dd2278..674dbf98887 100644 --- a/dbms/src/Interpreters/Aggregator.h +++ b/dbms/src/Interpreters/Aggregator.h @@ -220,15 +220,12 @@ struct AggregationMethodOneKeyStringNoCache std::optional shuffleKeyColumns(std::vector &, const Sizes &) { return {}; } - ALWAYS_INLINE static inline void insertKeyIntoColumns(const StringRef &, std::vector &, size_t) + ALWAYS_INLINE static inline void insertKeyIntoColumns(const StringRef & key, std::vector & key_columns, size_t) { - // insert empty because such column will be discarded. - } - // resize offsets for column string - ALWAYS_INLINE static inline void initAggKeys(size_t rows, IColumn * key_column) - { - static_cast(key_column)->getOffsets().resize_fill(rows, 0); + /// still need to insert data to key because spill may will use this + static_cast(key_columns[0])->insertData(key.data, key.size); } + ALWAYS_INLINE static inline void initAggKeys(size_t, IColumn *) {} }; /* @@ -289,20 +286,15 @@ struct AggregationMethodFastPathTwoKeysNoCache column->getData().resize_fill(rows, 0); } - // Only update offsets but DO NOT insert string data. - // Because of https://github.com/pingcap/tiflash/blob/84c2650bc4320919b954babeceb5aeaadb845770/dbms/src/Columns/IColumn.h#L160-L173, such column will be discarded. - ALWAYS_INLINE static inline const char * insertAggKeyIntoColumnString(const char * pos, IColumn *) + ALWAYS_INLINE static inline const char * insertAggKeyIntoColumnString(const char * pos, IColumn * key_column) { + /// still need to insert data to key because spill may will use this const size_t string_size = *reinterpret_cast(pos); pos += sizeof(string_size); + static_cast(key_column)->insertData(pos, string_size); return pos + string_size; } - // resize offsets for column string - ALWAYS_INLINE static inline void initAggKeyString(size_t rows, IColumn * key_column) - { - auto * column = static_cast(key_column); - column->getOffsets().resize_fill(rows, 0); - } + ALWAYS_INLINE static inline void initAggKeyString(size_t, IColumn *) {} template <> ALWAYS_INLINE static inline void initAggKeys(size_t rows, IColumn * key_column) diff --git a/dbms/src/TestUtils/mockExecutor.h b/dbms/src/TestUtils/mockExecutor.h index b3fb5d522c8..0b18bd3b54f 100644 --- a/dbms/src/TestUtils/mockExecutor.h +++ b/dbms/src/TestUtils/mockExecutor.h @@ -261,6 +261,7 @@ MockWindowFrame buildDefaultRowsFrame(); #define Min(expr) makeASTFunction("min", (expr)) #define Count(expr) makeASTFunction("count", (expr)) #define Sum(expr) makeASTFunction("sum", (expr)) +#define CountDistinct(expr) makeASTFunction("countDistinct", (expr)) /// Window functions #define RowNumber() makeASTFunction("RowNumber") From 3f88d4a3de295342c5ff92718e04991889804757 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Wed, 15 Mar 2023 14:12:38 +0800 Subject: [PATCH 11/18] Fix ilike function (#6950) close pingcap/tiflash#6949 --- dbms/src/Common/StringUtils/StringUtils.h | 5 + dbms/src/Functions/FunctionsStringSearch.h | 151 ++++++++++++++---- .../Functions/tests/gtest_strings_search.cpp | 129 +++++++++++++++ 3 files changed, 254 insertions(+), 31 deletions(-) diff --git a/dbms/src/Common/StringUtils/StringUtils.h b/dbms/src/Common/StringUtils/StringUtils.h index 689b940a9e5..be1c94ab657 100644 --- a/dbms/src/Common/StringUtils/StringUtils.h +++ b/dbms/src/Common/StringUtils/StringUtils.h @@ -93,6 +93,11 @@ inline bool isUpperAlphaASCII(char c) return (c >= 'A' && c <= 'Z'); } +inline bool isLowerAplhaASCII(char c) +{ + return (c >= 'a' && c <= 'z'); +} + inline bool isAlphaASCII(char c) { return (c >= 'a' && c <= 'z') diff --git a/dbms/src/Functions/FunctionsStringSearch.h b/dbms/src/Functions/FunctionsStringSearch.h index dc9bccd10f6..a023142bbb9 100644 --- a/dbms/src/Functions/FunctionsStringSearch.h +++ b/dbms/src/Functions/FunctionsStringSearch.h @@ -36,61 +36,149 @@ namespace DB using Chars_t = ColumnString::Chars_t; using Offsets = ColumnString::Offsets; -struct IlikeHelper +class IlikeLowerHelper { +public: + static void convertCollatorToBin(TiDB::TiDBCollatorPtr & collator) + { + if (collator == nullptr) + return; + + switch (collator->getCollatorType()) + { + case TiDB::ITiDBCollator::CollatorType::UTF8_GENERAL_CI: + case TiDB::ITiDBCollator::CollatorType::UTF8_UNICODE_CI: + collator = TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8_BIN); + break; + case TiDB::ITiDBCollator::CollatorType::UTF8MB4_GENERAL_CI: + case TiDB::ITiDBCollator::CollatorType::UTF8MB4_UNICODE_CI: + collator = TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_BIN); + break; + default: + break; + } + } + + // Only lower 'A', 'B', 'C'... 'Z', excluding the escape char + static void lowerAlphaASCII(Block & block, const ColumnNumbers & arguments) + { + MutableColumnPtr column_expr = block.getByPosition(arguments[0]).column->assumeMutable(); + MutableColumnPtr column_pat = block.getByPosition(arguments[1]).column->assumeMutable(); + const ColumnPtr & column_escape = block.getByPosition(arguments[2]).column; + + auto * col_haystack_const = typeid_cast(&*column_expr); + auto * col_needle_const = typeid_cast(&*column_pat); + + if (col_haystack_const != nullptr) + lowerColumnConst(col_haystack_const, nullptr); + else + lowerColumnString(column_expr, nullptr); + + if (col_needle_const != nullptr) + lowerColumnConst(col_needle_const, column_escape); + else + lowerColumnString(column_pat, column_escape); + } + +private: static void lowerStrings(Chars_t & chars) { size_t size = chars.size(); - size_t i = 0; - while (i < size) + for (size_t i = 0; i < size; ++i) { if (isUpperAlphaASCII(chars[i])) { chars[i] = toLowerIfAlphaASCII(chars[i]); - ++i; } else { size_t utf8_len = UTF8::seqLength(chars[i]); - i += utf8_len; + i += utf8_len - 1; } } } - static void lowerColumnConst(ColumnConst * lowered_col_const) + // When escape_char is a lower char, we need to convert it to the capital char + // Because: when lowering "ABC" with escape 'a', after lower, "ABC" -> "abc", + // then 'a' will be an escape char and it is not expected. + // Morever, when escape char is uppered we need to tell it to the caller. + static void lowerStringsExcludeEscapeChar(Chars_t & chars, char escape_char) + { + if (!isAlphaASCII(escape_char)) + { + lowerStrings(chars); + return; + } + + size_t size = chars.size(); + bool escaped = false; + char actual_escape_char = isLowerAplhaASCII(escape_char) ? toUpperIfAlphaASCII(escape_char) : escape_char; + + for (size_t i = 0; i < size; ++i) + { + char char_to_lower = chars[i]; + if (isUpperAlphaASCII(char_to_lower)) + { + // Do not lower the escape char, however when a char is equal to + // an escape char and it's after an escape char, we still lower it + // For example: "AA" (escape 'A'), -> "Aa" + if (char_to_lower != escape_char || escaped) + { + chars[i] = toLowerIfAlphaASCII(char_to_lower); + } + else + { + escaped = true; + continue; + } + } + else + { + if ((chars[i] == static_cast(escape_char)) && !escaped) + { + escaped = true; + + // It should be `chars[i] = toUpperIfAlphaASCII(chars[i])`, + // but 'actual_escape_char' is always equal to 'toUpperIfAlphaASCII(str[i])' + chars[i] = actual_escape_char; + continue; + } + size_t utf8_len = UTF8::seqLength(char_to_lower); + i += utf8_len - 1; + } + escaped = false; + } + } + + static void lowerColumnConst(ColumnConst * lowered_col_const, const ColumnPtr & column_escape) { auto * col_data = typeid_cast(&lowered_col_const->getDataColumn()); RUNTIME_ASSERT(col_data != nullptr, "Invalid column type, should be ColumnString"); - lowerStrings(col_data->getChars()); + lowerColumnStringImpl(col_data, column_escape); } - static void lowerColumnString(MutableColumnPtr & col) + static void lowerColumnString(MutableColumnPtr & col, const ColumnPtr & column_escape) { auto * col_vector = typeid_cast(&*col); RUNTIME_ASSERT(col_vector != nullptr, "Invalid column type, should be ColumnString"); - lowerStrings(col_vector->getChars()); + lowerColumnStringImpl(col_vector, column_escape); } - // Only lower the 'A', 'B', 'C'... - static void lowerAlphaASCII(Block & block, const ColumnNumbers & arguments) + static void lowerColumnStringImpl(ColumnString * lowered_col_data, const ColumnPtr & column_escape) { - MutableColumnPtr column_haystack = block.getByPosition(arguments[0]).column->assumeMutable(); - MutableColumnPtr column_needle = block.getByPosition(arguments[1]).column->assumeMutable(); + if (column_escape == nullptr) + { + lowerStrings(lowered_col_data->getChars()); + return; + } - auto * col_haystack_const = typeid_cast(&*column_haystack); - auto * col_needle_const = typeid_cast(&*column_needle); + const auto * col_escape_const = typeid_cast(&*column_escape); + RUNTIME_CHECK_MSG(col_escape_const != nullptr, "escape char column should be constant"); + char escape_char = static_cast(col_escape_const->getValue()); - if (col_haystack_const != nullptr) - lowerColumnConst(col_haystack_const); - else - lowerColumnString(column_haystack); - - if (col_needle_const != nullptr) - lowerColumnConst(col_needle_const); - else - lowerColumnString(column_needle); + lowerStringsExcludeEscapeChar(lowered_col_data->getChars(), escape_char); } }; @@ -197,13 +285,11 @@ class FunctionsStringSearch : public IFunction auto block = result_block; if constexpr (name == std::string_view(NameIlike3Args::name)) { - if (!collator->isCI()) - { - block.getByPosition(arguments[0]).column = (*std::move(result_block.getByPosition(arguments[0]).column)).mutate(); - block.getByPosition(arguments[1]).column = (*std::move(result_block.getByPosition(arguments[1]).column)).mutate(); + block.getByPosition(arguments[0]).column = (*std::move(result_block.getByPosition(arguments[0]).column)).mutate(); + block.getByPosition(arguments[1]).column = (*std::move(result_block.getByPosition(arguments[1]).column)).mutate(); - IlikeHelper::lowerAlphaASCII(block, arguments); - } + IlikeLowerHelper::lowerAlphaASCII(block, arguments); + IlikeLowerHelper::convertCollatorToBin(collator); } using ResultType = typename Impl::ResultType; @@ -235,6 +321,9 @@ class FunctionsStringSearch : public IFunction else { escape_char = static_cast(c); + if constexpr (name == std::string_view(NameIlike3Args::name)) + if (isLowerAplhaASCII(escape_char)) + escape_char = toUpperIfAlphaASCII(escape_char); } } if (!valid_args) @@ -302,7 +391,7 @@ class FunctionsStringSearch : public IFunction } private: - TiDB::TiDBCollatorPtr collator = nullptr; + mutable TiDB::TiDBCollatorPtr collator = nullptr; }; diff --git a/dbms/src/Functions/tests/gtest_strings_search.cpp b/dbms/src/Functions/tests/gtest_strings_search.cpp index 51560cf701a..1ac17f3bb62 100644 --- a/dbms/src/Functions/tests/gtest_strings_search.cpp +++ b/dbms/src/Functions/tests/gtest_strings_search.cpp @@ -17,6 +17,8 @@ #include #include +#include "magic_enum.hpp" + namespace DB { namespace tests @@ -668,6 +670,133 @@ TEST_F(StringMatch, IlikeConstWithConst) } } +TEST_F(StringMatch, CheckEscape) +{ + std::vector collators{ + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8_GENERAL_CI), + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_GENERAL_CI), + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8_UNICODE_CI), + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_UNICODE_CI), + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8MB4_BIN), + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::LATIN1_BIN), + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::BINARY), + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::ASCII_BIN), + TiDB::ITiDBCollator::getCollator(TiDB::ITiDBCollator::UTF8_BIN)}; + + std::vector> expr_vec{"", "aaz", "aaz", "AAz", "aAz", "a啊啊啊aa啊Zz", "ü", "á"}; + std::vector> pat_vec{"", "AAAAz", "Aaaz", "AAAAZ", "aAaAz", "a啊啊啊AaaA啊Zz", "Ü", "a"}; + std::vector> vec_vec_lower_a_expect = {1, 0, 1, 0, 1, 0, 0, 0}; // escape 'a' + std::vector> vec_vec_capital_a_expect = {1, 1, 1, 1, 1, 1, 0, 0}; // escape 'A' + ColumnWithTypeAndName escape_lower_a = createConstColumn(1, static_cast('a')); + ColumnWithTypeAndName escape_capital_a = createConstColumn(1, static_cast('A')); + + for (const auto * collator : collators) + { + // vec vec + ASSERT_COLUMN_EQ( + toNullableVec(vec_vec_lower_a_expect), + executeFunction( + "ilike3Args", + {toNullableVec(expr_vec), toNullableVec(pat_vec), escape_lower_a}, + collator)); + + ASSERT_COLUMN_EQ( + toNullableVec(vec_vec_capital_a_expect), + executeFunction( + "ilike3Args", + {toNullableVec(expr_vec), toNullableVec(pat_vec), escape_capital_a}, + collator)); + + // const const + ASSERT_COLUMN_EQ( + toConst(0), + executeFunction( + "ilike3Args", + {toConst("aa"), toConst("aa"), escape_lower_a}, + collator)); + + ASSERT_COLUMN_EQ( + toConst(1), + executeFunction( + "ilike3Args", + {toConst("aa"), toConst("aa"), escape_capital_a}, + collator)); + + ASSERT_COLUMN_EQ( + toConst(1), + executeFunction( + "ilike3Args", + {toConst("Aa"), toConst("aaA"), escape_lower_a}, + collator)); + + ASSERT_COLUMN_EQ( + toConst(0), + executeFunction( + "ilike3Args", + {toConst("Aa"), toConst("aaA"), escape_capital_a}, + collator)); + + ASSERT_COLUMN_EQ( + toConst(0), + executeFunction( + "ilike3Args", + {toConst("a啊啊a"), toConst("a啊啊A"), escape_lower_a}, + collator)); + + ASSERT_COLUMN_EQ( + toConst(0), + executeFunction( + "ilike3Args", + {toConst("a啊啊a"), toConst("A啊啊a"), escape_capital_a}, + collator)); + + ASSERT_COLUMN_EQ( + toConst(0), + executeFunction( + "ilike3Args", + {toConst("ü"), toConst("Ü"), escape}, + collator)); + + ASSERT_COLUMN_EQ( + toConst(0), + executeFunction( + "ilike3Args", + {toConst("a"), toConst("á"), escape}, + collator)); + + // vec const + ASSERT_COLUMN_EQ( + toNullableVec({0, 1, 1, 1, 1, 0, 0, 0}), + executeFunction( + "ilike3Args", + {toNullableVec(expr_vec), toConst("Aaaz"), escape_lower_a}, + collator)); + + ASSERT_COLUMN_EQ( + toNullableVec({0, 1, 1, 1, 1, 0, 0, 0}), + executeFunction( + "ilike3Args", + {toNullableVec(expr_vec), toConst("aAaZ"), escape_capital_a}, + collator)); + + // const vec + // "", "AAAAz", "Aaaz", "AAAAZ", "aAaAz", "a啊啊啊AaaA啊Zz", "Ü", "a"}; + ASSERT_COLUMN_EQ( + toNullableVec({0, 0, 1, 0, 1, 0, 0, 0}), + executeFunction( + "ilike3Args", + {toConst("aAz"), toNullableVec(pat_vec), escape_lower_a}, + collator)); + + ASSERT_COLUMN_EQ( + toNullableVec({0, 1, 1, 1, 1, 0, 0, 0}), + executeFunction( + "ilike3Args", + {toConst("AaZ"), toNullableVec(pat_vec), escape_capital_a}, + collator)); + } +} + // ilike function will modify the column's content in-place, in order to // ensure the column's content is not modified after function finishes the work, // we need to replace the modified columns with other columns which clone the From 38198e7986240caee7b2f6d556b76bbd73e68f2b Mon Sep 17 00:00:00 2001 From: JaySon Date: Wed, 15 Mar 2023 18:24:39 +0800 Subject: [PATCH 12/18] Simplify the config for disagg deployment (#7068) ref pingcap/tiflash#6827, ref pingcap/tidb#42190 --- dbms/src/Core/TiFlashDisaggregatedMode.cpp | 6 +- dbms/src/Core/TiFlashDisaggregatedMode.h | 1 + dbms/src/Interpreters/SharedContexts/Disagg.h | 3 +- dbms/src/Server/Server.cpp | 20 +++++- etc/config-template.toml | 6 +- tests/docker/config/tiflash_dt.toml | 66 ------------------- 6 files changed, 28 insertions(+), 74 deletions(-) diff --git a/dbms/src/Core/TiFlashDisaggregatedMode.cpp b/dbms/src/Core/TiFlashDisaggregatedMode.cpp index 2dd17703c7a..856d62e3ca2 100644 --- a/dbms/src/Core/TiFlashDisaggregatedMode.cpp +++ b/dbms/src/Core/TiFlashDisaggregatedMode.cpp @@ -24,7 +24,9 @@ DisaggregatedMode getDisaggregatedMode(const Poco::Util::LayeredConfiguration & if (config.has(config_key)) { std::string mode_str = config.getString(config_key); - RUNTIME_ASSERT(mode_str == DISAGGREGATED_MODE_WRITE || mode_str == DISAGGREGATED_MODE_COMPUTE, + RUNTIME_ASSERT(mode_str == DISAGGREGATED_MODE_WRITE + || mode_str == DISAGGREGATED_MODE_STORAGE // backward compatibility + || mode_str == DISAGGREGATED_MODE_COMPUTE, "Expect disaggregated_mode is {} or {}, got: {}", DISAGGREGATED_MODE_WRITE, DISAGGREGATED_MODE_COMPUTE, @@ -45,7 +47,7 @@ DisaggregatedMode getDisaggregatedMode(const Poco::Util::LayeredConfiguration & bool useAutoScaler(const Poco::Util::LayeredConfiguration & config) { static const std::string autoscaler_config_key = "flash.use_autoscaler"; - bool use_autoscaler = true; + bool use_autoscaler = false; if (config.has(autoscaler_config_key)) use_autoscaler = config.getBool(autoscaler_config_key); return use_autoscaler; diff --git a/dbms/src/Core/TiFlashDisaggregatedMode.h b/dbms/src/Core/TiFlashDisaggregatedMode.h index c79743016a4..5e12ff38cd3 100644 --- a/dbms/src/Core/TiFlashDisaggregatedMode.h +++ b/dbms/src/Core/TiFlashDisaggregatedMode.h @@ -23,6 +23,7 @@ // Note that TiFlash Write Node is also named as TiFlash Storage Node in many places. // To make sure it is consistent to our documents, we better stick with "tiflash_write" in the configurations. #define DISAGGREGATED_MODE_WRITE "tiflash_write" +#define DISAGGREGATED_MODE_STORAGE "tiflash_storage" // backward compatibility just for parsing config #define DISAGGREGATED_MODE_COMPUTE "tiflash_compute" // engine_role determine whether TiFlash use S3 to write. #define DISAGGREGATED_MODE_WRITE_ENGINE_ROLE "write" diff --git a/dbms/src/Interpreters/SharedContexts/Disagg.h b/dbms/src/Interpreters/SharedContexts/Disagg.h index f809cbefe17..acc3354914d 100644 --- a/dbms/src/Interpreters/SharedContexts/Disagg.h +++ b/dbms/src/Interpreters/SharedContexts/Disagg.h @@ -47,7 +47,8 @@ struct SharedContextDisagg : private boost::noncopyable DisaggregatedMode disaggregated_mode = DisaggregatedMode::None; - bool use_autoscaler = true; // TODO: remove this after AutoScaler is stable. Only meaningful in DisaggregatedComputeMode. + // Only meaningful in DisaggregatedComputeMode. + bool use_autoscaler = false; /// For both read node (downloading) and write node (uploading). DM::Remote::IDataStorePtr remote_data_store; diff --git a/dbms/src/Server/Server.cpp b/dbms/src/Server/Server.cpp index fcbf8edda43..464c8ccadb4 100644 --- a/dbms/src/Server/Server.cpp +++ b/dbms/src/Server/Server.cpp @@ -915,14 +915,30 @@ int Server::main(const std::vector & /*args*/) // "0" by default, means no quota, the actual disk capacity is used. size_t global_capacity_quota = 0; std::tie(global_capacity_quota, storage_config) = TiFlashStorageConfig::parseSettings(config(), log); - if (storage_config.format_version) + if (storage_config.format_version != 0) { + if (storage_config.s3_config.isS3Enabled() && storage_config.format_version != STORAGE_FORMAT_V5.identifier) + { + LOG_WARNING(log, "'storage.format_version' must be set to 5 when S3 is enabled!"); + throw Exception("'storage.format_version' must be set to 5 when S3 is enabled!"); + } setStorageFormat(storage_config.format_version); LOG_INFO(log, "Using format_version={} (explicit storage format detected).", storage_config.format_version); } else { - LOG_INFO(log, "Using format_version={} (default settings).", STORAGE_FORMAT_CURRENT.identifier); + if (storage_config.s3_config.isS3Enabled()) + { + // If the user does not explicitly set format_version in the config file but + // enables S3, then we set up a proper format version to support S3. + setStorageFormat(5); + LOG_INFO(log, "Using format_version={} (infer by S3 is enabled).", STORAGE_FORMAT_V5.identifier); + } + else + { + // Use the default settings + LOG_INFO(log, "Using format_version={} (default settings).", STORAGE_FORMAT_CURRENT.identifier); + } } LOG_INFO(log, "Using api_version={}", storage_config.api_version); diff --git a/etc/config-template.toml b/etc/config-template.toml index a717491ec9a..4f8ae3763b3 100644 --- a/etc/config-template.toml +++ b/etc/config-template.toml @@ -107,9 +107,9 @@ # read_index_runner_count = 1 ## The minimum duration to handle read-index tasks in each worker. # read_index_worker_tick_ms = 10 -# disaggregated_mode = "tiflash_storage" or "tiflash_compute" -## Means whether we use AutoScaler or PD for tiflash_compute nodes. Default use AutoScaler. Will remove this after AutoScaler is stable. -# use_autoscaler = true +# disaggregated_mode = "tiflash_write" or "tiflash_compute" +## Means whether we use AutoScaler or PD for tiflash_compute nodes. Default is false. +# use_autoscaler = false [flash.proxy] # addr = "0.0.0.0:20170" diff --git a/tests/docker/config/tiflash_dt.toml b/tests/docker/config/tiflash_dt.toml index 14c7bb1c400..775105dbbc9 100644 --- a/tests/docker/config/tiflash_dt.toml +++ b/tests/docker/config/tiflash_dt.toml @@ -13,71 +13,15 @@ # limitations under the License. tmp_path = "/tmp/tiflash/data/tmp" -display_name = "TiFlash" -## Deprecated storage path setting style. Check [storage] section for new style. path = "/tmp/tiflash/data/db" capacity = "10737418240" -## Deprecated storage path setting style of multi-disks. Check [storage] section for new style. -# path = "/tmp/tiflash/data/db,/tmp/tiflash1,/tmp/tiflash2" -# capacity = "0" mark_cache_size = 1073741824 minmax_index_cache_size = 1073741824 tcp_port = 9000 http_port = 8123 -## Storage paths settings. -# [storage] -## The storage format version in storage engine. Valid values: 1, 2 (experimental). -## format_version = 1 - -## If there are multiple SSD disks on the machine, -## specify the path list on `storage.main.dir` can improve TiFlash performance. - -## If there are multiple disks with different IO metrics (e.g. one SSD and some HDDs) -## on the machine, -## set `storage.latest.dir` to store the latest data on SSD (disks with higher IOPS metrics) -## set `storage.main.dir` to store the main data on HDD (disks with lower IOPS metrics) -## can improve TiFlash performance. - -# [storage.main] -## The path to store main data. -# e.g. -# dir = [ "/data0/tiflash" ] -# or -# dir = [ "/data0/tiflash", "/data1/tiflash" ] - -## Store capacity of each path, i.e. max data size allowed. -## If it is not set, or is set to 0s, the actual disk capacity is used. -## Note that we don't support human-readable big numbers(like "10GB") yet. -## Please set in the specified number of bytes. -# e.g. -# capacity = [ 10737418240, 10737418240 ] - -# [storage.latest] -## The path(s) to store latest data. -## If not set, it will be the same with `storage.main.dir`. -# dir = [ ] - -## Store capacity of each path, i.e. max data size allowed. -## If it is not set, or is set to 0s, the actual disk capacity is used. -# e.g. -# capacity = [ 10737418240, 10737418240 ] - -# [storage.raft] -## The path(s) to store Raft data. -## If not set, it will be the paths in `storage.latest.dir` appended with "/kvstore". -# dir = [ ] - -# [storage.io_rate_limit] -## The max I/O bandwith. Default value is 0 and I/O rate limit is disabled. -# max_bytes_per_sec = 268435456 -## max_read_bytes_per_sec and max_write_bytes_per_sec are the same meaning as max_bytes_per_sec, -## but for disk that read bandwidth and write bandwith are calculated separatly, such as GCP's persistent disks. -# max_read_bytes_per_sec = 0 -# max_write_bytes_per_sec = 0 - [flash] service_addr = "0.0.0.0:3930" [flash.flash_cluster] @@ -105,16 +49,6 @@ runAsDaemon = true [raft] pd_addr = "pd0:2379" ignore_databases = "system,default" -# specify which storage engine we use. tmt or dt -storage_engine = "dt" -# Deprecated Raft data storage path setting style. Check [storage.raft] section for new style. -# If it is not set, it will be the first path of "path" appended with "/kvstore". -# kvstore_path = "" - -[raft.snapshot] -# The way to apply snapshot data -# The value is one of "block" / "file1" / "file2". -# method = "file1" [profiles] [profiles.default] From 092e6180d254602d667f3045a49ded1bcb316389 Mon Sep 17 00:00:00 2001 From: JaySon Date: Wed, 15 Mar 2023 19:10:39 +0800 Subject: [PATCH 13/18] Support disagg read after data ingest by FAP (#7075) ref pingcap/tiflash#6827 --- dbms/src/Interpreters/Settings.h | 2 +- .../ColumnFile/ColumnFileSetSnapshot.h | 2 +- .../DeltaMerge/Remote/DataStore/DataStore.h | 2 + .../Remote/DataStore/DataStoreS3.cpp | 9 +++++ .../DeltaMerge/Remote/DataStore/DataStoreS3.h | 2 + .../DeltaMerge/Remote/Proto/remote.proto | 11 +++++- .../Storages/DeltaMerge/Remote/Serializer.cpp | 37 +++++++------------ .../Storages/DeltaMerge/Remote/Serializer.h | 3 -- .../Storages/StorageDisaggregatedRemote.cpp | 2 +- dbms/src/TiDB/Etcd/Client.cpp | 3 +- dbms/src/TiDB/OwnerManager.cpp | 1 + 11 files changed, 42 insertions(+), 32 deletions(-) diff --git a/dbms/src/Interpreters/Settings.h b/dbms/src/Interpreters/Settings.h index 76b1b4cbb98..7bb73a6ba19 100644 --- a/dbms/src/Interpreters/Settings.h +++ b/dbms/src/Interpreters/Settings.h @@ -238,7 +238,7 @@ struct Settings M(SettingCompressionMethod, dt_compression_method, CompressionMethod::LZ4, "The method of data compression when writing.") \ M(SettingInt64, dt_compression_level, 1, "The compression level.") \ \ - M(SettingInt64, remote_checkpoint_interval_seconds, 60, "The interval of uploading checkpoint to the remote store. Unit is second.") \ + M(SettingInt64, remote_checkpoint_interval_seconds, 30, "The interval of uploading checkpoint to the remote store. Unit is second.") \ M(SettingInt64, remote_gc_interval_seconds, 3600, "The interval of running GC task on the remote store. Unit is second.") \ \ M(SettingUInt64, max_rows_in_set, 0, "Maximum size of the set (in number of elements) resulting from the execution of the IN section.") \ diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileSetSnapshot.h b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileSetSnapshot.h index 781af5a6dc5..71f19763b44 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileSetSnapshot.h +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileSetSnapshot.h @@ -103,7 +103,7 @@ class ColumnFileSetSnapshot : public std::enable_shared_from_this #include #include #include @@ -139,6 +140,14 @@ IPreparedDMFileTokenPtr DataStoreS3::prepareDMFile(const S3::DMFileOID & oid, UI return std::make_shared(file_provider, oid, page_id); } +IPreparedDMFileTokenPtr DataStoreS3::prepareDMFileByKey(const String & remote_key) +{ + const auto view = S3::S3FilenameView::fromKeyWithPrefix(remote_key); + RUNTIME_CHECK(view.isDMFile(), magic_enum::enum_name(view.type), remote_key); + auto oid = view.getDMFileOID(); + return prepareDMFile(oid, 0); +} + DMFilePtr S3PreparedDMFileToken::restore(DMFile::ReadMetaMode read_mode) { return DMFile::restore( diff --git a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.h b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.h index 00288f227d9..722128b434c 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.h +++ b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.h @@ -47,6 +47,8 @@ class DataStoreS3 final : public IDataStore */ IPreparedDMFileTokenPtr prepareDMFile(const S3::DMFileOID & oid, UInt64 page_id) override; + IPreparedDMFileTokenPtr prepareDMFileByKey(const String & remote_key) override; + bool putCheckpointFiles(const PS::V3::LocalCheckpointFiles & local_files, StoreID store_id, UInt64 upload_seq) override; #ifndef DBMS_PUBLIC_GTEST diff --git a/dbms/src/Storages/DeltaMerge/Remote/Proto/remote.proto b/dbms/src/Storages/DeltaMerge/Remote/Proto/remote.proto index 00006886d27..f622b2f08c9 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/Proto/remote.proto +++ b/dbms/src/Storages/DeltaMerge/Remote/Proto/remote.proto @@ -72,6 +72,7 @@ message ColumnFileInMemory { message ColumnFileTiny { uint64 page_id = 1; uint64 page_size = 2; + CheckpointInfo checkpoint_info = 3; // serialized schema bytes schema = 5; @@ -82,7 +83,7 @@ message ColumnFileTiny { message ColumnFileBig { uint64 page_id = 1; - uint64 file_id = 2; + CheckpointInfo checkpoint_info = 2; // TODO: We should better recalculate these fields from local DTFile. uint64 valid_rows = 10; @@ -93,6 +94,14 @@ message ColumnFileDeleteRange { bytes key_range = 1; } +message CheckpointInfo { + bytes data_file_id = 1; + uint64 offset = 2; + uint64 size = 3; + // whether the data reclaimed on the write node or not + bool is_local_data_reclaimed = 4; +} + message TiFlashColumnInfo { int64 column_id = 1; // serialized name by IDataType::getName() diff --git a/dbms/src/Storages/DeltaMerge/Remote/Serializer.cpp b/dbms/src/Storages/DeltaMerge/Remote/Serializer.cpp index 926caf21d70..492cfcb3424 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/Serializer.cpp +++ b/dbms/src/Storages/DeltaMerge/Remote/Serializer.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -86,7 +87,9 @@ Serializer::serializeTo( { auto * remote_file = remote.add_stable_pages(); remote_file->set_page_id(dt_file->pageId()); - remote_file->set_file_id(dt_file->fileId()); + auto * checkpoint_info = remote_file->mutable_checkpoint_info(); + RUNTIME_CHECK(startsWith(dt_file->path(), "s3://"), dt_file->path()); + checkpoint_info->set_data_file_id(dt_file->path()); // It should be a key to remote path } remote.mutable_column_files_memtable()->CopyFrom(serializeTo(snap->delta->getMemTableSetSnapshot())); remote.mutable_column_files_persisted()->CopyFrom(serializeTo(snap->delta->getPersistedFileSetSnapshot())); @@ -121,14 +124,10 @@ SegmentSnapshotPtr Serializer::deserializeSegmentSnapshotFrom( delta_snap->mem_table_snap = deserializeColumnFileSet( proto.column_files_memtable(), data_store, - remote_store_id, - table_id, segment_range); delta_snap->persisted_files_snap = deserializeColumnFileSet( proto.column_files_persisted(), data_store, - remote_store_id, - table_id, segment_range); // Note: At this moment, we still cannot read from `delta_snap->mem_table_snap` and `delta_snap->persisted_files_snap`, @@ -157,12 +156,8 @@ SegmentSnapshotPtr Serializer::deserializeSegmentSnapshotFrom( dmfiles.reserve(proto.stable_pages().size()); for (const auto & stable_file : proto.stable_pages()) { - auto oid = Remote::DMFileOID{ - .store_id = remote_store_id, - .table_id = table_id, - .file_id = stable_file.file_id(), - }; - auto prepared = data_store->prepareDMFile(oid); + auto remote_key = stable_file.checkpoint_info().data_file_id(); + auto prepared = data_store->prepareDMFileByKey(remote_key); auto dmfile = prepared->restore(DMFile::ReadMetaMode::all()); dmfiles.emplace_back(std::move(dmfile)); } @@ -208,8 +203,6 @@ Serializer::serializeTo(const ColumnFileSetSnapshotPtr & snap) ColumnFileSetSnapshotPtr Serializer::deserializeColumnFileSet( const RepeatedPtrField & proto, const Remote::IDataStorePtr & data_store, - StoreID remote_store_id, - TableID table_id, const RowKeyRange & segment_range) { auto empty_data_provider = std::make_shared(); @@ -230,14 +223,8 @@ ColumnFileSetSnapshotPtr Serializer::deserializeColumnFileSet( else if (remote_column_file.has_big()) { const auto & big_file = remote_column_file.big(); - auto file_oid = Remote::DMFileOID{ - .store_id = remote_store_id, - .table_id = table_id, - .file_id = big_file.file_id(), - }; ret->column_files.push_back(deserializeCFBig( big_file, - file_oid, data_store, segment_range)); } @@ -334,6 +321,8 @@ RemotePb::ColumnFileRemote Serializer::serializeTo(const ColumnFileTiny & cf_tin remote_tiny->set_rows(cf_tiny.rows); remote_tiny->set_bytes(cf_tiny.bytes); + // TODO: read the checkpoint info from data_provider and send it to the compute node + return ret; } @@ -378,7 +367,8 @@ RemotePb::ColumnFileRemote Serializer::serializeTo(const ColumnFileBig & cf_big) { RemotePb::ColumnFileRemote ret; auto * remote_big = ret.mutable_big(); - remote_big->set_file_id(cf_big.file->fileId()); + auto * checkpoint_info = remote_big->mutable_checkpoint_info(); + checkpoint_info->set_data_file_id(cf_big.file->path()); remote_big->set_page_id(cf_big.file->pageId()); remote_big->set_valid_rows(cf_big.valid_rows); remote_big->set_valid_bytes(cf_big.valid_bytes); @@ -387,14 +377,13 @@ RemotePb::ColumnFileRemote Serializer::serializeTo(const ColumnFileBig & cf_big) ColumnFileBigPtr Serializer::deserializeCFBig( const RemotePb::ColumnFileBig & proto, - const Remote::DMFileOID & oid, const Remote::IDataStorePtr & data_store, const RowKeyRange & segment_range) { - RUNTIME_CHECK(proto.file_id() == oid.file_id); - LOG_DEBUG(Logger::get(), "Rebuild local ColumnFileBig from remote, dmf_oid={}", oid); + RUNTIME_CHECK(proto.has_checkpoint_info()); + LOG_DEBUG(Logger::get(), "Rebuild local ColumnFileBig from remote, key={}", proto.checkpoint_info().data_file_id()); - auto prepared = data_store->prepareDMFile(oid); + auto prepared = data_store->prepareDMFileByKey(proto.checkpoint_info().data_file_id()); auto dmfile = prepared->restore(DMFile::ReadMetaMode::all()); auto * cf_big = new ColumnFileBig(dmfile, proto.valid_rows(), proto.valid_bytes(), segment_range); return std::shared_ptr(cf_big); // The constructor is private, so we cannot use make_shared. diff --git a/dbms/src/Storages/DeltaMerge/Remote/Serializer.h b/dbms/src/Storages/DeltaMerge/Remote/Serializer.h index 540b6ecdbc2..0ede1479a65 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/Serializer.h +++ b/dbms/src/Storages/DeltaMerge/Remote/Serializer.h @@ -84,8 +84,6 @@ struct Serializer static ColumnFileSetSnapshotPtr deserializeColumnFileSet( const google::protobuf::RepeatedPtrField & proto, const Remote::IDataStorePtr & data_store, - StoreID remote_store_id, - TableID table_id, const RowKeyRange & segment_range); /// column file /// @@ -102,7 +100,6 @@ struct Serializer static RemotePb::ColumnFileRemote serializeTo(const ColumnFileBig & cf_big); static ColumnFileBigPtr deserializeCFBig( const RemotePb::ColumnFileBig & proto, - const Remote::DMFileOID & oid, const Remote::IDataStorePtr & data_store, const RowKeyRange & segment_range); }; diff --git a/dbms/src/Storages/StorageDisaggregatedRemote.cpp b/dbms/src/Storages/StorageDisaggregatedRemote.cpp index 156ad7b7308..f714d7949de 100644 --- a/dbms/src/Storages/StorageDisaggregatedRemote.cpp +++ b/dbms/src/Storages/StorageDisaggregatedRemote.cpp @@ -227,7 +227,7 @@ DM::RNRemoteReadTaskPtr StorageDisaggregated::buildDisaggregatedTask( LOG_DEBUG( log, - "Build RNRemoteTableReadTask finished, elapsed={}s store={} addr={} segments={} task_id={}", + "Build RNRemoteTableReadTask finished, elapsed={:.3f}s store={} addr={} segments={} task_id={}", watch_table.elapsedSeconds(), resp->store_id(), batch_cop_task.store_addr, diff --git a/dbms/src/TiDB/Etcd/Client.cpp b/dbms/src/TiDB/Etcd/Client.cpp index 15ec15dc72c..91a51053e66 100644 --- a/dbms/src/TiDB/Etcd/Client.cpp +++ b/dbms/src/TiDB/Etcd/Client.cpp @@ -189,7 +189,8 @@ Client::campaign(const String & name, const String & value, LeaseID lease_id) req.set_lease(lease_id); grpc::ClientContext context; - context.set_deadline(std::chrono::system_clock::now() + timeout); + // usually use `campaign` blocks until become leader or error happens, + // don't set timeout. v3electionpb::CampaignResponse resp; auto status = leaderClient()->election_stub->Campaign(&context, req, &resp); diff --git a/dbms/src/TiDB/OwnerManager.cpp b/dbms/src/TiDB/OwnerManager.cpp index 162e9fe80c0..92ed8f89d89 100644 --- a/dbms/src/TiDB/OwnerManager.cpp +++ b/dbms/src/TiDB/OwnerManager.cpp @@ -247,6 +247,7 @@ void EtcdOwnerManager::camaignLoop(Etcd::SessionPtr session) const auto lease_id = session->leaseID(); LOG_DEBUG(log, "new campaign loop with lease_id={:x}", lease_id); + // Let this thread blocks until becone owner or error occurs auto && [new_leader, status] = client->campaign(campaign_name, id, lease_id); if (!status.ok()) { From 1d0e914631fce1e7d3abcfcabadf08c5a728d002 Mon Sep 17 00:00:00 2001 From: Wenxuan Date: Thu, 16 Mar 2023 00:44:39 +0800 Subject: [PATCH 14/18] Disable prepare stage (#7078) ref pingcap/tiflash#6827 --- dbms/src/Storages/StorageDisaggregatedRemote.cpp | 2 +- tests/tidb-ci/new_collation_fullstack/function_collator.test | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dbms/src/Storages/StorageDisaggregatedRemote.cpp b/dbms/src/Storages/StorageDisaggregatedRemote.cpp index f714d7949de..a0d7e64087d 100644 --- a/dbms/src/Storages/StorageDisaggregatedRemote.cpp +++ b/dbms/src/Storages/StorageDisaggregatedRemote.cpp @@ -361,7 +361,7 @@ void StorageDisaggregated::buildRemoteSegmentInputStreams( log->identifier(), executor_id); - bool do_prepare = true; + bool do_prepare = false; // Build the input streams to read blocks from remote segments auto [column_defines, extra_table_id_index] = genColumnDefinesForDisaggregatedRead(table_scan); diff --git a/tests/tidb-ci/new_collation_fullstack/function_collator.test b/tests/tidb-ci/new_collation_fullstack/function_collator.test index 8821de30bfb..ed2cfda4203 100644 --- a/tests/tidb-ci/new_collation_fullstack/function_collator.test +++ b/tests/tidb-ci/new_collation_fullstack/function_collator.test @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +#TODO: Fix this test https://github.com/pingcap/tiflash/issues/7079 +#RETURN + mysql> drop table if exists test.t1 mysql> drop table if exists test.t2 mysql> create table test.t1(col_varchar_20_key_signed varchar(20) COLLATE utf8mb4_general_ci, col_varbinary_20_key_signed varbinary(20), col_varbinary_20_undef_signed varbinary(20)); From 957bbdac2b547de2ba371bfa6501c714c43f92fa Mon Sep 17 00:00:00 2001 From: Wenxuan Date: Thu, 16 Mar 2023 01:24:38 +0800 Subject: [PATCH 15/18] Retry more exceptions for disaggregated read (#7070) ref pingcap/tiflash#6827 --- dbms/src/Common/ErrorCodes.cpp | 3 +- .../Coprocessor/DAGStorageInterpreter.cpp | 17 ++--- .../WNEstablishDisaggTaskHandler.cpp | 10 ++- dbms/src/Flash/FlashService.cpp | 72 +++++++++++++------ dbms/src/Interpreters/AsynchronousMetrics.cpp | 7 ++ dbms/src/Storages/DeltaMerge/DMContext.h | 4 +- .../Storages/DeltaMerge/DeltaMergeStore.cpp | 8 +-- .../src/Storages/DeltaMerge/DeltaMergeStore.h | 8 +-- .../DeltaMerge/Remote/RNLocalPageCache.h | 2 +- .../RNRemoteSegmentThreadInputStream.cpp | 8 +-- .../Remote/RNRemoteSegmentThreadInputStream.h | 7 +- .../Remote/WNDisaggSnapshotManager.h | 20 +++--- .../DeltaMerge/workload/MainEntry.cpp | 17 +++++ dbms/src/Storages/StorageDeltaMerge.cpp | 3 +- .../Storages/StorageDisaggregatedRemote.cpp | 68 +++++++++++------- dbms/src/Storages/Transaction/LearnerRead.cpp | 4 +- dbms/src/Storages/Transaction/LockException.h | 16 ++--- .../Storages/Transaction/RegionException.h | 22 ++---- 18 files changed, 176 insertions(+), 120 deletions(-) diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index dc96adf651f..df388c4efa3 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -406,7 +406,6 @@ extern const int PAGE_SIZE_NOT_MATCH = 9006; extern const int ILLFORMED_PAGE_NAME = 9007; extern const int ILLFORMAT_RAFT_ROW = 9008; extern const int REGION_DATA_SCHEMA_UPDATED = 9009; -extern const int REGION_EPOCH_NOT_MATCH = 9010; extern const int LOCK_EXCEPTION = 10000; extern const int VERSION_ERROR = 10001; @@ -426,6 +425,8 @@ extern const int PTHREAD_ERROR = 10014; extern const int PS_ENTRY_NOT_EXISTS = 10015; extern const int PS_ENTRY_NO_VALID_VERSION = 10016; extern const int PS_DIR_APPLY_INVALID_STATUS = 10017; +extern const int DISAGG_ESTABLISH_RETRYABLE_ERROR = 10018; +extern const int REGION_LOCKED = 10019; extern const int S3_ERROR = 11000; extern const int CANNOT_SCHEDULE_TASK = 11001; diff --git a/dbms/src/Flash/Coprocessor/DAGStorageInterpreter.cpp b/dbms/src/Flash/Coprocessor/DAGStorageInterpreter.cpp index 0e5631ce355..67f78e1ee00 100644 --- a/dbms/src/Flash/Coprocessor/DAGStorageInterpreter.cpp +++ b/dbms/src/Flash/Coprocessor/DAGStorageInterpreter.cpp @@ -54,10 +54,6 @@ namespace DB { -namespace ErrorCodes -{ -extern const int REGION_EPOCH_NOT_MATCH; -} // namespace ErrorCodes namespace FailPoints { @@ -319,7 +315,13 @@ void DAGStorageInterpreter::executeImpl(DAGPipeline & pipeline) // and ask RN to send requests again with correct region info. When RN updates region info, // RN may be sending requests to other WN. - throw Exception("Rejected disaggregated DAG execute because RN region info does not match", DB::ErrorCodes::REGION_EPOCH_NOT_MATCH); + RegionException::UnavailableRegions region_ids; + for (const auto & info : context.getDAGContext()->retry_regions) + region_ids.insert(info.region_id); + + throw RegionException( + std::move(region_ids), + RegionException::RegionReadStatus::EPOCH_NOT_MATCH); } // A failpoint to test pause before alter lock released @@ -820,9 +822,8 @@ void DAGStorageInterpreter::buildLocalStreams(DAGPipeline & pipeline, size_t max const auto & snap_id = *dag_context.getDisaggTaskId(); auto timeout_s = context.getSettingsRef().disagg_task_snapshot_timeout; auto expired_at = Clock::now() + std::chrono::seconds(timeout_s); - bool register_snapshot_ok = snaps->registerSnapshot(snap_id, std::move(disaggregated_snap), expired_at); - RUNTIME_CHECK_MSG(register_snapshot_ok, "disaggregated task has been registered {}", snap_id); - LOG_INFO(log, "task snapshot registered, snapshot_id={}", snap_id); + bool register_snapshot_ok = snaps->registerSnapshot(snap_id, disaggregated_snap, expired_at); + RUNTIME_CHECK_MSG(register_snapshot_ok, "Disaggregated task has been registered, snap_id={}", snap_id); } if (has_multiple_partitions) diff --git a/dbms/src/Flash/Disaggregated/WNEstablishDisaggTaskHandler.cpp b/dbms/src/Flash/Disaggregated/WNEstablishDisaggTaskHandler.cpp index ddedace9e65..5d1670bc230 100644 --- a/dbms/src/Flash/Disaggregated/WNEstablishDisaggTaskHandler.cpp +++ b/dbms/src/Flash/Disaggregated/WNEstablishDisaggTaskHandler.cpp @@ -30,10 +30,6 @@ namespace DB { -namespace ErrorCodes -{ -extern const int REGION_EPOCH_NOT_MATCH; -} // namespace ErrorCodes WNEstablishDisaggTaskHandler::WNEstablishDisaggTaskHandler(ContextPtr context_, const DM::DisaggTaskId & task_id) : context(std::move(context_)) @@ -60,7 +56,9 @@ void WNEstablishDisaggTaskHandler::prepare(const disaggregated::EstablishDisaggT context->setSetting("read_tso", start_ts); if (request->timeout_s() < 0) + { throw TiFlashException(Errors::Coprocessor::BadRequest, "invalid timeout={}", request->timeout_s()); + } else if (request->timeout_s() > 0) { context->setSetting("disagg_task_snapshot_timeout", request->timeout_s()); @@ -92,9 +90,9 @@ void WNEstablishDisaggTaskHandler::execute(disaggregated::EstablishDisaggTaskRes response->set_store_id(kvstore->getStoreID()); } - auto snapshots = context->getSharedContextDisagg()->wn_snapshot_manager; + auto snaps = context->getSharedContextDisagg()->wn_snapshot_manager; const auto & task_id = *dag_context->getDisaggTaskId(); - auto snap = snapshots->getSnapshot(task_id); + auto snap = snaps->getSnapshot(task_id); RUNTIME_CHECK_MSG(snap, "Snapshot was missing, task_id={}", task_id); { diff --git a/dbms/src/Flash/FlashService.cpp b/dbms/src/Flash/FlashService.cpp index 8f4b2b54ca8..7f972dd924b 100644 --- a/dbms/src/Flash/FlashService.cpp +++ b/dbms/src/Flash/FlashService.cpp @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include #include @@ -51,6 +53,7 @@ namespace ErrorCodes { extern const int NOT_IMPLEMENTED; extern const int UNKNOWN_EXCEPTION; +extern const int DISAGG_ESTABLISH_RETRYABLE_ERROR; } // namespace ErrorCodes #define CATCH_FLASHSERVICE_EXCEPTION \ @@ -623,12 +626,14 @@ grpc::Status FlashService::EstablishDisaggTask(grpc::ServerContext * grpc_contex current_memory_tracker = nullptr; }); - grpc::Status ret_status = grpc::Status::OK; - auto record_error = [&](grpc::StatusCode err_code, int flash_err_code, const String & err_msg) { + auto record_error = [&](int flash_err_code, const String & err_msg) { + // Note: We intentinally do not remove the snapshot from the SnapshotManager + // when this request is failed. Consider this case: + // EstablishDisagg for A: ---------------- Failed --------------------------------------------- Cleanup Snapshot for A + // EstablishDisagg for B: - Failed - RN retry EstablishDisagg for A+B -- InsertSnapshot for A+B ----- FetchPages (Boom!) auto * err = response->mutable_error(); err->set_code(flash_err_code); err->set_msg(err_msg); - ret_status = grpc::Status(err_code, err_msg); }; try @@ -636,42 +641,63 @@ grpc::Status FlashService::EstablishDisaggTask(grpc::ServerContext * grpc_contex handler->prepare(request); handler->execute(response); } + catch (const RegionException & e) + { + for (const auto & region_id : e.unavailable_region) + { + auto * retry_region = response->add_retry_regions(); + retry_region->set_id(region_id); + // Note: retry_region's version and epoch is not set, because we miss these information + // from the exception. + } + LOG_INFO(logger, "EstablishDisaggTask meet RegionException {} (retryable), regions={}", e.message(), e.unavailable_region); + record_error( + ErrorCodes::DISAGG_ESTABLISH_RETRYABLE_ERROR, + fmt::format("Retryable error: {}", e.message())); + } + catch (const LockException & e) + { + auto * retry_region = response->add_retry_regions(); + retry_region->set_id(e.region_id); + // Note: retry_region's version and epoch is not set, because we miss these information + // from the exception. + + LOG_INFO(logger, "EstablishDisaggTask meet LockException (retryable), region_id={}", e.region_id); + // TODO: We may need to send this error back to TiDB? Otherwise TiDB + // may not resolve lock in time. + record_error( + ErrorCodes::DISAGG_ESTABLISH_RETRYABLE_ERROR, + fmt::format("Retryable error: {}", e.message())); + } catch (Exception & e) { - LOG_ERROR(logger, "EstablishDisaggTask meet Exception: {}\n{}", e.displayText(), e.getStackTrace().toString()); - record_error(grpc::StatusCode::INTERNAL, e.code(), e.message()); + LOG_ERROR(logger, "EstablishDisaggTask meet exception: {}\n{}", e.displayText(), e.getStackTrace().toString()); + record_error(e.code(), e.message()); } catch (const pingcap::Exception & e) { LOG_ERROR(logger, "EstablishDisaggTask meet KV Client Exception: {}", e.message()); - record_error(grpc::StatusCode::INTERNAL, ErrorCodes::UNKNOWN_EXCEPTION, e.message()); + record_error(e.code(), e.message()); } catch (std::exception & e) { LOG_ERROR(logger, "EstablishDisaggTask meet std::exception: {}", e.what()); - record_error(grpc::StatusCode::INTERNAL, ErrorCodes::UNKNOWN_EXCEPTION, e.what()); + record_error(ErrorCodes::UNKNOWN_EXCEPTION, e.what()); } catch (...) { LOG_ERROR(logger, "EstablishDisaggTask meet unknown exception"); - record_error(grpc::StatusCode::INTERNAL, ErrorCodes::UNKNOWN_EXCEPTION, "other exception"); + record_error(ErrorCodes::UNKNOWN_EXCEPTION, "other exception"); } - // When there is a region retry, exceptions will be thrown, so we placed here as a "finally". - if (auto * dag_ctx = db_context->getDAGContext(); dag_ctx) - { - // There may be region errors. Add information about which region to retry. - for (const auto & region : dag_ctx->retry_regions) - { - auto * retry_region = response->add_retry_regions(); - retry_region->set_id(region.region_id); - retry_region->mutable_region_epoch()->set_conf_ver(region.region_conf_version); - retry_region->mutable_region_epoch()->set_version(region.region_version); - } - } + LOG_DEBUG( + logger, + "Handle EstablishDisaggTask request done, resp_err={}", + response->has_error() ? response->error().ShortDebugString() : "(null)"); - LOG_DEBUG(logger, "Handle EstablishDisaggTask request done, resp_err={}", response->error().ShortDebugString()); - return ret_status; + // The response is send back to TiFlash. Always assign gRPC::Status::OK, so that TiFlash response + // handlers can deal with the embedded error correctly. + return grpc::Status::OK; } grpc::Status FlashService::FetchDisaggPages( @@ -732,7 +758,7 @@ grpc::Status FlashService::FetchDisaggPages( } catch (const Exception & e) { - LOG_ERROR(logger, "FetchDisaggPages meet Exception: {}\n{}", e.message(), e.getStackTrace().toString()); + LOG_ERROR(logger, "FetchDisaggPages meet exception: {}\n{}", e.message(), e.getStackTrace().toString()); return record_error(tiflashErrorCodeToGrpcStatusCode(e.code()), e.message()); } catch (const pingcap::Exception & e) diff --git a/dbms/src/Interpreters/AsynchronousMetrics.cpp b/dbms/src/Interpreters/AsynchronousMetrics.cpp index f82cb68e8b3..e08725ea91d 100644 --- a/dbms/src/Interpreters/AsynchronousMetrics.cpp +++ b/dbms/src/Interpreters/AsynchronousMetrics.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -141,6 +142,12 @@ FileUsageStatistics AsynchronousMetrics::getPageStorageFileUsage() .merge(meta_usage) .merge(data_usage); } + + if (auto ps_cache = context.getSharedContextDisagg()->rn_page_cache_storage; ps_cache != nullptr) + { + usage.merge(ps_cache->getUniversalPageStorage()->getFileUsageStatistics()); + } + return usage; } diff --git a/dbms/src/Storages/DeltaMerge/DMContext.h b/dbms/src/Storages/DeltaMerge/DMContext.h index 0362e84df4a..c63f2987b31 100644 --- a/dbms/src/Storages/DeltaMerge/DMContext.h +++ b/dbms/src/Storages/DeltaMerge/DMContext.h @@ -100,7 +100,7 @@ struct DMContext : private boost::noncopyable bool is_common_handle_, size_t rowkey_column_size_, const DB::Settings & settings, - const ScanContextPtr & scan_context_ = std::make_shared(), + const ScanContextPtr scan_context_ = nullptr, const String & tracing_id_ = "") : db_context(db_context_) , path_pool(path_pool_) @@ -125,7 +125,7 @@ struct DMContext : private boost::noncopyable , enable_relevant_place(settings.dt_enable_relevant_place) , enable_skippable_place(settings.dt_enable_skippable_place) , tracing_id(tracing_id_) - , scan_context(scan_context_) + , scan_context(scan_context_ ? scan_context_ : std::make_shared()) { } diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp index 14aca60cead..c2c47217907 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp @@ -420,7 +420,7 @@ void DeltaMergeStore::shutdown() LOG_TRACE(log, "Shutdown DeltaMerge end"); } -DMContextPtr DeltaMergeStore::newDMContext(const Context & db_context, const DB::Settings & db_settings, const String & tracing_id, const ScanContextPtr & scan_context_) +DMContextPtr DeltaMergeStore::newDMContext(const Context & db_context, const DB::Settings & db_settings, const String & tracing_id, ScanContextPtr scan_context_) { std::shared_lock lock(read_write_mutex); @@ -997,7 +997,7 @@ BlockInputStreams DeltaMergeStore::read(const Context & db_context, size_t expected_block_size, const SegmentIdSet & read_segments, size_t extra_table_id_index, - const ScanContextPtr & scan_context) + ScanContextPtr scan_context) { // Use the id from MPP/Coprocessor level as tracing_id auto dm_context = newDMContext(db_context, db_settings, tracing_id, scan_context); @@ -1087,7 +1087,7 @@ SourceOps DeltaMergeStore::readSourceOps( size_t expected_block_size, const SegmentIdSet & read_segments, size_t extra_table_id_index, - const ScanContextPtr & scan_context) + ScanContextPtr scan_context) { // Use the id from MPP/Coprocessor level as tracing_id auto dm_context = newDMContext(db_context, db_settings, tracing_id, scan_context); @@ -1153,7 +1153,7 @@ DeltaMergeStore::writeNodeBuildRemoteReadSnapshot( size_t num_streams, const String & tracing_id, const SegmentIdSet & read_segments, - const ScanContextPtr & scan_context) + ScanContextPtr scan_context) { auto dm_context = newDMContext(db_context, db_settings, tracing_id, scan_context); auto log_tracing_id = getLogTracingId(*dm_context); diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h index 327d52721e1..b70930c5779 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h @@ -351,7 +351,7 @@ class DeltaMergeStore : private boost::noncopyable size_t expected_block_size = DEFAULT_BLOCK_SIZE, const SegmentIdSet & read_segments = {}, size_t extra_table_id_index = InvalidColumnID, - const ScanContextPtr & scan_context = std::make_shared()); + ScanContextPtr scan_context = nullptr); /// Read rows in two modes: @@ -372,7 +372,7 @@ class DeltaMergeStore : private boost::noncopyable size_t expected_block_size = DEFAULT_BLOCK_SIZE, const SegmentIdSet & read_segments = {}, size_t extra_table_id_index = InvalidColumnID, - const ScanContextPtr & scan_context = std::make_shared()); + ScanContextPtr scan_context = nullptr); Remote::DisaggPhysicalTableReadSnapshotPtr writeNodeBuildRemoteReadSnapshot( @@ -382,7 +382,7 @@ class DeltaMergeStore : private boost::noncopyable size_t num_streams, const String & tracing_id, const SegmentIdSet & read_segments = {}, - const ScanContextPtr & scan_context = std::make_shared()); + ScanContextPtr scan_context = nullptr); /// Try flush all data in `range` to disk and return whether the task succeed. bool flushCache(const Context & context, const RowKeyRange & range, bool try_until_succeed = true); @@ -483,7 +483,7 @@ class DeltaMergeStore : private boost::noncopyable private: #endif - DMContextPtr newDMContext(const Context & db_context, const DB::Settings & db_settings, const String & tracing_id = "", const ScanContextPtr & scan_context = std::make_shared()); + DMContextPtr newDMContext(const Context & db_context, const DB::Settings & db_settings, const String & tracing_id = "", ScanContextPtr scan_context = nullptr); static bool pkIsHandle(const ColumnDefine & handle_define) { diff --git a/dbms/src/Storages/DeltaMerge/Remote/RNLocalPageCache.h b/dbms/src/Storages/DeltaMerge/Remote/RNLocalPageCache.h index 6a48d9c260b..6ecd6460e4e 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/RNLocalPageCache.h +++ b/dbms/src/Storages/DeltaMerge/Remote/RNLocalPageCache.h @@ -15,6 +15,7 @@ #pragma once #include +#include #include #include #include @@ -25,7 +26,6 @@ namespace DB { -class Context; class ReadBuffer; using ReadBufferPtr = std::shared_ptr; diff --git a/dbms/src/Storages/DeltaMerge/Remote/RNRemoteSegmentThreadInputStream.cpp b/dbms/src/Storages/DeltaMerge/Remote/RNRemoteSegmentThreadInputStream.cpp index 7a3607a161a..1461ee9b4db 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/RNRemoteSegmentThreadInputStream.cpp +++ b/dbms/src/Storages/DeltaMerge/Remote/RNRemoteSegmentThreadInputStream.cpp @@ -29,7 +29,7 @@ namespace DB::DM BlockInputStreams RNRemoteSegmentThreadInputStream::buildInputStreams( const Context & db_context, const RNRemoteReadTaskPtr & remote_read_tasks, - const RNPagePreparerPtr & page_downloader, + const RNPagePreparerPtr & page_preparer, const DM::ColumnDefinesPtr & columns_to_read, UInt64 read_tso, size_t num_streams, @@ -46,7 +46,7 @@ BlockInputStreams RNRemoteSegmentThreadInputStream::buildInputStreams( BlockInputStreamPtr stream = std::make_shared( db_context, remote_read_tasks, - page_downloader, + page_preparer, *columns_to_read, rs_filter, read_tso, @@ -63,7 +63,7 @@ BlockInputStreams RNRemoteSegmentThreadInputStream::buildInputStreams( RNRemoteSegmentThreadInputStream::RNRemoteSegmentThreadInputStream( const Context & db_context_, RNRemoteReadTaskPtr read_tasks_, - RNPagePreparerPtr page_downloader_, + RNPagePreparerPtr page_preparer_, const ColumnDefines & columns_to_read_, const RSOperatorPtr & filter_, UInt64 max_version_, @@ -73,7 +73,7 @@ RNRemoteSegmentThreadInputStream::RNRemoteSegmentThreadInputStream( std::string_view req_id) : db_context(db_context_) , read_tasks(std::move(read_tasks_)) - , page_downloader(std::move(page_downloader_)) + , page_preparer(std::move(page_preparer_)) , columns_to_read(columns_to_read_) , filter(filter_) , header(toEmptyBlock(columns_to_read)) diff --git a/dbms/src/Storages/DeltaMerge/Remote/RNRemoteSegmentThreadInputStream.h b/dbms/src/Storages/DeltaMerge/Remote/RNRemoteSegmentThreadInputStream.h index 43f26590413..81c5811ee2c 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/RNRemoteSegmentThreadInputStream.h +++ b/dbms/src/Storages/DeltaMerge/Remote/RNRemoteSegmentThreadInputStream.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -45,7 +44,7 @@ class RNRemoteSegmentThreadInputStream : public IProfilingBlockInputStream static BlockInputStreams buildInputStreams( const Context & db_context, const RNRemoteReadTaskPtr & remote_read_tasks, - const RNPagePreparerPtr & page_downloader, + const RNPagePreparerPtr & page_preparer, const DM::ColumnDefinesPtr & columns_to_read, UInt64 read_tso, size_t num_streams, @@ -58,7 +57,7 @@ class RNRemoteSegmentThreadInputStream : public IProfilingBlockInputStream RNRemoteSegmentThreadInputStream( const Context & db_context_, RNRemoteReadTaskPtr read_tasks_, - RNPagePreparerPtr page_downloader_, + RNPagePreparerPtr page_preparer_, const ColumnDefines & columns_to_read_, const RSOperatorPtr & filter_, UInt64 max_version_, @@ -85,7 +84,7 @@ class RNRemoteSegmentThreadInputStream : public IProfilingBlockInputStream private: const Context & db_context; RNRemoteReadTaskPtr read_tasks; - RNPagePreparerPtr page_downloader; + RNPagePreparerPtr page_preparer; ColumnDefines columns_to_read; RSOperatorPtr filter; Block header; diff --git a/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.h b/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.h index f6be59f08e0..1918ae57c42 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.h +++ b/dbms/src/Storages/DeltaMerge/Remote/WNDisaggSnapshotManager.h @@ -40,8 +40,8 @@ class WNDisaggSnapshotManager public: struct SnapshotWithExpireTime { - const DisaggReadSnapshotPtr snap; - const Timepoint expired_at; + DisaggReadSnapshotPtr snap; + Timepoint expired_at; }; public: @@ -49,15 +49,16 @@ class WNDisaggSnapshotManager ~WNDisaggSnapshotManager(); - bool registerSnapshot(const DisaggTaskId & task_id, DisaggReadSnapshotPtr && snap, const Timepoint & expired_at) + bool registerSnapshot(const DisaggTaskId & task_id, const DisaggReadSnapshotPtr & snap, const Timepoint & expired_at) { - LOG_DEBUG(log, "Register Disaggregated Snapshot, task_id={}", task_id); - std::unique_lock lock(mtx); - if (auto iter = snapshots.find(task_id); iter != snapshots.end()) - return false; + LOG_DEBUG(log, "Register Disaggregated Snapshot, task_id={}", task_id); - snapshots.emplace(task_id, SnapshotWithExpireTime{.snap = std::move(snap), .expired_at = expired_at}); + // Since EstablishDisagg may be retried, there may be existing snapshot. + // We replace these existing snapshot using a new one. + snapshots.insert_or_assign( + task_id, + SnapshotWithExpireTime{.snap = snap, .expired_at = expired_at}); return true; } @@ -76,11 +77,10 @@ class WNDisaggSnapshotManager private: bool unregisterSnapshot(const DisaggTaskId & task_id) { - LOG_DEBUG(log, "Unregister Disaggregated Snapshot, task_id={}", task_id); - std::unique_lock lock(mtx); if (auto iter = snapshots.find(task_id); iter != snapshots.end()) { + LOG_DEBUG(log, "Unregister Disaggregated Snapshot, task_id={}", task_id); snapshots.erase(iter); return true; } diff --git a/dbms/src/Storages/DeltaMerge/workload/MainEntry.cpp b/dbms/src/Storages/DeltaMerge/workload/MainEntry.cpp index b34c28699bf..16a827eed63 100644 --- a/dbms/src/Storages/DeltaMerge/workload/MainEntry.cpp +++ b/dbms/src/Storages/DeltaMerge/workload/MainEntry.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,22 @@ void initThreadPool() { size_t default_num_threads = std::max(4UL, 2 * std::thread::hardware_concurrency()); GlobalThreadPool::initialize( + /*max_threads*/ default_num_threads * 20, + /*max_free_threads*/ default_num_threads, + /*queue_size*/ default_num_threads * 10); + S3FileCachePool::initialize( + /*max_threads*/ default_num_threads, + /*max_free_threads*/ default_num_threads / 2, + /*queue_size*/ default_num_threads * 2); + DataStoreS3Pool::initialize( + /*max_threads*/ default_num_threads, + /*max_free_threads*/ default_num_threads / 2, + /*queue_size*/ default_num_threads * 2); + RNRemoteReadTaskPool::initialize( + /*max_threads*/ default_num_threads, + /*max_free_threads*/ default_num_threads / 2, + /*queue_size*/ default_num_threads * 2); + RNPagePreparerPool::initialize( /*max_threads*/ default_num_threads, /*max_free_threads*/ default_num_threads / 2, /*queue_size*/ default_num_threads * 2); diff --git a/dbms/src/Storages/StorageDeltaMerge.cpp b/dbms/src/Storages/StorageDeltaMerge.cpp index 5784c1b38d7..3191e63aaf9 100644 --- a/dbms/src/Storages/StorageDeltaMerge.cpp +++ b/dbms/src/Storages/StorageDeltaMerge.cpp @@ -876,7 +876,6 @@ StorageDeltaMerge::writeNodeBuildRemoteReadSnapshot( RUNTIME_CHECK(query_info.mvcc_query_info != nullptr); const auto & mvcc_query_info = *query_info.mvcc_query_info; auto ranges = parseMvccQueryInfo(mvcc_query_info, num_streams, context, query_info.req_id, tracing_logger); - const auto & scan_context = mvcc_query_info.scan_context; auto read_segments = parseSegmentSet(select_query.segment_expression_list); auto snap = store->writeNodeBuildRemoteReadSnapshot( @@ -886,7 +885,7 @@ StorageDeltaMerge::writeNodeBuildRemoteReadSnapshot( num_streams, query_info.req_id, read_segments, - scan_context); + mvcc_query_info.scan_context); snap->column_defines = std::make_shared(columns_to_read); diff --git a/dbms/src/Storages/StorageDisaggregatedRemote.cpp b/dbms/src/Storages/StorageDisaggregatedRemote.cpp index a0d7e64087d..1b65ddc307e 100644 --- a/dbms/src/Storages/StorageDisaggregatedRemote.cpp +++ b/dbms/src/Storages/StorageDisaggregatedRemote.cpp @@ -79,7 +79,7 @@ namespace DB namespace ErrorCodes { -extern const int REGION_EPOCH_NOT_MATCH; +extern const int DISAGG_ESTABLISH_RETRYABLE_ERROR; } // namespace ErrorCodes BlockInputStreams StorageDisaggregated::readFromWriteNode( @@ -88,7 +88,7 @@ BlockInputStreams StorageDisaggregated::readFromWriteNode( { DM::RNRemoteReadTaskPtr remote_read_tasks; - pingcap::kv::Backoffer bo(pingcap::kv::copBuildTaskMaxBackoff); + pingcap::kv::Backoffer bo(pingcap::kv::scanMaxBackoff); while (true) { // TODO: We could only retry failed stores. @@ -108,11 +108,11 @@ BlockInputStreams StorageDisaggregated::readFromWriteNode( } catch (DB::Exception & e) { - if (e.code() != ErrorCodes::REGION_EPOCH_NOT_MATCH) + if (e.code() != ErrorCodes::DISAGG_ESTABLISH_RETRYABLE_ERROR) throw; - bo.backoff(pingcap::kv::boRegionMiss, pingcap::Exception(e.message())); - LOG_INFO(log, "meets region epoch not match, retry to build remote read tasks"); + bo.backoff(pingcap::kv::boRegionMiss, pingcap::Exception(e.message(), e.code())); + LOG_INFO(log, "Meets retryable error: {}, retry to build remote read tasks", e.message()); } } @@ -163,33 +163,51 @@ DM::RNRemoteReadTaskPtr StorageDisaggregated::buildDisaggregatedTask( if (resp->has_error()) { - LOG_DEBUG( - log, - "Received EstablishDisaggregated response with error, addr={} err={}", - batch_cop_task.store_addr, - resp->error().msg()); - - if (resp->error().code() == ErrorCodes::REGION_EPOCH_NOT_MATCH) + if (resp->error().code() == ErrorCodes::DISAGG_ESTABLISH_RETRYABLE_ERROR) { - // Refresh region cache and throw an exception for retrying + // Refresh region cache and throw an exception for retrying. + // Note: retry_region's region epoch is not set. We need to recover from the request. + + std::unordered_set retry_regions; for (const auto & retry_region : resp->retry_regions()) + retry_regions.insert(retry_region.id()); + + LOG_INFO( + log, + "Received EstablishDisaggregated response with retryable error: {}, addr={} retry_regions={}", + resp->error().msg(), + batch_cop_task.store_addr, + retry_regions); + + for (const auto & region : req->regions()) { - auto region_id = pingcap::kv::RegionVerID( - retry_region.id(), - retry_region.region_epoch().conf_ver(), - retry_region.region_epoch().version()); - cluster->region_cache->dropRegion(region_id); + if (retry_regions.contains(region.region_id())) + { + auto region_ver_id = pingcap::kv::RegionVerID( + region.region_id(), + region.region_epoch().conf_ver(), + region.region_epoch().version()); + cluster->region_cache->dropRegion(region_ver_id); + } } - throw Exception(resp->error().msg(), ErrorCodes::REGION_EPOCH_NOT_MATCH); + throw Exception( + resp->error().msg(), + ErrorCodes::DISAGG_ESTABLISH_RETRYABLE_ERROR); } else { - // Meet other errors... May be not retirable? - throw Exception(ErrorCodes::LOGICAL_ERROR, - "EstablishDisaggregatedTask failed, addr={} error={} code={}", - batch_cop_task.store_addr, - resp->error().msg(), - resp->error().code()); + LOG_WARNING( + log, + "Received EstablishDisaggregated response with error, addr={} err={}", + batch_cop_task.store_addr, + resp->error().msg()); + + // Meet other errors... May be not retryable? + throw Exception( + resp->error().code(), + "EstablishDisaggregatedTask failed: {}, addr={}", + resp->error().msg(), + batch_cop_task.store_addr); } } diff --git a/dbms/src/Storages/Transaction/LearnerRead.cpp b/dbms/src/Storages/Transaction/LearnerRead.cpp index 2118a67f608..053dea273c1 100644 --- a/dbms/src/Storages/Transaction/LearnerRead.cpp +++ b/dbms/src/Storages/Transaction/LearnerRead.cpp @@ -384,7 +384,7 @@ LearnerReadSnapshot doLearnerRead( region_to_query.region_id, region_to_query.version, RecordKVFormat::DecodedTiKVKeyRangeToDebugString(region_to_query.range_in_table), - RegionException::RegionReadStatusString(status)); + magic_enum::enum_name(status)); unavailable_regions.add(region->id(), status); } }, @@ -469,7 +469,7 @@ void validateQueryInfo( region_query_info.region_id, region_query_info.version, RecordKVFormat::DecodedTiKVKeyRangeToDebugString(region_query_info.range_in_table), - RegionException::RegionReadStatusString(status)); + magic_enum::enum_name(status)); } } diff --git a/dbms/src/Storages/Transaction/LockException.h b/dbms/src/Storages/Transaction/LockException.h index c5c4e517bb6..4dc07883896 100644 --- a/dbms/src/Storages/Transaction/LockException.h +++ b/dbms/src/Storages/Transaction/LockException.h @@ -16,24 +16,22 @@ #include #include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#ifdef __clang__ -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif #include -#pragma GCC diagnostic pop namespace DB { -using RegionVerID = pingcap::kv::RegionVerID; + +namespace ErrorCodes +{ +extern const int REGION_LOCKED; +} // namespace ErrorCodes class LockException : public Exception { public: explicit LockException(RegionID region_id_, LockInfoPtr lock_info) - : region_id(region_id_) + : Exception("Region is locked", ErrorCodes::REGION_LOCKED) + , region_id(region_id_) , lock_info(std::move(lock_info)) {} diff --git a/dbms/src/Storages/Transaction/RegionException.h b/dbms/src/Storages/Transaction/RegionException.h index 54254f03be5..d359a1c3ac4 100644 --- a/dbms/src/Storages/Transaction/RegionException.h +++ b/dbms/src/Storages/Transaction/RegionException.h @@ -17,6 +17,8 @@ #include #include +#include + namespace DB { @@ -32,25 +34,15 @@ class RegionException : public Exception EPOCH_NOT_MATCH, }; - static const char * RegionReadStatusString(RegionReadStatus s) - { - switch (s) - { - case RegionReadStatus::OK: - return "OK"; - case RegionReadStatus::NOT_FOUND: - return "NOT_FOUND"; - case RegionReadStatus::EPOCH_NOT_MATCH: - return "EPOCH_NOT_MATCH"; - } - return "Unknown"; - }; - using UnavailableRegions = std::unordered_set; public: RegionException(UnavailableRegions && unavailable_region_, RegionReadStatus status_) - : Exception(RegionReadStatusString(status_)), unavailable_region(std::move(unavailable_region_)), status(status_) + : Exception(fmt::format( + "Region error {}", + magic_enum::enum_name(status_))) + , unavailable_region(std::move(unavailable_region_)) + , status(status_) {} /// Region could be found with correct epoch, but unavailable (e.g. its lease in proxy has not been built with leader). From ffe4d8133f5fcf5a49babd76eb8bb7e783a873e6 Mon Sep 17 00:00:00 2001 From: JaySon Date: Thu, 16 Mar 2023 02:12:38 +0800 Subject: [PATCH 16/18] Support sharing the same S3 bucket for multiple clusters (#7076) ref pingcap/tiflash#6827 --- .../Flash/Disaggregated/MockS3LockClient.h | 25 +- .../src/Flash/Disaggregated/S3LockService.cpp | 34 +- dbms/src/Flash/Disaggregated/S3LockService.h | 2 - .../tests/gtest_s3_lock_service.cpp | 44 +-- dbms/src/Server/StorageConfigParser.cpp | 11 +- dbms/src/Storages/DeltaMerge/File/DMFile.cpp | 24 +- .../Remote/DataStore/DataStoreS3.cpp | 21 +- ...est_dm_delta_merge_store_fast_add_peer.cpp | 30 +- .../Page/V3/CheckpointFile/Proto/common.proto | 1 + .../Page/V3/Universal/S3LockLocalManager.cpp | 4 +- .../Page/V3/Universal/S3PageReader.cpp | 4 +- .../Universal/UniversalPageStorageService.cpp | 8 +- .../V3/Universal/tests/gtest_checkpoint.cpp | 14 +- .../Universal/tests/gtest_lock_local_mgr.cpp | 26 +- .../V3/Universal/tests/gtest_remote_read.cpp | 16 +- .../Storages/S3/CheckpointManifestS3Set.cpp | 23 +- .../src/Storages/S3/CheckpointManifestS3Set.h | 2 - dbms/src/Storages/S3/FileCache.cpp | 6 +- dbms/src/Storages/S3/MockS3Client.cpp | 69 +++- dbms/src/Storages/S3/MockS3Client.h | 6 +- dbms/src/Storages/S3/S3Common.cpp | 335 ++++++++++++------ dbms/src/Storages/S3/S3Common.h | 79 +++-- dbms/src/Storages/S3/S3GCManager.cpp | 138 ++++---- dbms/src/Storages/S3/S3RandomAccessFile.cpp | 13 +- dbms/src/Storages/S3/S3RandomAccessFile.h | 9 +- dbms/src/Storages/S3/S3WritableFile.cpp | 60 ++-- dbms/src/Storages/S3/S3WritableFile.h | 12 +- .../src/Storages/S3/tests/gtest_filecache.cpp | 32 +- dbms/src/Storages/S3/tests/gtest_s3client.cpp | 82 +++++ dbms/src/Storages/S3/tests/gtest_s3file.cpp | 29 +- .../Storages/S3/tests/gtest_s3gcmanager.cpp | 129 +++---- dbms/src/Storages/Transaction/FastAddPeer.cpp | 5 +- .../tests/gtest_kvstore_fast_add_peer.cpp | 30 +- dbms/src/TestUtils/TiFlashTestEnv.cpp | 16 +- dbms/src/TestUtils/TiFlashTestEnv.h | 12 +- dbms/src/TestUtils/gtests_dbms_main.cpp | 4 +- 36 files changed, 731 insertions(+), 624 deletions(-) create mode 100644 dbms/src/Storages/S3/tests/gtest_s3client.cpp diff --git a/dbms/src/Flash/Disaggregated/MockS3LockClient.h b/dbms/src/Flash/Disaggregated/MockS3LockClient.h index 0aae5f3e866..e6e6c9c998b 100644 --- a/dbms/src/Flash/Disaggregated/MockS3LockClient.h +++ b/dbms/src/Flash/Disaggregated/MockS3LockClient.h @@ -30,13 +30,7 @@ class MockS3LockClient : public IS3LockClient { public: explicit MockS3LockClient(std::shared_ptr c) - : MockS3LockClient(c, c->bucket()) - { - } - - MockS3LockClient(std::shared_ptr c, const String & bucket_) : s3_client(std::move(c)) - , bucket(bucket_) { } @@ -45,16 +39,16 @@ class MockS3LockClient : public IS3LockClient { // If the data file exist and no delmark exist, then create a lock file on `data_file_key` auto view = S3FilenameView::fromKey(data_file_key); - if (!objectExists(*s3_client, bucket, data_file_key)) + if (!objectExists(*s3_client, data_file_key)) { return {false, ""}; } auto delmark_key = view.getDelMarkKey(); - if (objectExists(*s3_client, bucket, delmark_key)) + if (objectExists(*s3_client, delmark_key)) { return {false, ""}; } - uploadEmptyFile(*s3_client, bucket, view.getLockKey(lock_store_id, lock_seq)); + uploadEmptyFile(*s3_client, view.getLockKey(lock_store_id, lock_seq)); return {true, ""}; } @@ -64,23 +58,18 @@ class MockS3LockClient : public IS3LockClient // If there is no lock on the given `data_file_key`, then mark as deleted auto view = S3FilenameView::fromKey(data_file_key); auto lock_prefix = view.getLockPrefix(); - bool any_lock_exist = false; - listPrefix(*s3_client, bucket, lock_prefix, [&any_lock_exist](const Aws::S3::Model::ListObjectsV2Result & result) -> S3::PageResult { - if (!result.GetContents().empty()) - any_lock_exist = true; - return S3::PageResult{.num_keys = result.GetContents().size(), .more = false}; - }); + auto lock_key_opt = S3::anyKeyExistWithPrefix(*s3_client, lock_prefix); + bool any_lock_exist = lock_key_opt.has_value(); if (any_lock_exist) { return {false, ""}; } - uploadEmptyFile(*s3_client, bucket, view.getDelMarkKey()); + uploadEmptyFile(*s3_client, view.getDelMarkKey()); return {true, ""}; } private: - std::shared_ptr s3_client; - String bucket; + std::shared_ptr s3_client; }; } // namespace DB::S3 diff --git a/dbms/src/Flash/Disaggregated/S3LockService.cpp b/dbms/src/Flash/Disaggregated/S3LockService.cpp index 825f57f2d54..f022580f5df 100644 --- a/dbms/src/Flash/Disaggregated/S3LockService.cpp +++ b/dbms/src/Flash/Disaggregated/S3LockService.cpp @@ -200,7 +200,7 @@ bool S3LockService::tryAddLockImpl( auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); // make sure data file exists auto object_key = key_view.isDMFile() ? fmt::format("{}/{}", data_file_key, DM::DMFile::metav2FileName()) : data_file_key; - if (!DB::S3::objectExists(*s3_client, s3_client->bucket(), object_key)) + if (!DB::S3::objectExists(*s3_client, object_key)) { auto * e = response->mutable_result()->mutable_conflict(); e->set_reason(fmt::format("data file not exist, key={}", data_file_key)); @@ -210,7 +210,7 @@ bool S3LockService::tryAddLockImpl( // make sure data file is not mark as deleted const auto delmark_key = key_view.getDelMarkKey(); - if (DB::S3::objectExists(*s3_client, s3_client->bucket(), delmark_key)) + if (DB::S3::objectExists(*s3_client, delmark_key)) { auto * e = response->mutable_result()->mutable_conflict(); e->set_reason(fmt::format("data file is mark deleted, key={} delmark={}", data_file_key, delmark_key)); @@ -228,7 +228,7 @@ bool S3LockService::tryAddLockImpl( } const auto lock_key = key_view.getLockKey(lock_store_id, lock_seq); // upload lock file - DB::S3::uploadEmptyFile(*s3_client, s3_client->bucket(), lock_key); + DB::S3::uploadEmptyFile(*s3_client, lock_key); if (!gc_owner->isOwner()) { // although the owner is changed after lock file is uploaded, but @@ -244,28 +244,6 @@ bool S3LockService::tryAddLockImpl( return true; } -std::optional S3LockService::anyLockExist(const String & lock_prefix) -{ - std::optional lock_key; - auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); - DB::S3::listPrefix( - *s3_client, - s3_client->bucket(), - lock_prefix, - [&lock_key](const Aws::S3::Model::ListObjectsV2Result & result) -> S3::PageResult { - const auto & contents = result.GetContents(); - if (!contents.empty()) - { - lock_key = contents.front().GetKey(); - } - return S3::PageResult{ - .num_keys = contents.size(), - .more = false, // do not need more result - }; - }); - return lock_key; -} - bool S3LockService::tryMarkDeleteImpl(const String & data_file_key, disaggregated::TryMarkDeleteResponse * response) { const S3FilenameView key_view = S3FilenameView::fromKey(data_file_key); @@ -294,7 +272,8 @@ bool S3LockService::tryMarkDeleteImpl(const String & data_file_key, disaggregate // make sure data file has not been locked const auto lock_prefix = key_view.getLockPrefix(); - std::optional lock_key = anyLockExist(lock_prefix); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); + std::optional lock_key = S3::anyKeyExistWithPrefix(*s3_client, lock_prefix); if (lock_key) { auto * e = response->mutable_result()->mutable_conflict(); @@ -318,8 +297,7 @@ bool S3LockService::tryMarkDeleteImpl(const String & data_file_key, disaggregate { tagging = TaggingObjectIsDeleted; } - auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); - DB::S3::uploadEmptyFile(*s3_client, s3_client->bucket(), delmark_key, tagging); + DB::S3::uploadEmptyFile(*s3_client, delmark_key, tagging); if (!gc_owner->isOwner()) { // owner changed happens when delmark is uploading, can not diff --git a/dbms/src/Flash/Disaggregated/S3LockService.h b/dbms/src/Flash/Disaggregated/S3LockService.h index d32214f321b..ac4196a57bd 100644 --- a/dbms/src/Flash/Disaggregated/S3LockService.h +++ b/dbms/src/Flash/Disaggregated/S3LockService.h @@ -100,8 +100,6 @@ class S3LockService final : private boost::noncopyable DataFileMutexPtr getDataFileLatch(const String & data_file_key); - static std::optional anyLockExist(const String & lock_prefix); - private: std::unordered_map file_latch_map; std::mutex file_latch_map_mutex; diff --git a/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp b/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp index 594a6a0529b..12dbf7e2bee 100644 --- a/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp +++ b/dbms/src/Flash/Disaggregated/tests/gtest_s3_lock_service.cpp @@ -55,7 +55,7 @@ class S3LockServiceTest s3_client = client_factory.sharedTiFlashClient(); s3_lock_service = std::make_unique(owner_manager); - ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, s3_client->bucket()); + ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client); createS3DataFiles(); } CATCH @@ -66,7 +66,7 @@ class S3LockServiceTest for (size_t i = 1; i <= 5; ++i) { auto data_filename = S3Filename::fromDMFileOID(DMFileOID{.store_id = store_id, .table_id = physical_table_id, .file_id = dm_file_id}); - DB::S3::uploadEmptyFile(*s3_client, s3_client->bucket(), fmt::format("{}/{}", data_filename.toFullKey(), DM::DMFile::metav2FileName())); + DB::S3::uploadEmptyFile(*s3_client, fmt::format("{}/{}", data_filename.toFullKey(), DM::DMFile::metav2FileName())); ++dm_file_id; } } @@ -78,7 +78,7 @@ class S3LockServiceTest { --dm_file_id; auto data_filename = S3Filename::fromDMFileOID(DMFileOID{.store_id = store_id, .table_id = physical_table_id, .file_id = dm_file_id}); - DB::S3::deleteObject(*s3_client, s3_client->bucket(), data_filename.toFullKey()); + DB::S3::deleteObject(*s3_client, data_filename.toFullKey()); } } @@ -132,9 +132,9 @@ try ASSERT_TRUE(status_code.ok()) << status_code.error_message(); ASSERT_TRUE(response.result().has_success()) << response.ShortDebugString(); - ASSERT_TRUE(DB::S3::objectExists(*s3_client, s3_client->bucket(), lock_key)); + ASSERT_TRUE(DB::S3::objectExists(*s3_client, lock_key)); - DB::S3::deleteObject(*s3_client, s3_client->bucket(), lock_key); + DB::S3::deleteObject(*s3_client, lock_key); } CATCH @@ -153,9 +153,9 @@ try ASSERT_TRUE(status_code.ok()) << status_code.error_message(); ASSERT_TRUE(response.result().has_success()) << response.ShortDebugString(); - ASSERT_TRUE(DB::S3::objectExists(*s3_client, s3_client->bucket(), delmark_key)); + ASSERT_TRUE(DB::S3::objectExists(*s3_client, delmark_key)); - DB::S3::deleteObject(*s3_client, s3_client->bucket(), delmark_key); + DB::S3::deleteObject(*s3_client, delmark_key); } CATCH @@ -175,7 +175,7 @@ try auto status_code = s3_lock_service->tryMarkDelete(&request, &response); ASSERT_TRUE(status_code.ok()) << status_code.error_message(); - ASSERT_TRUE(DB::S3::objectExists(*s3_client, s3_client->bucket(), delmark_key)); + ASSERT_TRUE(DB::S3::objectExists(*s3_client, delmark_key)); } // Try add lock file, should fail @@ -190,10 +190,10 @@ try ASSERT_TRUE(status_code.ok()); ASSERT_TRUE(!response.result().has_success()) << response.ShortDebugString(); ASSERT_TRUE(response.result().has_conflict()) << response.ShortDebugString(); - ASSERT_TRUE(!DB::S3::objectExists(*s3_client, s3_client->bucket(), lock_key)); + ASSERT_TRUE(!DB::S3::objectExists(*s3_client, lock_key)); } - DB::S3::deleteObject(*s3_client, s3_client->bucket(), delmark_key); + DB::S3::deleteObject(*s3_client, delmark_key); } CATCH @@ -216,7 +216,7 @@ try auto status_code = s3_lock_service->tryAddLock(&request, &response); ASSERT_TRUE(status_code.ok()); - ASSERT_TRUE(DB::S3::objectExists(*s3_client, s3_client->bucket(), lock_key)); + ASSERT_TRUE(DB::S3::objectExists(*s3_client, lock_key)); } // Try add delete mark, should fail @@ -230,10 +230,10 @@ try ASSERT_TRUE(status_code.ok()); ASSERT_TRUE(!response.result().has_success()) << response.ShortDebugString(); ASSERT_TRUE(response.result().has_conflict()) << response.ShortDebugString(); - ASSERT_TRUE(!DB::S3::objectExists(*s3_client, s3_client->bucket(), delmark_key)); + ASSERT_TRUE(!DB::S3::objectExists(*s3_client, delmark_key)); } - DB::S3::deleteObject(*s3_client, s3_client->bucket(), lock_key); + DB::S3::deleteObject(*s3_client, lock_key); } CATCH @@ -257,7 +257,7 @@ try ASSERT_TRUE(status_code.ok()); ASSERT_TRUE(!response.result().has_success()) << response.ShortDebugString(); ASSERT_TRUE(response.result().has_conflict()) << response.ShortDebugString(); - ASSERT_TRUE(!DB::S3::objectExists(*s3_client, s3_client->bucket(), lock_key)); + ASSERT_TRUE(!DB::S3::objectExists(*s3_client, lock_key)); } } CATCH @@ -282,9 +282,9 @@ try ASSERT_TRUE(status_code.ok()); ASSERT_TRUE(response.result().has_success()) << response.ShortDebugString(); - ASSERT_TRUE(DB::S3::objectExists(*s3_client, s3_client->bucket(), lock_key)); + ASSERT_TRUE(DB::S3::objectExists(*s3_client, lock_key)); - DB::S3::deleteObject(*s3_client, s3_client->bucket(), lock_key); + DB::S3::deleteObject(*s3_client, lock_key); } }; @@ -316,7 +316,7 @@ try auto status_code = s3_lock_service->tryMarkDelete(&request, &response); ASSERT_TRUE(status_code.ok()); - ASSERT_TRUE(DB::S3::objectExists(*s3_client, s3_client->bucket(), delmark_key)); + ASSERT_TRUE(DB::S3::objectExists(*s3_client, delmark_key)); }; std::vector threads; @@ -331,7 +331,7 @@ try thread.join(); } - DB::S3::deleteObject(*s3_client, s3_client->bucket(), delmark_key); + DB::S3::deleteObject(*s3_client, delmark_key); } CATCH @@ -390,13 +390,13 @@ try auto delmark_key = data_filename.toView().getDelMarkKey(); // Either lock or delete file should exist - if (DB::S3::objectExists(*s3_client, s3_client->bucket(), delmark_key)) + if (DB::S3::objectExists(*s3_client, delmark_key)) { - DB::S3::deleteObject(*s3_client, s3_client->bucket(), delmark_key); + DB::S3::deleteObject(*s3_client, delmark_key); } - else if (DB::S3::objectExists(*s3_client, s3_client->bucket(), lock_key)) + else if (DB::S3::objectExists(*s3_client, lock_key)) { - DB::S3::deleteObject(*s3_client, s3_client->bucket(), lock_key); + DB::S3::deleteObject(*s3_client, lock_key); } else { diff --git a/dbms/src/Server/StorageConfigParser.cpp b/dbms/src/Server/StorageConfigParser.cpp index c6833e2a407..ce56f9dca02 100644 --- a/dbms/src/Server/StorageConfigParser.cpp +++ b/dbms/src/Server/StorageConfigParser.cpp @@ -27,6 +27,7 @@ #endif #include +#include #include #include #include @@ -50,11 +51,11 @@ namespace ErrorCodes extern const int INVALID_CONFIG_PARAMETER; } // namespace ErrorCodes -static std::string getCanonicalPath(std::string path) +static std::string getCanonicalPath(std::string path, std::string_view hint = "path") { Poco::trimInPlace(path); if (path.empty()) - throw Exception("path configuration parameter is empty"); + throw Exception(ErrorCodes::INVALID_CONFIG_PARAMETER, "'{}' configuration parameter is empty", hint); if (path.back() != '/') path += '/'; return path; @@ -550,7 +551,7 @@ void StorageS3Config::parse(const String & content, const LoggerPtr & log) readConfig(table, "request_timeout_ms", request_timeout_ms); RUNTIME_CHECK(request_timeout_ms > 0); readConfig(table, "root", root); - RUNTIME_CHECK(!root.empty()); + getCanonicalPath(root, "root"); // ensure not empty and ends with '/' auto read_s3_auth_info_from_env = [&]() { access_key_id = Poco::Environment::get(S3_ACCESS_KEY_ID, /*default*/ ""); @@ -571,10 +572,12 @@ void StorageS3Config::parse(const String & content, const LoggerPtr & log) LOG_INFO( log, - "endpoint={} bucket={} max_connections={} connection_timeout_ms={} " + "endpoint={} bucket={} root={} " + "max_connections={} connection_timeout_ms={} " "request_timeout_ms={} access_key_id_size={} secret_access_key_size={}", endpoint, bucket, + root, max_connections, connection_timeout_ms, request_timeout_ms, diff --git a/dbms/src/Storages/DeltaMerge/File/DMFile.cpp b/dbms/src/Storages/DeltaMerge/File/DMFile.cpp index 06a599300c0..0c88cd8ac6e 100644 --- a/dbms/src/Storages/DeltaMerge/File/DMFile.cpp +++ b/dbms/src/Storages/DeltaMerge/File/DMFile.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -647,24 +648,17 @@ std::vector DMFile::listLocal(const String & parent_path) std::vector DMFile::listS3(const String & parent_path) { std::vector filenames; - auto client = S3::ClientFactory::instance().sharedClient(); - const auto & bucket = S3::ClientFactory::instance().bucket(); + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); auto list_prefix = parent_path + "/"; - S3::listPrefix( + S3::listPrefixWithDelimiter( *client, - bucket, list_prefix, /*delimiter*/ "/", - [&filenames, &list_prefix](const Aws::S3::Model::ListObjectsV2Result & result) { - const Aws::Vector & prefixes = result.GetCommonPrefixes(); - filenames.reserve(filenames.size() + prefixes.size()); - for (const auto & prefix : prefixes) - { - RUNTIME_CHECK(prefix.GetPrefix().size() > list_prefix.size(), prefix.GetPrefix(), list_prefix); - auto short_name_size = prefix.GetPrefix().size() - list_prefix.size() - 1; // `1` for the delimiter in last. - filenames.push_back(prefix.GetPrefix().substr(list_prefix.size(), short_name_size)); // Cut prefix and last delimiter. - } - return S3::PageResult{.num_keys = prefixes.size(), .more = true}; + [&filenames, &list_prefix](const Aws::S3::Model::CommonPrefix & prefix) { + RUNTIME_CHECK(prefix.GetPrefix().size() > list_prefix.size(), prefix.GetPrefix(), list_prefix); + auto short_name_size = prefix.GetPrefix().size() - list_prefix.size() - 1; // `1` for the delimiter in last. + filenames.push_back(prefix.GetPrefix().substr(list_prefix.size(), short_name_size)); // Cut prefix and last delimiter. + return S3::PageResult{.num_keys = 1, .more = true}; }); return filenames; } @@ -1062,4 +1056,4 @@ void DMFile::switchToRemote(const S3::DMFileOID & oid) } // namespace DM -} // namespace DB \ No newline at end of file +} // namespace DB diff --git a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp index dc7b8e9d61b..d3a93849f24 100644 --- a/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp +++ b/dbms/src/Storages/DeltaMerge/Remote/DataStore/DataStoreS3.cpp @@ -37,8 +37,7 @@ void DataStoreS3::putDMFile(DMFilePtr local_dmfile, const S3::DMFileOID & oid, b const auto remote_dir = S3::S3Filename::fromDMFileOID(oid).toFullKey(); LOG_DEBUG(log, "Start upload DMFile, local_dir={} remote_dir={} local_files={}", local_dir, remote_dir, local_files); - auto s3_client = S3::ClientFactory::instance().sharedClient(); - const auto & bucket = S3::ClientFactory::instance().bucket(); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); std::vector> upload_results; for (const auto & fname : local_files) @@ -52,7 +51,7 @@ void DataStoreS3::putDMFile(DMFilePtr local_dmfile, const S3::DMFileOID & oid, b auto remote_fname = fmt::format("{}/{}", remote_dir, fname); auto task = std::make_shared>( [&, local_fname = std::move(local_fname), remote_fname = std::move(remote_fname)]() { - S3::uploadFile(*s3_client, bucket, local_fname, remote_fname); + S3::uploadFile(*s3_client, local_fname, remote_fname); }); upload_results.push_back(task->get_future()); DataStoreS3Pool::get().scheduleOrThrowOnError([task]() { (*task)(); }); @@ -65,7 +64,7 @@ void DataStoreS3::putDMFile(DMFilePtr local_dmfile, const S3::DMFileOID & oid, b // Only when the meta upload is successful, the dmfile upload can be considered successful. auto local_meta_fname = fmt::format("{}/{}", local_dir, DMFile::metav2FileName()); auto remote_meta_fname = fmt::format("{}/{}", remote_dir, DMFile::metav2FileName()); - S3::uploadFile(*s3_client, bucket, local_meta_fname, remote_meta_fname); + S3::uploadFile(*s3_client, local_meta_fname, remote_meta_fname); if (remove_local) { @@ -76,8 +75,7 @@ void DataStoreS3::putDMFile(DMFilePtr local_dmfile, const S3::DMFileOID & oid, b bool DataStoreS3::putCheckpointFiles(const PS::V3::LocalCheckpointFiles & local_files, StoreID store_id, UInt64 upload_seq) { - auto s3_client = S3::ClientFactory::instance().sharedClient(); - const auto & bucket = S3::ClientFactory::instance().bucket(); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); /// First upload all CheckpointData files and their locks, /// then upload the CheckpointManifest to make the files within @@ -91,8 +89,8 @@ bool DataStoreS3::putCheckpointFiles(const PS::V3::LocalCheckpointFiles & local_ const auto & local_datafile = local_files.data_files[idx]; auto s3key = S3::S3Filename::newCheckpointData(store_id, upload_seq, idx); auto lock_key = s3key.toView().getLockKey(store_id, upload_seq); - S3::uploadFile(*s3_client, bucket, local_datafile, s3key.toFullKey()); - S3::uploadEmptyFile(*s3_client, bucket, lock_key); + S3::uploadFile(*s3_client, local_datafile, s3key.toFullKey()); + S3::uploadEmptyFile(*s3_client, lock_key); }); upload_results.push_back(task->get_future()); DataStoreS3Pool::get().scheduleOrThrowOnError([task] { (*task)(); }); @@ -104,15 +102,14 @@ bool DataStoreS3::putCheckpointFiles(const PS::V3::LocalCheckpointFiles & local_ // upload manifest after all CheckpointData uploaded auto s3key = S3::S3Filename::newCheckpointManifest(store_id, upload_seq); - S3::uploadFile(*s3_client, bucket, local_files.manifest_file, s3key.toFullKey()); + S3::uploadFile(*s3_client, local_files.manifest_file, s3key.toFullKey()); return true; // upload success } void DataStoreS3::copyToLocal(const S3::DMFileOID & remote_oid, const std::vector & target_short_fnames, const String & local_dir) { - auto s3_client = S3::ClientFactory::instance().sharedClient(); - const auto & bucket = S3::ClientFactory::instance().bucket(); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); const auto remote_dir = S3::S3Filename::fromDMFileOID(remote_oid).toFullKey(); std::vector> results; for (const auto & fname : target_short_fnames) @@ -122,7 +119,7 @@ void DataStoreS3::copyToLocal(const S3::DMFileOID & remote_oid, const std::vecto auto task = std::make_shared>( [&, local_fname = std::move(local_fname), remote_fname = std::move(remote_fname)]() { auto tmp_fname = fmt::format("{}.tmp", local_fname); - S3::downloadFile(*s3_client, bucket, tmp_fname, remote_fname); + S3::downloadFile(*s3_client, tmp_fname, remote_fname); Poco::File(tmp_fname).renameTo(local_fname); }); results.push_back(task->get_future()); diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_merge_store_fast_add_peer.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_merge_store_fast_add_peer.cpp index fc2c3648a7c..dd6affa3ea0 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_merge_store_fast_add_peer.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_merge_store_fast_add_peer.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -33,10 +34,9 @@ #include #include #include +#include #include -#include "DataStreams/OneBlockInputStream.h" - namespace DB { @@ -60,7 +60,8 @@ class DeltaMergeStoreTestFastAddPeer : public DB::base::TiFlashStorageTestBasic void SetUp() override { FailPointHelper::enableFailPoint(FailPoints::force_use_dmfile_format_v3); - ASSERT_TRUE(createBucketIfNotExist()); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); + ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client)); TiFlashStorageTestBasic::SetUp(); auto & global_context = TiFlashTestEnv::getGlobalContext(); if (global_context.getSharedContextDisagg()->remote_data_store == nullptr) @@ -163,29 +164,6 @@ class DeltaMergeStoreTestFastAddPeer : public DB::base::TiFlashStorageTestBasic return {handle_range, {external_file}}; // There are some duplicated info. This is to minimize the change to our test code. } - bool createBucketIfNotExist() - { - auto s3_client = S3::ClientFactory::instance().sharedClient(); - auto bucket = S3::ClientFactory::instance().bucket(); - Aws::S3::Model::CreateBucketRequest request; - request.SetBucket(bucket); - auto outcome = s3_client->CreateBucket(request); - if (outcome.IsSuccess()) - { - LOG_DEBUG(Logger::get(), "Created bucket {}", bucket); - } - else if (outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou") - { - LOG_DEBUG(Logger::get(), "Bucket {} already exist", bucket); - } - else - { - const auto & err = outcome.GetError(); - LOG_ERROR(Logger::get(), "CreateBucket: {}:{}", err.GetExceptionName(), err.GetMessage()); - } - return outcome.IsSuccess() || outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou"; - } - void dumpCheckpoint() { auto temp_dir = getTemporaryPath() + "/"; diff --git a/dbms/src/Storages/Page/V3/CheckpointFile/Proto/common.proto b/dbms/src/Storages/Page/V3/CheckpointFile/Proto/common.proto index 9954bd95e91..7b8935906a1 100644 --- a/dbms/src/Storages/Page/V3/CheckpointFile/Proto/common.proto +++ b/dbms/src/Storages/Page/V3/CheckpointFile/Proto/common.proto @@ -27,4 +27,5 @@ message WriterInfo { message RemoteInfo { string type_name = 1; // e.g. "S3" / "LocalFS" string name = 2; // Remote-type specific name for description purpose. + string root = 3; // Identifier for the cluster. It is the `storage.s3.root` when using S3 } diff --git a/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.cpp b/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.cpp index 49de7bd6b80..4b8c9156dbe 100644 --- a/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.cpp +++ b/dbms/src/Storages/Page/V3/Universal/S3LockLocalManager.cpp @@ -53,7 +53,7 @@ void S3LockLocalManager::initStoreInfo(StoreID actual_store_id, DB::S3::S3LockCl // we need to restore the last_upload_sequence from S3 auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); - const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, s3_client->bucket(), actual_store_id); + const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, actual_store_id); if (!manifests.empty()) { last_upload_sequence = manifests.latestUploadSequence(); @@ -171,7 +171,7 @@ String S3LockLocalManager::createS3Lock(const String & datafile_key, const S3::S // directly create lock through S3 client // TODO: handle s3 network error and retry? auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); - S3::uploadEmptyFile(*s3_client, s3_client->bucket(), lockkey); + S3::uploadEmptyFile(*s3_client, lockkey); LOG_DEBUG(log, "S3 lock created for local datafile, lockkey={}", lockkey); } else diff --git a/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp b/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp index 64481acd322..20aa1493045 100644 --- a/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp +++ b/dbms/src/Storages/Page/V3/Universal/S3PageReader.cpp @@ -34,13 +34,13 @@ Page S3PageReader::read(const UniversalPageIdAndEntry & page_id_and_entry) if (remote_name_view.isLockFile()) { #endif - remote_file = std::make_shared(s3_client, s3_client->bucket(), remote_name_view.asDataFile().toFullKey()); + remote_file = std::make_shared(s3_client, remote_name_view.asDataFile().toFullKey()); #ifdef DBMS_PUBLIC_GTEST } else { // Just used in unit test which want to just focus on read write logic - remote_file = std::make_shared(s3_client, s3_client->bucket(), *location.data_file_id); + remote_file = std::make_shared(s3_client, *location.data_file_id); } #endif ReadBufferFromRandomAccessFile buf(remote_file); diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp index d1a467fcabb..81e0b1f8fa3 100644 --- a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorageService.cpp @@ -126,7 +126,10 @@ bool UniversalPageStorageService::uploadCheckpoint() return uploadCheckpointImpl(store_info, s3lock_client, remote_store); } -bool UniversalPageStorageService::uploadCheckpointImpl(const metapb::Store & store_info, const S3::S3LockClientPtr & s3lock_client, const DM::Remote::IDataStorePtr & remote_store) +bool UniversalPageStorageService::uploadCheckpointImpl( + const metapb::Store & store_info, + const S3::S3LockClientPtr & s3lock_client, + const DM::Remote::IDataStorePtr & remote_store) { uni_page_storage->initLocksLocalManager(store_info.id(), s3lock_client); const auto upload_info = uni_page_storage->allocateNewUploadLocksInfo(); @@ -140,8 +143,11 @@ bool UniversalPageStorageService::uploadCheckpointImpl(const metapb::Store & sto auto * ri = wi.mutable_remote_info(); ri->set_type_name("S3"); // ri->set_name(); this field is not used currently + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); + ri->set_root(client->root()); } + auto local_dir = Poco::Path(global_context.getTemporaryPath() + fmt::format("/checkpoint_upload_{}", upload_info.upload_sequence)).absolute(); Poco::File(local_dir).createDirectories(); auto local_dir_str = local_dir.toString() + "/"; diff --git a/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp b/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp index 538280dca1c..5d33614b377 100644 --- a/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp +++ b/dbms/src/Storages/Page/V3/Universal/tests/gtest_checkpoint.cpp @@ -758,9 +758,8 @@ class UniversalPageStorageServiceCheckpointTest : public DB::base::TiFlashStorag delegator, PageStorageConfig{.blob_heavy_gc_valid_rate = 1.0}); log = Logger::get("UniversalPageStorageServiceCheckpointTest"); - s3_client = S3::ClientFactory::instance().sharedClient(); - bucket = S3::ClientFactory::instance().bucket(); - ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket)); + s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); + ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client)); } protected: @@ -791,8 +790,7 @@ class UniversalPageStorageServiceCheckpointTest : public DB::base::TiFlashStorag protected: UniversalPageStorageServicePtr uni_ps_service; - std::shared_ptr s3_client; - String bucket; + std::shared_ptr s3_client; UInt64 tag = 0; UInt64 store_id = 2; @@ -805,7 +803,7 @@ try auto page_storage = uni_ps_service->getUniversalPageStorage(); auto store_info = metapb::Store{}; store_info.set_id(store_id); - auto s3lock_client = std::make_shared(s3_client, bucket); + auto s3lock_client = std::make_shared(s3_client); auto remote_store = std::make_shared(::DB::tests::TiFlashTestEnv::getMockFileProvider()); // Mock normal writes { @@ -875,8 +873,8 @@ try auto ingest_from_dtfile = S3::S3Filename::fromDMFileOID(S3::DMFileOID{.store_id = another_store_id, .table_id = 50, .file_id = 999}); { // create object on s3 for locking - S3::uploadEmptyFile(*s3_client, bucket, ingest_from_data_file.toFullKey()); - S3::uploadEmptyFile(*s3_client, bucket, ingest_from_dtfile.toFullKey()); + S3::uploadEmptyFile(*s3_client, ingest_from_data_file.toFullKey()); + S3::uploadEmptyFile(*s3_client, ingest_from_dtfile.toFullKey()); UniversalWriteBatch batch; PS::V3::CheckpointLocation loc21{ diff --git a/dbms/src/Storages/Page/V3/Universal/tests/gtest_lock_local_mgr.cpp b/dbms/src/Storages/Page/V3/Universal/tests/gtest_lock_local_mgr.cpp index 5584ac9b4a4..9baa7ce0b52 100644 --- a/dbms/src/Storages/Page/V3/Universal/tests/gtest_lock_local_mgr.cpp +++ b/dbms/src/Storages/Page/V3/Universal/tests/gtest_lock_local_mgr.cpp @@ -39,24 +39,22 @@ class S3LockLocalManagerTest : public testing::Test { public: S3LockLocalManagerTest() - : s3_client(S3::ClientFactory::instance().sharedClient()) - , bucket(S3::ClientFactory::instance().bucket()) + : s3_client(S3::ClientFactory::instance().sharedTiFlashClient()) , log(Logger::get()) {} void SetUp() override { - ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket); + ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client); } void TearDown() override { - ::DB::tests::TiFlashTestEnv::deleteBucket(*s3_client, bucket); + ::DB::tests::TiFlashTestEnv::deleteBucket(*s3_client); } protected: - std::shared_ptr s3_client; - String bucket; + std::shared_ptr s3_client; LoggerPtr log; }; @@ -65,7 +63,7 @@ try { StoreID this_store_id = 100; PS::V3::S3LockLocalManager mgr; - auto mock_s3lock_client = std::make_shared(s3_client, bucket); + auto mock_s3lock_client = std::make_shared(s3_client); mgr.initStoreInfo(this_store_id, mock_s3lock_client); auto info = mgr.allocateNewUploadLocksInfo(); @@ -81,7 +79,7 @@ try auto s3name_dtfile = S3::S3Filename::fromDMFileOID(S3::DMFileOID{.store_id = old_store_id, .table_id = 10, .file_id = 5}); auto s3name_datafile = S3::S3Filename::newCheckpointData(old_store_id, old_store_seq, 1); { - S3::uploadEmptyFile(*s3_client, bucket, s3name_dtfile.toFullKey()); + S3::uploadEmptyFile(*s3_client, s3name_dtfile.toFullKey()); PS::V3::CheckpointLocation loc{ .data_file_id = std::make_shared(s3name_dtfile.toFullKey()), .offset_in_file = 0, @@ -91,7 +89,7 @@ try } { auto key = std::make_shared(s3name_datafile.toFullKey()); - S3::uploadEmptyFile(*s3_client, bucket, *key); + S3::uploadEmptyFile(*s3_client, *key); PS::V3::CheckpointLocation loc2{ .data_file_id = key, .offset_in_file = 0, @@ -117,8 +115,8 @@ try ASSERT_GT(info.pre_lock_keys.count(expected_lockkey1), 0) << fmt::format("{}", lock_by_seq); const String expected_lockkey2 = s3name_dtfile.toView().getLockKey(this_store_id, info.upload_sequence); ASSERT_GT(info.pre_lock_keys.count(expected_lockkey2), 0) << fmt::format("{}", info.pre_lock_keys); - EXPECT_TRUE(S3::objectExists(*s3_client, bucket, expected_lockkey1)); - EXPECT_TRUE(S3::objectExists(*s3_client, bucket, expected_lockkey2)); + EXPECT_TRUE(S3::objectExists(*s3_client, expected_lockkey1)); + EXPECT_TRUE(S3::objectExists(*s3_client, expected_lockkey2)); // pre_lock_keys won't be cleaned after `allocateNewUploadLocksInfo` info = mgr.allocateNewUploadLocksInfo(); @@ -140,7 +138,7 @@ try { StoreID this_store_id = 100; PS::V3::S3LockLocalManager mgr; - auto mock_s3lock_client = std::make_shared(s3_client, bucket); + auto mock_s3lock_client = std::make_shared(s3_client); mgr.initStoreInfo(this_store_id, mock_s3lock_client); // Mock FAP ingest following pages from another store @@ -152,7 +150,7 @@ try auto s3name_dtfile = S3::S3Filename::fromDMFileOID(S3::DMFileOID{.store_id = old_store_id, .table_id = 10, .file_id = 5}); auto s3name_datafile = S3::S3Filename::newCheckpointData(old_store_id, old_store_seq, 1); { - S3::uploadEmptyFile(*s3_client, bucket, s3name_dtfile.toFullKey()); + S3::uploadEmptyFile(*s3_client, s3name_dtfile.toFullKey()); PS::V3::CheckpointLocation loc{ .data_file_id = std::make_shared(s3name_dtfile.toFullKey()), .offset_in_file = 0, @@ -162,7 +160,7 @@ try } { auto key = std::make_shared(s3name_datafile.toFullKey()); - S3::uploadEmptyFile(*s3_client, bucket, *key); + S3::uploadEmptyFile(*s3_client, *key); PS::V3::CheckpointLocation loc2{ .data_file_id = key, .offset_in_file = 0, diff --git a/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp b/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp index 9ba82585da2..6c35ea3ff8a 100644 --- a/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp +++ b/dbms/src/Storages/Page/V3/Universal/tests/gtest_remote_read.cpp @@ -56,10 +56,9 @@ class UniPageStorageRemoteReadTest : public DB::base::TiFlashStorageTestBasic createIfNotExist(path); file_provider = DB::tests::TiFlashTestEnv::getDefaultFileProvider(); delegator = std::make_shared(path); - s3_client = S3::ClientFactory::instance().sharedClient(); - bucket = S3::ClientFactory::instance().bucket(); + s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); - ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket)); + ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client)); page_storage = UniversalPageStorage::create("write", delegator, config, file_provider); page_storage->restore(); @@ -76,7 +75,7 @@ class UniPageStorageRemoteReadTest : public DB::base::TiFlashStorageTestBasic delegator = std::make_shared(path); auto storage = UniversalPageStorage::create("test.t", delegator, config_, file_provider); storage->restore(); - auto mock_s3lock_client = std::make_shared(s3_client, bucket); + auto mock_s3lock_client = std::make_shared(s3_client); storage->initLocksLocalManager(100, mock_s3lock_client); return storage; } @@ -86,7 +85,7 @@ class UniPageStorageRemoteReadTest : public DB::base::TiFlashStorageTestBasic const String & full_path = dir + "/" + f_name; ReadBufferPtr src_buf = std::make_shared(full_path); S3::WriteSettings write_setting; - WritableFilePtr dst_file = std::make_shared(s3_client, bucket, f_name, write_setting); + WritableFilePtr dst_file = std::make_shared(s3_client, f_name, write_setting); WriteBufferPtr dst_buf = std::make_shared(dst_file); copyData(*src_buf, *dst_buf); dst_buf->next(); @@ -97,7 +96,7 @@ class UniPageStorageRemoteReadTest : public DB::base::TiFlashStorageTestBasic protected: void deleteBucket() { - ::DB::tests::TiFlashTestEnv::deleteBucket(*s3_client, bucket); + ::DB::tests::TiFlashTestEnv::deleteBucket(*s3_client); } protected: @@ -105,8 +104,7 @@ class UniPageStorageRemoteReadTest : public DB::base::TiFlashStorageTestBasic String remote_dir; FileProviderPtr file_provider; PSDiskDelegatorPtr delegator; - std::shared_ptr s3_client; - String bucket; + std::shared_ptr s3_client; PageStorageConfig config; std::shared_ptr page_storage; @@ -321,7 +319,7 @@ try } // create an empty bucket because reload will try to read from S3 - ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket)); + ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client)); reload(); { diff --git a/dbms/src/Storages/S3/CheckpointManifestS3Set.cpp b/dbms/src/Storages/S3/CheckpointManifestS3Set.cpp index 894afc2b354..7cd8ac85c43 100644 --- a/dbms/src/Storages/S3/CheckpointManifestS3Set.cpp +++ b/dbms/src/Storages/S3/CheckpointManifestS3Set.cpp @@ -22,28 +22,17 @@ namespace DB::S3 { CheckpointManifestS3Set CheckpointManifestS3Set::getFromS3(const S3::TiFlashS3Client & client, StoreID store_id) -{ - return CheckpointManifestS3Set::getFromS3(client, client.bucket(), store_id); -} - -CheckpointManifestS3Set -CheckpointManifestS3Set::getFromS3(const Aws::S3::S3Client & client, const String & bucket, StoreID store_id) { const auto manifest_prefix = S3::S3Filename::fromStoreId(store_id).toManifestPrefix(); std::vector manifests; - listPrefix(client, bucket, manifest_prefix, [&](const Aws::S3::Model::ListObjectsV2Result & result) { - const auto & objects = result.GetContents(); - manifests.reserve(manifests.size() + objects.size()); - for (const auto & object : objects) - { - const auto & mf_key = object.GetKey(); - // also store the object.GetLastModified() for removing - // outdated manifest objects - manifests.emplace_back(CheckpointManifestS3Object{mf_key, object.GetLastModified()}); - } - return DB::S3::PageResult{.num_keys = objects.size(), .more = true}; + S3::listPrefix(client, manifest_prefix, [&](const Aws::S3::Model::Object & object) { + const auto & mf_key = object.GetKey(); + // also store the object.GetLastModified() for removing + // outdated manifest objects + manifests.emplace_back(CheckpointManifestS3Object{mf_key, object.GetLastModified()}); + return DB::S3::PageResult{.num_keys = 1, .more = true}; }); return CheckpointManifestS3Set::create(manifests); } diff --git a/dbms/src/Storages/S3/CheckpointManifestS3Set.h b/dbms/src/Storages/S3/CheckpointManifestS3Set.h index d88e090e40e..21b1328dce9 100644 --- a/dbms/src/Storages/S3/CheckpointManifestS3Set.h +++ b/dbms/src/Storages/S3/CheckpointManifestS3Set.h @@ -38,8 +38,6 @@ class CheckpointManifestS3Set public: static CheckpointManifestS3Set getFromS3(const S3::TiFlashS3Client & client, StoreID store_id); - static CheckpointManifestS3Set getFromS3(const Aws::S3::S3Client & client, const String & bucket, StoreID store_id); - static CheckpointManifestS3Set create(const std::vector & manifest_keys); ALWAYS_INLINE bool empty() const { return manifests.empty(); } diff --git a/dbms/src/Storages/S3/FileCache.cpp b/dbms/src/Storages/S3/FileCache.cpp index 95bcb45e068..b9e335aad8d 100644 --- a/dbms/src/Storages/S3/FileCache.cpp +++ b/dbms/src/Storages/S3/FileCache.cpp @@ -378,11 +378,9 @@ bool FileCache::finalizeReservedSize(FileType reserve_for, UInt64 reserved_size, void FileCache::downloadImpl(const String & s3_key, FileSegmentPtr & file_seg) { Stopwatch sw; - auto client = S3::ClientFactory::instance().sharedClient(); - const auto & bucket = S3::ClientFactory::instance().bucket(); + auto client = S3::ClientFactory::instance().sharedTiFlashClient(); Aws::S3::Model::GetObjectRequest req; - req.SetBucket(bucket); - req.SetKey(s3_key); + client->setBucketAndKeyWithRoot(req, s3_key); ProfileEvents::increment(ProfileEvents::S3GetObject); auto outcome = client->GetObject(req); if (!outcome.IsSuccess()) diff --git a/dbms/src/Storages/S3/MockS3Client.cpp b/dbms/src/Storages/S3/MockS3Client.cpp index 44b988c248c..d074a80ef39 100644 --- a/dbms/src/Storages/S3/MockS3Client.cpp +++ b/dbms/src/Storages/S3/MockS3Client.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,13 @@ namespace DB::S3::tests { using namespace Aws::S3; +String MockS3Client::normalizedKey(String ori_key) +{ + if (ori_key.starts_with('/')) + return ori_key.substr(1, ori_key.size()); + return ori_key; +} + Model::GetObjectOutcome MockS3Client::GetObject(const Model::GetObjectRequest & request) const { std::lock_guard lock(mtx); @@ -63,7 +71,7 @@ Model::GetObjectOutcome MockS3Client::GetObject(const Model::GetObjectRequest & return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuchBucket"); } const auto & bucket_storage = itr->second; - auto itr_obj = bucket_storage.find(request.GetKey()); + auto itr_obj = bucket_storage.find(normalizedKey(request.GetKey())); if (itr_obj == bucket_storage.end()) { return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuchKey"); @@ -84,7 +92,7 @@ Model::PutObjectOutcome MockS3Client::PutObject(const Model::PutObjectRequest & return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuchBucket"); } auto & bucket_storage = itr->second; - bucket_storage[request.GetKey()] = String{std::istreambuf_iterator(*request.GetBody()), {}}; + bucket_storage[normalizedKey(request.GetKey())] = String{std::istreambuf_iterator(*request.GetBody()), {}}; return Model::PutObjectResult{}; } @@ -111,8 +119,8 @@ Model::CopyObjectOutcome MockS3Client::CopyObject(const Model::CopyObjectRequest auto src_bucket_storage = src_itr->second; auto dst_bucket_storage = dst_itr->second; RUNTIME_CHECK(src_bucket_storage.contains(src_key), src_bucket, src_key); - dst_bucket_storage[request.GetKey()] = src_bucket_storage[src_key]; - storage_tagging[request.GetBucket()][request.GetKey()] = request.GetTagging(); + dst_bucket_storage[normalizedKey(request.GetKey())] = src_bucket_storage[src_key]; + storage_tagging[request.GetBucket()][normalizedKey(request.GetKey())] = request.GetTagging(); return Model::CopyObjectResult{}; } @@ -124,9 +132,9 @@ Model::GetObjectTaggingOutcome MockS3Client::GetObjectTagging(const Model::GetOb { return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuckBucket"); } - auto taggings = storage_tagging[request.GetBucket()][request.GetKey()]; + auto taggings = storage_tagging[request.GetBucket()][normalizedKey(request.GetKey())]; auto pos = taggings.find('='); - RUNTIME_CHECK(pos != String::npos, pos, taggings.size()); + RUNTIME_CHECK(pos != String::npos, taggings, pos, taggings.size()); Aws::S3::Model::Tag tag; tag.WithKey(taggings.substr(0, pos)) .WithValue(taggings.substr(pos + 1, taggings.size())); @@ -144,7 +152,7 @@ Model::DeleteObjectOutcome MockS3Client::DeleteObject(const Model::DeleteObjectR return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuchBucket"); } auto & bucket_storage = itr->second; - bucket_storage.erase(request.GetKey()); + bucket_storage.erase(normalizedKey(request.GetKey())); return Model::DeleteObjectResult{}; } @@ -158,18 +166,43 @@ Model::ListObjectsV2Outcome MockS3Client::ListObjectsV2(const Model::ListObjects } const auto & bucket_storage = itr->second; Model::ListObjectsV2Result result; - for (auto itr_obj = bucket_storage.lower_bound(request.GetPrefix()); itr_obj != bucket_storage.end(); ++itr_obj) + RUNTIME_CHECK(!request.DelimiterHasBeenSet() || request.GetDelimiter() == "/", request.GetDelimiter()); + + auto normalized_prefix = normalizedKey(request.GetPrefix()); + if (!request.DelimiterHasBeenSet()) + { + for (auto itr_obj = bucket_storage.lower_bound(normalized_prefix); itr_obj != bucket_storage.end(); ++itr_obj) + { + if (startsWith(itr_obj->first, normalized_prefix)) + { + Model::Object obj; + obj.SetKey(itr_obj->first); + obj.SetSize(itr_obj->second.size()); + result.AddContents(std::move(obj)); + } + else + { + break; + } + } + } + else { - if (startsWith(itr_obj->first, request.GetPrefix())) + std::set common_prefix; + const auto & delimiter = request.GetDelimiter(); + for (auto itr_obj = bucket_storage.lower_bound(normalized_prefix); itr_obj != bucket_storage.end(); ++itr_obj) { - Model::Object obj; - obj.SetKey(itr_obj->first); - obj.SetSize(itr_obj->second.size()); - result.AddContents(std::move(obj)); + if (!startsWith(itr_obj->first, normalized_prefix)) + break; + const auto & key = itr_obj->first; + auto pos = key.find(delimiter, normalized_prefix.size()); + if (pos == String::npos) + continue; + common_prefix.insert(key.substr(0, pos + delimiter.size())); } - else + for (const auto & p : common_prefix) { - break; + result.AddCommonPrefixes(Model::CommonPrefix().WithPrefix(p)); } } return result; @@ -184,7 +217,7 @@ Model::HeadObjectOutcome MockS3Client::HeadObject(const Model::HeadObjectRequest return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuchBucket"); } const auto & bucket_storage = itr->second; - auto itr_obj = bucket_storage.find(request.GetKey()); + auto itr_obj = bucket_storage.find(normalizedKey(request.GetKey())); if (itr_obj != bucket_storage.end()) { auto r = Model::HeadObjectResult{}; @@ -192,7 +225,7 @@ Model::HeadObjectOutcome MockS3Client::HeadObject(const Model::HeadObjectRequest if (auto v = FailPointHelper::getFailPointVal(FailPoints::force_set_mocked_s3_object_mtime); v) { auto m = std::any_cast>(v.value()); - if (auto iter_m = m.find(request.GetKey()); iter_m != m.end()) + if (auto iter_m = m.find(normalizedKey(request.GetKey())); iter_m != m.end()) { r.SetLastModified(iter_m->second); } @@ -237,7 +270,7 @@ Model::CompleteMultipartUploadOutcome MockS3Client::CompleteMultipartUpload(cons return Aws::S3::S3ErrorMapper::GetErrorForName("NoSuchBucket"); } auto & bucket_storage = itr->second; - bucket_storage[request.GetKey()] = s; + bucket_storage[normalizedKey(request.GetKey())] = s; return Model::CompleteMultipartUploadResult{}; } diff --git a/dbms/src/Storages/S3/MockS3Client.h b/dbms/src/Storages/S3/MockS3Client.h index 069c11c1712..d967d1c6491 100644 --- a/dbms/src/Storages/S3/MockS3Client.h +++ b/dbms/src/Storages/S3/MockS3Client.h @@ -25,8 +25,8 @@ using namespace Aws::S3; class MockS3Client final : public S3::TiFlashS3Client { public: - explicit MockS3Client(const String & bucket = "") - : TiFlashS3Client(bucket) + explicit MockS3Client(const String & bucket, const String & root) + : TiFlashS3Client(bucket, root) {} ~MockS3Client() override = default; @@ -45,6 +45,8 @@ class MockS3Client final : public S3::TiFlashS3Client Model::GetObjectTaggingOutcome GetObjectTagging(const Model::GetObjectTaggingRequest & request) const override; private: + static String normalizedKey(String ori_key); + // Object key -> Object data using BucketStorage = std::map; // Object key -> Object tagging diff --git a/dbms/src/Storages/S3/S3Common.cpp b/dbms/src/Storages/S3/S3Common.cpp index a37d6cc2a14..69897e7c438 100644 --- a/dbms/src/Storages/S3/S3Common.cpp +++ b/dbms/src/Storages/S3/S3Common.cpp @@ -12,8 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include +#include #include #include #include @@ -125,24 +127,49 @@ class AWSLogger final : public Aws::Utils::Logging::LogSystemInterface namespace DB::S3 { -TiFlashS3Client::TiFlashS3Client(const String & bucket_name_) +// ensure the `key_root` format like "user0/". No '/' at the beginning and '/' at the end +String normalizedRoot(String ori_root) // a copy for changing +{ + if (startsWith(ori_root, "/") && ori_root.size() != 1) + { + ori_root = ori_root.substr(1, ori_root.size()); + } + if (!endsWith(ori_root, "/")) + { + ori_root += "/"; + } + return ori_root; +} + +TiFlashS3Client::TiFlashS3Client(const String & bucket_name_, const String & root_) : bucket_name(bucket_name_) -{} + , key_root(normalizedRoot(root_)) + , log(Logger::get(fmt::format("bucket={} root={}", bucket_name, key_root))) +{ +} TiFlashS3Client::TiFlashS3Client( const String & bucket_name_, + const String & root_, const Aws::Auth::AWSCredentials & credentials, const Aws::Client::ClientConfiguration & clientConfiguration, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy signPayloads, bool useVirtualAddressing) : Aws::S3::S3Client(credentials, clientConfiguration, signPayloads, useVirtualAddressing) , bucket_name(bucket_name_) + , key_root(normalizedRoot(root_)) + , log(Logger::get(fmt::format("bucket={} root={}", bucket_name, key_root))) { } -TiFlashS3Client::TiFlashS3Client(const String & bucket_name_, std::unique_ptr && raw_client) +TiFlashS3Client::TiFlashS3Client( + const String & bucket_name_, + const String & root_, + std::unique_ptr && raw_client) : Aws::S3::S3Client(std::move(*raw_client)) , bucket_name(bucket_name_) + , key_root(normalizedRoot(root_)) + , log(Logger::get(fmt::format("bucket={} root={}", bucket_name, key_root))) { } @@ -154,24 +181,23 @@ bool ClientFactory::isEnabled() const void ClientFactory::init(const StorageS3Config & config_, bool mock_s3_) { config = config_; + config.root = normalizedRoot(config.root); Aws::InitAPI(aws_options); Aws::Utils::Logging::InitializeAWSLogging(std::make_shared()); if (!mock_s3_) { - shared_client = create(); - shared_tiflash_client = std::make_shared(config.bucket, create()); + shared_tiflash_client = std::make_shared(config.bucket, config.root, create()); } else { - shared_tiflash_client = std::make_unique(config.bucket); - shared_client = shared_tiflash_client; // share the same object + shared_tiflash_client = std::make_unique(config.bucket, config.root); } } void ClientFactory::shutdown() { + // Reset S3Client before Aws::ShutdownAPI. shared_tiflash_client.reset(); - shared_client.reset(); // Reset S3Client before Aws::ShutdownAPI. Aws::Utils::Logging::ShutdownAWSLogging(); Aws::ShutdownAPI(aws_options); } @@ -189,22 +215,11 @@ std::unique_ptr ClientFactory::create() const return create(config); } -const String & ClientFactory::bucket() const -{ - // `bucket` is read-only. - return config.bucket; -} - -std::shared_ptr ClientFactory::sharedClient() const -{ - // `shared_client` is created during initialization and destroyed when process exits - // which means it is read-only when processing requests. So, it is safe to read `shared_client` - // without acquiring lock. - return shared_client; -} - std::shared_ptr ClientFactory::sharedTiFlashClient() const { + // `shared_tiflash_client` is created during initialization and destroyed + // when process exits which means it is read-only when processing requests. + // So, it is safe to read `shared_tiflash_client` without acquiring lock. return shared_tiflash_client; } @@ -250,44 +265,19 @@ bool isNotFoundError(Aws::S3::S3Errors error) return error == Aws::S3::S3Errors::RESOURCE_NOT_FOUND || error == Aws::S3::S3Errors::NO_SUCH_KEY; } -Aws::S3::Model::HeadObjectOutcome headObject(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id) +Aws::S3::Model::HeadObjectOutcome headObject(const TiFlashS3Client & client, const String & key) { ProfileEvents::increment(ProfileEvents::S3HeadObject); Stopwatch sw; SCOPE_EXIT({ GET_METRIC(tiflash_storage_s3_request_seconds, type_head_object).Observe(sw.elapsedSeconds()); }); Aws::S3::Model::HeadObjectRequest req; - req.WithBucket(bucket).WithKey(key); - if (!version_id.empty()) - { - req.SetVersionId(version_id); - } + client.setBucketAndKeyWithRoot(req, key); return client.HeadObject(req); } -S3::ObjectInfo getObjectInfo(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool throw_on_error) -{ - auto outcome = headObject(client, bucket, key, version_id); - - if (outcome.IsSuccess()) - { - auto read_result = outcome.GetResultWithOwnership(); - return {.size = static_cast(read_result.GetContentLength()), .last_modification_time = read_result.GetLastModified().Millis() / 1000}; - } - else if (throw_on_error) - { - throw fromS3Error(outcome.GetError(), "Failed to HEAD object, key={}", key); - } - return {}; -} - -size_t getObjectSize(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool throw_on_error) -{ - return getObjectInfo(client, bucket, key, version_id, throw_on_error).size; -} - -bool objectExists(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id) +bool objectExists(const TiFlashS3Client & client, const String & key) { - auto outcome = headObject(client, bucket, key, version_id); + auto outcome = headObject(client, key); if (outcome.IsSuccess()) { return true; @@ -297,14 +287,14 @@ bool objectExists(const Aws::S3::S3Client & client, const String & bucket, const { return false; } - throw fromS3Error(outcome.GetError(), "Failed to check existence of object, bucket={} key={}", bucket, key); + throw fromS3Error(outcome.GetError(), "S3 HeadObject failed, bucket={} root={} key={}", client.bucket(), client.root(), key); } -void uploadEmptyFile(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & tagging) +void uploadEmptyFile(const TiFlashS3Client & client, const String & key, const String & tagging) { Stopwatch sw; Aws::S3::Model::PutObjectRequest req; - req.WithBucket(bucket).WithKey(key); + client.setBucketAndKeyWithRoot(req, key); if (!tagging.empty()) req.SetTagging(tagging); req.SetContentType("binary/octet-stream"); @@ -314,19 +304,18 @@ void uploadEmptyFile(const Aws::S3::S3Client & client, const String & bucket, co auto result = client.PutObject(req); if (!result.IsSuccess()) { - throw fromS3Error(result.GetError(), "S3 PutEmptyObject failed, bucket={} key={}", bucket, key); + throw fromS3Error(result.GetError(), "S3 PutEmptyObject failed, bucket={} root={} key={}", client.bucket(), client.root(), key); } auto elapsed_seconds = sw.elapsedSeconds(); GET_METRIC(tiflash_storage_s3_request_seconds, type_put_object).Observe(elapsed_seconds); - static auto log = Logger::get(); - LOG_DEBUG(log, "uploadEmptyFile remote_fname={}, cost={:.2f}s", key, elapsed_seconds); + LOG_DEBUG(client.log, "uploadEmptyFile key={}, cost={:.2f}s", key, elapsed_seconds); } -void uploadFile(const Aws::S3::S3Client & client, const String & bucket, const String & local_fname, const String & remote_fname) +void uploadFile(const TiFlashS3Client & client, const String & local_fname, const String & remote_fname) { Stopwatch sw; Aws::S3::Model::PutObjectRequest req; - req.WithBucket(bucket).WithKey(remote_fname); + client.setBucketAndKeyWithRoot(req, remote_fname); req.SetContentType("binary/octet-stream"); auto istr = Aws::MakeShared("PutObjectInputStream", local_fname, std::ios_base::in | std::ios_base::binary); RUNTIME_CHECK_MSG(istr->is_open(), "Open {} fail: {}", local_fname, strerror(errno)); @@ -336,26 +325,24 @@ void uploadFile(const Aws::S3::S3Client & client, const String & bucket, const S auto result = client.PutObject(req); if (!result.IsSuccess()) { - throw fromS3Error(result.GetError(), "S3 PutObject failed, local_fname={} bucket={} key={}", local_fname, bucket, remote_fname); + throw fromS3Error(result.GetError(), "S3 PutObject failed, local_fname={} bucket={} root={} key={}", local_fname, client.bucket(), client.root(), remote_fname); } ProfileEvents::increment(ProfileEvents::S3WriteBytes, write_bytes); auto elapsed_seconds = sw.elapsedSeconds(); GET_METRIC(tiflash_storage_s3_request_seconds, type_put_object).Observe(elapsed_seconds); - static auto log = Logger::get(); - LOG_DEBUG(log, "uploadFile local_fname={}, remote_fname={}, write_bytes={} cost={:.2f}s", local_fname, remote_fname, write_bytes, elapsed_seconds); + LOG_DEBUG(client.log, "uploadFile local_fname={}, key={}, write_bytes={} cost={:.2f}s", local_fname, remote_fname, write_bytes, elapsed_seconds); } -void downloadFile(const Aws::S3::S3Client & client, const String & bucket, const String & local_fname, const String & remote_fname) +void downloadFile(const TiFlashS3Client & client, const String & local_fname, const String & remote_fname) { Stopwatch sw; Aws::S3::Model::GetObjectRequest req; - req.SetBucket(bucket); - req.SetKey(remote_fname); + client.setBucketAndKeyWithRoot(req, remote_fname); ProfileEvents::increment(ProfileEvents::S3GetObject); auto outcome = client.GetObject(req); if (!outcome.IsSuccess()) { - throw fromS3Error(outcome.GetError(), "remote_fname={}", remote_fname); + throw fromS3Error(outcome.GetError(), "S3 GetObject failed, bucket={} root={} key={}", client.bucket(), client.root(), remote_fname); } ProfileEvents::increment(ProfileEvents::S3ReadBytes, outcome.GetResult().GetContentLength()); GET_METRIC(tiflash_storage_s3_request_seconds, type_get_object).Observe(sw.elapsedSeconds()); @@ -365,33 +352,35 @@ void downloadFile(const Aws::S3::S3Client & client, const String & bucket, const RUNTIME_CHECK_MSG(ostr.good(), "Write {} fail: {}", local_fname, strerror(errno)); } -void rewriteObjectWithTagging(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & tagging) +void rewriteObjectWithTagging(const TiFlashS3Client & client, const String & key, const String & tagging) { Stopwatch sw; Aws::S3::Model::CopyObjectRequest req; // rewrite the object with `key`, adding tagging to the new object - req.WithBucket(bucket).WithCopySource(bucket + "/" + key).WithKey(key) // + // The copy_source format is "${source_bucket}/${source_key}" + auto copy_source = client.bucket() + "/" + (client.root() == "/" ? "" : client.root()) + key; + client.setBucketAndKeyWithRoot(req, key); + req.WithCopySource(copy_source) // .WithTagging(tagging) .WithTaggingDirective(Aws::S3::Model::TaggingDirective::REPLACE); ProfileEvents::increment(ProfileEvents::S3CopyObject); auto outcome = client.CopyObject(req); if (!outcome.IsSuccess()) { - throw fromS3Error(outcome.GetError(), "key={}", key); + throw fromS3Error(outcome.GetError(), "S3 CopyObject failed, bucket={} root={} key={}", client.bucket(), client.root(), key); } auto elapsed_seconds = sw.elapsedSeconds(); GET_METRIC(tiflash_storage_s3_request_seconds, type_copy_object).Observe(elapsed_seconds); - static auto log = Logger::get(); - LOG_DEBUG(log, "rewrite object key={} cost={:.2f}s", key, elapsed_seconds); + LOG_DEBUG(client.log, "rewrite object key={} cost={:.2f}s", key, elapsed_seconds); } -void ensureLifecycleRuleExist(const Aws::S3::S3Client & client, const String & bucket, Int32 expire_days) +void ensureLifecycleRuleExist(const TiFlashS3Client & client, Int32 expire_days) { bool lifecycle_rule_has_been_set = false; Aws::Vector old_rules; { Aws::S3::Model::GetBucketLifecycleConfigurationRequest req; - req.SetBucket(bucket); + req.SetBucket(client.bucket()); auto outcome = client.GetBucketLifecycleConfiguration(req); if (!outcome.IsSuccess()) { @@ -425,23 +414,22 @@ void ensureLifecycleRuleExist(const Aws::S3::S3Client & client, const String & b } } - static LoggerPtr log = Logger::get(); if (lifecycle_rule_has_been_set) { - LOG_INFO(log, "The lifecycle rule has been set, n_rules={} filter={}", old_rules.size(), TaggingObjectIsDeleted); + LOG_INFO(client.log, "The lifecycle rule has been set, n_rules={} filter={}", old_rules.size(), TaggingObjectIsDeleted); return; } else { UNUSED(expire_days); - LOG_WARNING(log, "The lifecycle rule with filter \"{}\" has not been set, please check the bucket lifecycle configuration", TaggingObjectIsDeleted); + LOG_WARNING(client.log, "The lifecycle rule with filter \"{}\" has not been set, please check the bucket lifecycle configuration", TaggingObjectIsDeleted); return; } #if 0 // Adding rule by AWS SDK is failed, don't know why // Reference: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3OutpostsLifecycleCLIJava.html - LOG_INFO(log, "The lifecycle rule with filter \"{}\" has not been added, n_rules={}", TaggingObjectIsDeleted, old_rules.size()); + LOG_INFO(client.log, "The lifecycle rule with filter \"{}\" has not been added, n_rules={}", TaggingObjectIsDeleted, old_rules.size()); static_assert(TaggingObjectIsDeleted == "tiflash_deleted=true"); std::vector filter_tags{Aws::S3::Model::Tag().WithKey("tiflash_deleted").WithValue("true")}; Aws::S3::Model::LifecycleRuleFilter filter; @@ -471,38 +459,90 @@ void ensureLifecycleRuleExist(const Aws::S3::S3Client & client, const String & b { throw fromS3Error(outcome.GetError(), "PutBucketLifecycle fail"); } - LOG_INFO(log, "The lifecycle rule has been added, new_n_rules={} tag={}", old_rules.size() + 1, TaggingObjectIsDeleted); + LOG_INFO(client.log, "The lifecycle rule has been added, new_n_rules={} tag={}", old_rules.size(), TaggingObjectIsDeleted); #endif } void listPrefix( - const Aws::S3::S3Client & client, - const String & bucket, + const TiFlashS3Client & client, const String & prefix, - std::function pager) + std::function pager) { - // Usually we don't need to set delimiter. - // Check the docs here for Delimiter && CommonPrefixes when you really need it. - // https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-prefixes.html - listPrefix(client, bucket, prefix, /*delimiter*/ "", pager); + Stopwatch sw; + Aws::S3::Model::ListObjectsV2Request req; + req.WithBucket(client.bucket()).WithPrefix(client.root() + prefix); + + // If the `root == '/'`, then the return result will cut it off + // else we need to cut the root in the following codes + bool need_cut = client.root() != "/"; + size_t cut_size = client.root().size(); + + bool done = false; + size_t num_keys = 0; + while (!done) + { + Stopwatch sw_list; + ProfileEvents::increment(ProfileEvents::S3ListObjects); + auto outcome = client.ListObjectsV2(req); + if (!outcome.IsSuccess()) + { + throw fromS3Error(outcome.GetError(), "S3 ListObjectV2s failed, bucket={} root={} prefix={}", client.bucket(), client.root(), prefix); + } + GET_METRIC(tiflash_storage_s3_request_seconds, type_list_objects).Observe(sw_list.elapsedSeconds()); + + PageResult page_res{}; + const auto & result = outcome.GetResult(); + auto page_keys = result.GetCommonPrefixes().size(); + num_keys += page_keys; + for (const auto & object : result.GetContents()) + { + if (!need_cut) + { + page_res = pager(object); + } + else + { + // Copy the `Object` to cut off the `root` from key, the cost should be acceptable :( + auto object_without_root = object; + object_without_root.SetKey(object.GetKey().substr(cut_size, object.GetKey().size())); + page_res = pager(object_without_root); + } + if (!page_res.more) + break; + } + + // handle the result size over max size + done = !result.GetIsTruncated(); + if (!done && page_res.more) + { + const auto & next_token = result.GetNextContinuationToken(); + req.SetContinuationToken(next_token); + LOG_DEBUG(client.log, "listPrefix prefix={}, keys={}, total_keys={}, next_token={}", prefix, page_keys, num_keys, next_token); + } + } + LOG_DEBUG(client.log, "listPrefix prefix={}, total_keys={}, cost={:.2f}s", prefix, num_keys, sw.elapsedSeconds()); } -void listPrefix( - const Aws::S3::S3Client & client, - const String & bucket, +// Check the docs here for Delimiter && CommonPrefixes when you really need it. +// https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-prefixes.html +void listPrefixWithDelimiter( + const TiFlashS3Client & client, const String & prefix, std::string_view delimiter, - std::function pager) + std::function pager) { Stopwatch sw; Aws::S3::Model::ListObjectsV2Request req; - req.WithBucket(bucket).WithPrefix(prefix); + req.WithBucket(client.bucket()).WithPrefix(client.root() + prefix); if (!delimiter.empty()) { req.SetDelimiter(String(delimiter)); } - static auto log = Logger::get("S3ListPrefix"); + // If the `root == '/'`, then the return result will cut it off + // else we need to cut the root in the following codes + bool need_cut = client.root() != "/"; + size_t cut_size = client.root().size(); bool done = false; size_t num_keys = 0; @@ -513,13 +553,30 @@ void listPrefix( auto outcome = client.ListObjectsV2(req); if (!outcome.IsSuccess()) { - throw fromS3Error(outcome.GetError(), "S3 ListObjects failed, bucket={} prefix={} delimiter={}", bucket, prefix, delimiter); + throw fromS3Error(outcome.GetError(), "S3 ListObjectV2s failed, bucket={} root={} prefix={} delimiter={}", client.bucket(), client.root(), prefix, delimiter); } GET_METRIC(tiflash_storage_s3_request_seconds, type_list_objects).Observe(sw_list.elapsedSeconds()); + PageResult page_res{}; const auto & result = outcome.GetResult(); - PageResult page_res = pager(result); - num_keys += page_res.num_keys; + auto page_keys = result.GetCommonPrefixes().size(); + num_keys += page_keys; + for (const auto & prefix : result.GetCommonPrefixes()) + { + if (!need_cut) + { + page_res = pager(prefix); + } + else + { + // Copy the `CommonPrefix` to cut off the `root`, the cost should be acceptable :( + auto prefix_without_root = prefix; + prefix_without_root.SetPrefix(prefix.GetPrefix().substr(cut_size, prefix.GetPrefix().size())); + page_res = pager(prefix_without_root); + } + if (!page_res.more) + break; + } // handle the result size over max size done = !result.GetIsTruncated(); @@ -527,55 +584,61 @@ void listPrefix( { const auto & next_token = result.GetNextContinuationToken(); req.SetContinuationToken(next_token); - LOG_DEBUG(log, "listPrefix prefix={}, keys={}, total_keys={}, next_token={}", prefix, page_res.num_keys, num_keys, next_token); + LOG_DEBUG(client.log, "listPrefixWithDelimiter prefix={}, delimiter={}, keys={}, total_keys={}, next_token={}", prefix, delimiter, page_keys, num_keys, next_token); } } - LOG_DEBUG(log, "listPrefix prefix={}, total_keys={}, cost={:.2f}s", prefix, num_keys, sw.elapsedSeconds()); + LOG_DEBUG(client.log, "listPrefixWithDelimiter prefix={}, delimiter={}, total_keys={}, cost={:.2f}s", prefix, delimiter, num_keys, sw.elapsedSeconds()); } -std::unordered_map listPrefixWithSize(const Aws::S3::S3Client & client, const String & bucket, const String & prefix) +std::optional anyKeyExistWithPrefix(const TiFlashS3Client & client, const String & prefix) +{ + std::optional key_opt; + listPrefix(client, prefix, [&key_opt](const Aws::S3::Model::Object & object) { + key_opt = object.GetKey(); + return PageResult{ + .num_keys = 1, + .more = false, // do not need more result + }; + }); + return key_opt; +} + +std::unordered_map listPrefixWithSize(const TiFlashS3Client & client, const String & prefix) { std::unordered_map keys_with_size; - listPrefix(client, bucket, prefix, "", [&](const Aws::S3::Model::ListObjectsV2Result & result) { - const auto & objects = result.GetContents(); - keys_with_size.reserve(keys_with_size.size() + objects.size()); - for (const auto & object : objects) - { - keys_with_size.emplace(object.GetKey().substr(prefix.size()), object.GetSize()); // Cut prefix - } - return PageResult{.num_keys = objects.size(), .more = true}; + listPrefix(client, prefix, [&](const Aws::S3::Model::Object & object) { + keys_with_size.emplace(object.GetKey().substr(prefix.size()), object.GetSize()); // Cut prefix + return PageResult{.num_keys = 1, .more = true}; }); return keys_with_size; } std::pair tryGetObjectModifiedTime( - const Aws::S3::S3Client & client, - const String & bucket, + const TiFlashS3Client & client, const String & key) { - auto o = headObject(client, bucket, key); + auto o = headObject(client, key); if (!o.IsSuccess()) { if (const auto & err = o.GetError(); isNotFoundError(err.GetErrorType())) { return {false, {}}; } - throw fromS3Error(o.GetError(), "Failed to check existence of object, bucket={} key={}", bucket, key); + throw fromS3Error(o.GetError(), "Failed to check existence of object, bucket={} key={}", client.bucket(), key); } // Else the object still exist const auto & res = o.GetResult(); // "DeleteMark" of S3 service, don't know what will lead to this - RUNTIME_CHECK(!res.GetDeleteMarker(), bucket, key); + RUNTIME_CHECK(!res.GetDeleteMarker(), client.bucket(), key); return {true, res.GetLastModified()}; } -void deleteObject(const Aws::S3::S3Client & client, const String & bucket, const String & key) +void deleteObject(const TiFlashS3Client & client, const String & key) { Stopwatch sw; Aws::S3::Model::DeleteObjectRequest req; - req.SetBucket(bucket); - req.SetKey(key); + client.setBucketAndKeyWithRoot(req, key); ProfileEvents::increment(ProfileEvents::S3DeleteObject); auto o = client.DeleteObject(req); RUNTIME_CHECK(o.IsSuccess(), o.GetError().GetMessage()); @@ -584,4 +647,50 @@ void deleteObject(const Aws::S3::S3Client & client, const String & bucket, const GET_METRIC(tiflash_storage_s3_request_seconds, type_delete_object).Observe(sw.elapsedSeconds()); } +void rawListPrefix( + const Aws::S3::S3Client & client, + const String & bucket, + const String & prefix, + std::string_view delimiter, + std::function pager) +{ + Stopwatch sw; + Aws::S3::Model::ListObjectsV2Request req; + req.WithBucket(bucket).WithPrefix(prefix); + if (!delimiter.empty()) + { + req.SetDelimiter(String(delimiter)); + } + + static auto log = Logger::get("S3RawListPrefix"); + + bool done = false; + size_t num_keys = 0; + while (!done) + { + Stopwatch sw_list; + ProfileEvents::increment(ProfileEvents::S3ListObjects); + auto outcome = client.ListObjectsV2(req); + if (!outcome.IsSuccess()) + { + throw fromS3Error(outcome.GetError(), "S3 ListObjectV2s failed, bucket={} prefix={} delimiter={}", bucket, prefix, delimiter); + } + GET_METRIC(tiflash_storage_s3_request_seconds, type_list_objects).Observe(sw_list.elapsedSeconds()); + + const auto & result = outcome.GetResult(); + PageResult page_res = pager(result); + num_keys += page_res.num_keys; + + // handle the result size over max size + done = !result.GetIsTruncated(); + if (!done && page_res.more) + { + const auto & next_token = result.GetNextContinuationToken(); + req.SetContinuationToken(next_token); + LOG_DEBUG(log, "rawListPrefix bucket={} prefix={} delimiter={} keys={} total_keys={} next_token={}", bucket, prefix, delimiter, page_res.num_keys, num_keys, next_token); + } + } + LOG_DEBUG(log, "rawListPrefix bucket={} prefix={} delimiter={} total_keys={} cost={:.2f}s", bucket, prefix, delimiter, num_keys, sw.elapsedSeconds()); +} + } // namespace DB::S3 diff --git a/dbms/src/Storages/S3/S3Common.h b/dbms/src/Storages/S3/S3Common.h index b52b1e75fed..88f4be2e3b3 100644 --- a/dbms/src/Storages/S3/S3Common.h +++ b/dbms/src/Storages/S3/S3Common.h @@ -15,6 +15,7 @@ #pragma once #include +#include #include #include #include @@ -47,21 +48,37 @@ class TiFlashS3Client : public Aws::S3::S3Client // Usually one tiflash instance only need access one bucket. // Store the bucket name to simpilfy some param passing. - explicit TiFlashS3Client(const String & bucket_name_); + TiFlashS3Client(const String & bucket_name_, const String & root_); TiFlashS3Client( const String & bucket_name_, + const String & root_, const Aws::Auth::AWSCredentials & credentials, const Aws::Client::ClientConfiguration & clientConfiguration, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy signPayloads, bool useVirtualAddressing); - TiFlashS3Client(const String & bucket_name_, std::unique_ptr && raw_client); + TiFlashS3Client( + const String & bucket_name_, + const String & root_, + std::unique_ptr && raw_client); const String & bucket() const { return bucket_name; } + const String & root() const { return key_root; } + + template + void setBucketAndKeyWithRoot(Request & req, const String & key) const + { + req.WithBucket(bucket_name).WithKey(key_root + key); + } + private: const String bucket_name; + String key_root; + +public: + LoggerPtr log; }; enum class S3GCMethod @@ -83,8 +100,7 @@ class ClientFactory void shutdown(); - const String & bucket() const; - std::shared_ptr sharedClient() const; + const String & bucket() const { return config.bucket; } std::shared_ptr sharedTiFlashClient() const; @@ -100,40 +116,29 @@ class ClientFactory Aws::SDKOptions aws_options; StorageS3Config config; - std::shared_ptr shared_client; std::shared_ptr shared_tiflash_client; }; -struct ObjectInfo -{ - size_t size = 0; - time_t last_modification_time = 0; -}; - bool isNotFoundError(Aws::S3::S3Errors error); -Aws::S3::Model::HeadObjectOutcome headObject(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id = ""); - -S3::ObjectInfo getObjectInfo(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool throw_on_error); - -size_t getObjectSize(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool throw_on_error); +Aws::S3::Model::HeadObjectOutcome headObject(const TiFlashS3Client & client, const String & key); -bool objectExists(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id = ""); +bool objectExists(const TiFlashS3Client & client, const String & key); -void uploadFile(const Aws::S3::S3Client & client, const String & bucket, const String & local_fname, const String & remote_fname); +void uploadFile(const TiFlashS3Client & client, const String & local_fname, const String & remote_fname); constexpr std::string_view TaggingObjectIsDeleted = "tiflash_deleted=true"; -void ensureLifecycleRuleExist(const Aws::S3::S3Client & client, const String & bucket, Int32 expire_days); +void ensureLifecycleRuleExist(const TiFlashS3Client & client, Int32 expire_days); /** * tagging is the tag-set for the object. The tag-set must be encoded as URL Query * parameters. (For example, "Key1=Value1") */ -void uploadEmptyFile(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & tagging = ""); +void uploadEmptyFile(const TiFlashS3Client & client, const String & key, const String & tagging = ""); -void downloadFile(const Aws::S3::S3Client & client, const String & bucket, const String & local_fname, const String & remote_fname); +void downloadFile(const TiFlashS3Client & client, const String & local_fname, const String & remote_fname); -void rewriteObjectWithTagging(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & tagging); +void rewriteObjectWithTagging(const TiFlashS3Client & client, const String & key, const String & tagging); struct PageResult { @@ -143,25 +148,33 @@ struct PageResult bool more; }; void listPrefix( - const Aws::S3::S3Client & client, - const String & bucket, + const TiFlashS3Client & client, const String & prefix, - std::function pager); -void listPrefix( - const Aws::S3::S3Client & client, - const String & bucket, + std::function pager); +void listPrefixWithDelimiter( + const TiFlashS3Client & client, const String & prefix, std::string_view delimiter, - std::function pager); + std::function pager); -std::unordered_map listPrefixWithSize(const Aws::S3::S3Client & client, const String & bucket, const String & prefix); +std::optional anyKeyExistWithPrefix(const TiFlashS3Client & client, const String & prefix); + +std::unordered_map listPrefixWithSize(const TiFlashS3Client & client, const String & prefix); std::pair tryGetObjectModifiedTime( - const Aws::S3::S3Client & client, - const String & bucket, + const TiFlashS3Client & client, const String & key); -void deleteObject(const Aws::S3::S3Client & client, const String & bucket, const String & key); +void deleteObject(const TiFlashS3Client & client, const String & key); + +// Unlike `listPrefix` or other methods above, this does not handle +// the TiFlashS3Client `root`. +void rawListPrefix( + const Aws::S3::S3Client & client, + const String & bucket, + const String & prefix, + std::string_view delimiter, + std::function pager); } // namespace DB::S3 diff --git a/dbms/src/Storages/S3/S3GCManager.cpp b/dbms/src/Storages/S3/S3GCManager.cpp index 8695be20a91..ae163ec27b3 100644 --- a/dbms/src/Storages/S3/S3GCManager.cpp +++ b/dbms/src/Storages/S3/S3GCManager.cpp @@ -87,7 +87,7 @@ bool S3GCManager::runOnAllStores() if (config.method == S3GCMethod::Lifecycle && !lifecycle_has_been_set) { auto client = S3::ClientFactory::instance().sharedTiFlashClient(); - ensureLifecycleRuleExist(*client, client->bucket(), /*expire_days*/ 1); + ensureLifecycleRuleExist(*client, /*expire_days*/ 1); lifecycle_has_been_set = true; } @@ -230,38 +230,40 @@ void S3GCManager::cleanUnusedLocks( { auto client = S3::ClientFactory::instance().sharedTiFlashClient(); // All locks (even for different stores) share the same prefix, list the lock files under this prefix - listPrefix(*client, client->bucket(), scan_prefix, [&](const Aws::S3::Model::ListObjectsV2Result & result) { - const auto & objects = result.GetContents(); - if (shutdown_called) - { - LOG_INFO(log, "shutting down, break"); - // .more=false to break the list - return PageResult{.num_keys = objects.size(), .more = false}; - } + S3::listPrefix( + *client, + scan_prefix, + [&](const Aws::S3::Model::Object & object) { + if (shutdown_called) + { + LOG_INFO(log, "shutting down, break"); + // .more=false to break the list + return PageResult{.num_keys = 1, .more = false}; + } - for (const auto & object : objects) - { - const auto & lock_key = object.GetKey(); - LOG_TRACE(log, "lock_key={}", lock_key); - const auto lock_filename_view = S3FilenameView::fromKey(lock_key); - RUNTIME_CHECK(lock_filename_view.isLockFile(), lock_key); - const auto lock_info = lock_filename_view.getLockInfo(); - // The lock file is not managed by `gc_store_id`, skip - if (lock_info.store_id != gc_store_id) - continue; - // The lock is not managed by the latest manifest yet, wait for - // next GC round - if (lock_info.sequence > safe_sequence) - continue; - // The lock is still valid - if (valid_lock_files.count(lock_key) > 0) - continue; - - // The data file is not used by `gc_store_id` anymore, remove the lock file - cleanOneLock(lock_key, lock_filename_view, timepoint); - } - return PageResult{.num_keys = objects.size(), .more = true}; - }); + do + { + const auto & lock_key = object.GetKey(); + LOG_TRACE(log, "lock_key={}", lock_key); + const auto lock_filename_view = S3FilenameView::fromKey(lock_key); + RUNTIME_CHECK(lock_filename_view.isLockFile(), lock_key); + const auto lock_info = lock_filename_view.getLockInfo(); + // The lock file is not managed by `gc_store_id`, skip + if (lock_info.store_id != gc_store_id) + break; + // The lock is not managed by the latest manifest yet, wait for + // next GC round + if (lock_info.sequence > safe_sequence) + break; + // The lock is still valid + if (valid_lock_files.count(lock_key) > 0) + break; + + // The data file is not used by `gc_store_id` anymore, remove the lock file + cleanOneLock(lock_key, lock_filename_view, timepoint); + } while (false); + return PageResult{.num_keys = 1, .more = true}; + }); } void S3GCManager::cleanOneLock(const String & lock_key, const S3FilenameView & lock_filename_view, const Aws::Utils::DateTime & timepoint) @@ -273,7 +275,7 @@ void S3GCManager::cleanOneLock(const String & lock_key, const S3FilenameView & l // delete S3 lock file auto client = S3::ClientFactory::instance().sharedTiFlashClient(); - deleteObject(*client, client->bucket(), lock_key); + deleteObject(*client, lock_key); // TODO: If `lock_key` is the only lock to datafile and GCManager crashes // after the lock deleted but before delmark uploaded, then the @@ -282,7 +284,7 @@ void S3GCManager::cleanOneLock(const String & lock_key, const S3FilenameView & l bool delmark_exists = false; Aws::Utils::DateTime mtime; - std::tie(delmark_exists, mtime) = tryGetObjectModifiedTime(*client, client->bucket(), unlocked_datafile_delmark_key); + std::tie(delmark_exists, mtime) = tryGetObjectModifiedTime(*client, unlocked_datafile_delmark_key); if (!delmark_exists) { bool ok; @@ -384,7 +386,7 @@ void S3GCManager::removeDataFileIfDelmarkExpired( physicalRemoveDataFile(datafile_key); auto client = S3::ClientFactory::instance().sharedTiFlashClient(); - deleteObject(*client, client->bucket(), delmark_key); + deleteObject(*client, delmark_key); LOG_INFO(log, "datafile delmark deleted, key={}", delmark_key); } @@ -395,27 +397,26 @@ void S3GCManager::tryCleanExpiredDataFiles(UInt64 gc_store_id, const Aws::Utils: // its correspond StableFile or CheckpointDataFile. const auto prefix = S3Filename::fromStoreId(gc_store_id).toDataPrefix(); auto client = S3::ClientFactory::instance().sharedTiFlashClient(); - listPrefix(*client, client->bucket(), prefix, [&](const Aws::S3::Model::ListObjectsV2Result & result) { - const auto & objects = result.GetContents(); + S3::listPrefix(*client, prefix, [&](const Aws::S3::Model::Object & object) { if (shutdown_called) { LOG_INFO(log, "shutting down, break"); // .more=false to break the list - return PageResult{.num_keys = objects.size(), .more = false}; + return PageResult{.num_keys = 1, .more = false}; } - for (const auto & object : objects) + do { const auto & delmark_key = object.GetKey(); LOG_TRACE(log, "key={}", object.GetKey()); const auto filename_view = S3FilenameView::fromKey(delmark_key); // Only remove the data file with expired delmark if (!filename_view.isDelMark()) - continue; + break; auto datafile_key = filename_view.asDataFile().toFullKey(); removeDataFileIfDelmarkExpired(datafile_key, delmark_key, timepoint, object.GetLastModified()); - } - return PageResult{.num_keys = objects.size(), .more = true}; + } while (false); + return PageResult{.num_keys = 1, .more = true}; }); } @@ -428,7 +429,7 @@ void S3GCManager::lifecycleMarkDataFileDeleted(const String & datafile_key) if (!view.isDMFile()) { // CheckpointDataFile is a single object, add tagging for it and update its mtime - rewriteObjectWithTagging(*client, client->bucket(), datafile_key, String(TaggingObjectIsDeleted)); + rewriteObjectWithTagging(*client, datafile_key, String(TaggingObjectIsDeleted)); LOG_INFO(log, "datafile deleted by lifecycle tagging, key={}", datafile_key); } else @@ -437,15 +438,11 @@ void S3GCManager::lifecycleMarkDataFileDeleted(const String & datafile_key) // Rewrite all objects with tagging belong to this DMFile // TODO: If GCManager unexpectedly exit in the middle, it will leave some broken // sub file for DMFile, try clean them later. - S3::listPrefix(*client, client->bucket(), datafile_key, [this, &client, &datafile_key](const Aws::S3::Model::ListObjectsV2Result & result) { - const auto & objs = result.GetContents(); - for (const auto & obj : objs) - { - const auto & sub_key = obj.GetKey(); - rewriteObjectWithTagging(*client, client->bucket(), sub_key, String(TaggingObjectIsDeleted)); - LOG_INFO(log, "datafile deleted by lifecycle tagging, key={} sub_key={}", datafile_key, sub_key); - } - return PageResult{.num_keys = objs.size(), .more = true}; + S3::listPrefix(*client, datafile_key, [this, &client, &datafile_key](const Aws::S3::Model::Object & object) { + const auto & sub_key = object.GetKey(); + rewriteObjectWithTagging(*client, sub_key, String(TaggingObjectIsDeleted)); + LOG_INFO(log, "datafile deleted by lifecycle tagging, key={} sub_key={}", datafile_key, sub_key); + return PageResult{.num_keys = 1, .more = true}; }); LOG_INFO(log, "datafile deleted by lifecycle tagging, all sub keys are deleted, key={}", datafile_key); } @@ -460,7 +457,7 @@ void S3GCManager::physicalRemoveDataFile(const String & datafile_key) if (!view.isDMFile()) { // CheckpointDataFile is a single object, remove it. - deleteObject(*client, client->bucket(), datafile_key); + deleteObject(*client, datafile_key); LOG_INFO(log, "datafile deleted, key={}", datafile_key); } else @@ -469,15 +466,11 @@ void S3GCManager::physicalRemoveDataFile(const String & datafile_key) // Remove all objects belong to this DMFile // TODO: If GCManager unexpectedly exit in the middle, it will leave some broken // sub file for DMFile, try clean them later. - S3::listPrefix(*client, client->bucket(), datafile_key, [this, &client, &datafile_key](const Aws::S3::Model::ListObjectsV2Result & result) { - const auto & objs = result.GetContents(); - for (const auto & obj : objs) - { - const auto & sub_key = obj.GetKey(); - deleteObject(*client, client->bucket(), sub_key); - LOG_INFO(log, "datafile deleted, key={} sub_key={}", datafile_key, sub_key); - } - return PageResult{.num_keys = objs.size(), .more = true}; + S3::listPrefix(*client, datafile_key, [this, &client, &datafile_key](const Aws::S3::Model::Object & object) { + const auto & sub_key = object.GetKey(); + deleteObject(*client, sub_key); + LOG_INFO(log, "datafile deleted, key={} sub_key={}", datafile_key, sub_key); + return PageResult{.num_keys = 1, .more = true}; }); LOG_INFO(log, "datafile deleted, all sub keys are deleted, key={}", datafile_key); } @@ -490,20 +483,15 @@ std::vector S3GCManager::getAllStoreIds() // common prefixes result. // Reference: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-prefixes.html auto client = S3::ClientFactory::instance().sharedTiFlashClient(); - listPrefix( + S3::listPrefixWithDelimiter( *client, - client->bucket(), /*prefix*/ S3Filename::allStorePrefix(), /*delimiter*/ "/", - [&all_store_ids](const Aws::S3::Model::ListObjectsV2Result & result) { - const Aws::Vector & prefixes = result.GetCommonPrefixes(); - for (const auto & prefix : prefixes) - { - const auto filename_view = S3FilenameView::fromStoreKeyPrefix(prefix.GetPrefix()); - RUNTIME_CHECK(filename_view.type == S3FilenameType::StorePrefix, prefix.GetPrefix()); - all_store_ids.emplace_back(filename_view.store_id); - } - return PageResult{.num_keys = prefixes.size(), .more = true}; + [&all_store_ids](const Aws::S3::Model::CommonPrefix & prefix) { + const auto filename_view = S3FilenameView::fromStoreKeyPrefix(prefix.GetPrefix()); + RUNTIME_CHECK(filename_view.type == S3FilenameType::StorePrefix, prefix.GetPrefix()); + all_store_ids.emplace_back(filename_view.store_id); + return PageResult{.num_keys = 1, .more = true}; }); return all_store_ids; @@ -550,7 +538,7 @@ void S3GCManager::removeOutdatedManifest(const CheckpointManifestS3Set & manifes for (const auto & mf : manifests.objects()) { // store is tombstone, remove all manifests - deleteObject(*client, client->bucket(), mf.second.key); + deleteObject(*client, mf.second.key); LOG_INFO( log, "remove outdated manifest because store is tombstone, key={} mtime={}", @@ -566,7 +554,7 @@ void S3GCManager::removeOutdatedManifest(const CheckpointManifestS3Set & manifes for (const auto & mf : outdated_mfs) { // expired manifest, remove - deleteObject(*client, client->bucket(), mf.key); + deleteObject(*client, mf.key); LOG_INFO( log, "remove outdated manifest, key={} mtime={}", diff --git a/dbms/src/Storages/S3/S3RandomAccessFile.cpp b/dbms/src/Storages/S3/S3RandomAccessFile.cpp index 843d2517fa1..92bc1301e2a 100644 --- a/dbms/src/Storages/S3/S3RandomAccessFile.cpp +++ b/dbms/src/Storages/S3/S3RandomAccessFile.cpp @@ -30,11 +30,9 @@ extern const Event S3ReadBytes; namespace DB::S3 { S3RandomAccessFile::S3RandomAccessFile( - std::shared_ptr client_ptr_, - const String & bucket_, + std::shared_ptr client_ptr_, const String & remote_fname_) : client_ptr(std::move(client_ptr_)) - , bucket(bucket_) , remote_fname(remote_fname_) , log(Logger::get("S3RandomAccessFile")) { @@ -48,7 +46,7 @@ ssize_t S3RandomAccessFile::read(char * buf, size_t size) size_t gcount = istr.gcount(); if (gcount == 0 && !istr.eof()) { - LOG_ERROR(log, "Cannot read from istream. bucket={} key={}", bucket, remote_fname); + LOG_ERROR(log, "Cannot read from istream. bucket={} root={} key={}", client_ptr->bucket(), client_ptr->root(), remote_fname); return -1; } ProfileEvents::increment(ProfileEvents::S3ReadBytes, gcount); @@ -76,13 +74,12 @@ void S3RandomAccessFile::initialize() { Stopwatch sw; Aws::S3::Model::GetObjectRequest req; - req.SetBucket(bucket); - req.SetKey(remote_fname); + client_ptr->setBucketAndKeyWithRoot(req, remote_fname); ProfileEvents::increment(ProfileEvents::S3GetObject); auto outcome = client_ptr->GetObject(req); if (!outcome.IsSuccess()) { - throw S3::fromS3Error(outcome.GetError(), "bucket={} key={}", bucket, remote_fname); + throw S3::fromS3Error(outcome.GetError(), "S3 GetObject failed, bucket={} root={} key={}", client_ptr->bucket(), client_ptr->root(), remote_fname); } ProfileEvents::increment(ProfileEvents::S3ReadBytes, outcome.GetResult().GetContentLength()); GET_METRIC(tiflash_storage_s3_request_seconds, type_get_object).Observe(sw.elapsedSeconds()); @@ -111,6 +108,6 @@ RandomAccessFilePtr S3RandomAccessFile::create(const String & remote_fname) return file; } auto & ins = S3::ClientFactory::instance(); - return std::make_shared(ins.sharedClient(), ins.bucket(), remote_fname); + return std::make_shared(ins.sharedTiFlashClient(), remote_fname); } } // namespace DB::S3 diff --git a/dbms/src/Storages/S3/S3RandomAccessFile.h b/dbms/src/Storages/S3/S3RandomAccessFile.h index 767dbe49da2..11c1ec29e98 100644 --- a/dbms/src/Storages/S3/S3RandomAccessFile.h +++ b/dbms/src/Storages/S3/S3RandomAccessFile.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -38,8 +39,7 @@ class S3RandomAccessFile final : public RandomAccessFile static RandomAccessFilePtr create(const String & remote_fname); S3RandomAccessFile( - std::shared_ptr client_ptr_, - const String & bucket_, + std::shared_ptr client_ptr_, const String & remote_fname_); off_t seek(off_t offset, int whence) override; @@ -48,7 +48,7 @@ class S3RandomAccessFile final : public RandomAccessFile std::string getFileName() const override { - return fmt::format("{}/{}", bucket, remote_fname); + return fmt::format("{}/{}", client_ptr->bucket(), remote_fname); } ssize_t pread(char * /*buf*/, size_t /*size*/, off_t /*offset*/) const override @@ -74,8 +74,7 @@ class S3RandomAccessFile final : public RandomAccessFile private: void initialize(); - std::shared_ptr client_ptr; - String bucket; + std::shared_ptr client_ptr; String remote_fname; Aws::S3::Model::GetObjectResult read_result; diff --git a/dbms/src/Storages/S3/S3WritableFile.cpp b/dbms/src/Storages/S3/S3WritableFile.cpp index 30cbfa291b0..03884ed18b4 100644 --- a/dbms/src/Storages/S3/S3WritableFile.cpp +++ b/dbms/src/Storages/S3/S3WritableFile.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -56,12 +57,10 @@ struct S3WritableFile::PutObjectTask }; S3WritableFile::S3WritableFile( - std::shared_ptr client_ptr_, - const String & bucket_, + std::shared_ptr client_ptr_, const String & remote_fname_, const WriteSettings & write_settings_) - : bucket(bucket_) - , remote_fname(remote_fname_) + : remote_fname(remote_fname_) , client_ptr(std::move(client_ptr_)) , write_settings(write_settings_) , log(Logger::get("S3WritableFile")) @@ -76,7 +75,7 @@ ssize_t S3WritableFile::write(char * buf, size_t size) temporary_buffer->write(buf, size); if (!temporary_buffer->good()) { - LOG_ERROR(log, "write size={} failed: bucket={} key={}", size, bucket, remote_fname); + LOG_ERROR(log, "write size={} failed: bucket={} root={} key={}", size, client_ptr->bucket(), client_ptr->root(), remote_fname); return -1; } ProfileEvents::increment(ProfileEvents::S3WriteBytes, size); @@ -127,7 +126,7 @@ void S3WritableFile::finalize() if (write_settings.check_objects_after_upload) { // TODO(jinhe): check checksums. - auto resp = S3::headObject(*client_ptr, bucket, remote_fname); + auto resp = S3::headObject(*client_ptr, remote_fname); checkS3Outcome(resp); } } @@ -139,8 +138,7 @@ void S3WritableFile::createMultipartUpload() GET_METRIC(tiflash_storage_s3_request_seconds, type_create_multi_part_upload).Observe(sw.elapsedSeconds()); }); Aws::S3::Model::CreateMultipartUploadRequest req; - req.SetBucket(bucket); - req.SetKey(remote_fname); + client_ptr->setBucketAndKeyWithRoot(req, remote_fname); req.SetContentType("binary/octet-stream"); ProfileEvents::increment(ProfileEvents::S3CreateMultipartUpload); auto outcome = client_ptr->CreateMultipartUpload(req); @@ -153,7 +151,7 @@ void S3WritableFile::writePart() auto size = temporary_buffer->tellp(); if (size < 0) { - throw Exception(ErrorCodes::CORRUPTED_DATA, "Buffer is in bad state. bucket={}, key={}", bucket, remote_fname); + throw Exception(ErrorCodes::CORRUPTED_DATA, "Buffer is in bad state. bucket={} root={} key={}", client_ptr->bucket(), client_ptr->root(), remote_fname); } if (size == 0) { @@ -172,8 +170,7 @@ void S3WritableFile::fillUploadRequest(Aws::S3::Model::UploadPartRequest & req) // Increase part number. ++part_number; // Setup request. - req.SetBucket(bucket); - req.SetKey(remote_fname); + client_ptr->setBucketAndKeyWithRoot(req, remote_fname); req.SetPartNumber(static_cast(part_number)); req.SetUploadId(multipart_upload_id); req.SetContentLength(temporary_buffer->tellp()); @@ -195,11 +192,10 @@ void S3WritableFile::processUploadRequest(UploadPartTask & task) void S3WritableFile::completeMultipartUpload() { - RUNTIME_CHECK_MSG(!part_tags.empty(), "Failed to complete multipart upload. No parts have uploaded. bucket={}, key={}", bucket, remote_fname); + RUNTIME_CHECK_MSG(!part_tags.empty(), "Failed to complete multipart upload. No parts have uploaded. bucket={} root={} key={}", client_ptr->bucket(), client_ptr->root(), remote_fname); Aws::S3::Model::CompleteMultipartUploadRequest req; - req.SetBucket(bucket); - req.SetKey(remote_fname); + client_ptr->setBucketAndKeyWithRoot(req, remote_fname); req.SetUploadId(multipart_upload_id); Aws::S3::Model::CompletedMultipartUpload multipart_upload; for (size_t i = 0; i < part_tags.size(); ++i) @@ -220,17 +216,33 @@ void S3WritableFile::completeMultipartUpload() auto outcome = client_ptr->CompleteMultipartUpload(req); if (outcome.IsSuccess()) { - LOG_DEBUG(log, "Multipart upload has completed. bucket={} key={} upload_id={} parts={}", bucket, remote_fname, multipart_upload_id, part_tags.size()); + LOG_DEBUG(log, "Multipart upload has completed. bucket={} root={} key={} upload_id={} parts={}", client_ptr->bucket(), client_ptr->root(), remote_fname, multipart_upload_id, part_tags.size()); break; } if (i + 1 < max_retry) { const auto & e = outcome.GetError(); - LOG_INFO(log, "Multipart upload failed and need retry: bucket={} key={} upload_id={} parts={} error={} message={}", bucket, remote_fname, multipart_upload_id, part_tags.size(), magic_enum::enum_name(e.GetErrorType()), e.GetMessage()); + LOG_INFO( + log, + "Multipart upload failed and need retry: bucket={} root={} key={} upload_id={} parts={} error={} message={}", + client_ptr->bucket(), + client_ptr->root(), + remote_fname, + multipart_upload_id, + part_tags.size(), + magic_enum::enum_name(e.GetErrorType()), + e.GetMessage()); } else { - throw fromS3Error(outcome.GetError(), "bucket={} key={} upload_id={} parts={}", bucket, remote_fname, multipart_upload_id, part_tags.size()); + throw fromS3Error( + outcome.GetError(), + "S3 CompleteMultipartUpload failed, bucket={} root={} key={} upload_id={} parts={}", + client_ptr->bucket(), + client_ptr->root(), + remote_fname, + multipart_upload_id, + part_tags.size()); } } } @@ -240,7 +252,7 @@ void S3WritableFile::makeSinglepartUpload() auto size = temporary_buffer->tellp(); if (size < 0) { - throw Exception(ErrorCodes::CORRUPTED_DATA, "Buffer is in bad state. bucket={}, key={}", bucket, remote_fname); + throw Exception(ErrorCodes::CORRUPTED_DATA, "Buffer is in bad state. bucket={} root={} key={}", client_ptr->bucket(), client_ptr->root(), remote_fname); } PutObjectTask task; fillPutRequest(task.req); @@ -249,8 +261,7 @@ void S3WritableFile::makeSinglepartUpload() void S3WritableFile::fillPutRequest(Aws::S3::Model::PutObjectRequest & req) { - req.SetBucket(bucket); - req.SetKey(remote_fname); + client_ptr->setBucketAndKeyWithRoot(req, remote_fname); req.SetContentLength(temporary_buffer->tellp()); req.SetBody(temporary_buffer); req.SetContentType("binary/octet-stream"); @@ -269,17 +280,17 @@ void S3WritableFile::processPutRequest(const PutObjectTask & task) auto outcome = client_ptr->PutObject(task.req); if (outcome.IsSuccess()) { - LOG_DEBUG(log, "Single part upload has completed. bucket={}, key={}, size={}", bucket, remote_fname, task.req.GetContentLength()); + LOG_DEBUG(log, "Single part upload has completed. bucket={} root={} key={}, size={}", client_ptr->bucket(), client_ptr->root(), remote_fname, task.req.GetContentLength()); break; } if (i + 1 < max_retry) { const auto & e = outcome.GetError(); - LOG_INFO(log, "Single part upload failed: bucket={} key={} error={} message={}", bucket, remote_fname, magic_enum::enum_name(e.GetErrorType()), e.GetMessage()); + LOG_INFO(log, "Single part upload failed: bucket={} root={} key={} error={} message={}", client_ptr->bucket(), client_ptr->root(), remote_fname, magic_enum::enum_name(e.GetErrorType()), e.GetMessage()); } else { - throw fromS3Error(outcome.GetError(), "bucket={} key={}", bucket, remote_fname); + throw fromS3Error(outcome.GetError(), "S3 PutObject failed, bucket={} root={} key={}", client_ptr->bucket(), client_ptr->root(), remote_fname); } } } @@ -287,8 +298,7 @@ void S3WritableFile::processPutRequest(const PutObjectTask & task) std::shared_ptr S3WritableFile::create(const String & remote_fname_) { return std::make_shared( - S3::ClientFactory::instance().sharedClient(), - S3::ClientFactory::instance().bucket(), + S3::ClientFactory::instance().sharedTiFlashClient(), remote_fname_, WriteSettings{}); } diff --git a/dbms/src/Storages/S3/S3WritableFile.h b/dbms/src/Storages/S3/S3WritableFile.h index 809cb2eaf65..2b4003d309f 100644 --- a/dbms/src/Storages/S3/S3WritableFile.h +++ b/dbms/src/Storages/S3/S3WritableFile.h @@ -51,8 +51,7 @@ class S3WritableFile final : public WritableFile static std::shared_ptr create(const String & remote_fname_); S3WritableFile( - std::shared_ptr client_ptr_, - const String & bucket_, + std::shared_ptr client_ptr_, const String & remote_fname_, const WriteSettings & write_settings_); @@ -65,7 +64,7 @@ class S3WritableFile final : public WritableFile std::string getFileName() const override { - return fmt::format("{}/{}", bucket, remote_fname); + return fmt::format("{}/{}", client_ptr->bucket(), remote_fname); } void close() override @@ -145,13 +144,12 @@ class S3WritableFile final : public WritableFile { if (!outcome.IsSuccess()) { - throw S3::fromS3Error(outcome.GetError(), "bucket={} key={}", bucket, remote_fname); + throw S3::fromS3Error(outcome.GetError(), "bucket={} root={} key={}", client_ptr->bucket(), client_ptr->root(), remote_fname); } } - const String bucket; const String remote_fname; - const std::shared_ptr client_ptr; + const std::shared_ptr client_ptr; const WriteSettings write_settings; std::shared_ptr temporary_buffer; // Buffer to accumulate data. @@ -168,4 +166,4 @@ class S3WritableFile final : public WritableFile bool is_close = false; }; -} // namespace DB::S3 \ No newline at end of file +} // namespace DB::S3 diff --git a/dbms/src/Storages/S3/tests/gtest_filecache.cpp b/dbms/src/Storages/S3/tests/gtest_filecache.cpp index 81031c92b1a..dd8df69f793 100644 --- a/dbms/src/Storages/S3/tests/gtest_filecache.cpp +++ b/dbms/src/Storages/S3/tests/gtest_filecache.cpp @@ -55,9 +55,8 @@ class FileCacheTest : public ::testing::Test tmp_dir = DB::tests::TiFlashTestEnv::getTemporaryPath("FileCacheTest"); log = Logger::get("FileCacheTest"); std::filesystem::remove_all(std::filesystem::path(tmp_dir)); - s3_client = ::DB::S3::ClientFactory::instance().sharedClient(); - bucket = ::DB::S3::ClientFactory::instance().bucket(); - ASSERT_TRUE(createBucketIfNotExist()); + s3_client = ::DB::S3::ClientFactory::instance().sharedTiFlashClient(); + ASSERT_TRUE(DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client)); std::random_device dev; rng = std::mt19937{dev()}; next_id = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); @@ -65,10 +64,9 @@ class FileCacheTest : public ::testing::Test } protected: - std::shared_ptr s3_client; - String bucket; + std::shared_ptr s3_client; std::mt19937 rng; - UInt64 next_id; + UInt64 next_id = 0; inline static const std::vector basenames = { "%2D1.dat", @@ -88,31 +86,11 @@ class FileCacheTest : public ::testing::Test "meta", }; - bool createBucketIfNotExist() - { - Aws::S3::Model::CreateBucketRequest request; - request.SetBucket(bucket); - Aws::S3::Model::CreateBucketOutcome outcome = s3_client->CreateBucket(request); - if (outcome.IsSuccess()) - { - LOG_DEBUG(log, "Created bucket {}", bucket); - } - else if (outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou") - { - LOG_DEBUG(log, "Bucket {} already exist", bucket); - } - else - { - const auto & err = outcome.GetError(); - LOG_ERROR(log, "CreateBucket: {}:{}", err.GetExceptionName(), err.GetMessage()); - } - return outcome.IsSuccess() || outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou"; - } void writeFile(const String & key, char value, size_t size, const WriteSettings & write_setting) { Stopwatch sw; - S3WritableFile file(s3_client, bucket, key, write_setting); + S3WritableFile file(s3_client, key, write_setting); size_t write_size = 0; constexpr size_t buf_size = 1024 * 1024 * 10; String buf_unit(buf_size, value); diff --git a/dbms/src/Storages/S3/tests/gtest_s3client.cpp b/dbms/src/Storages/S3/tests/gtest_s3client.cpp new file mode 100644 index 00000000000..948777d8ba1 --- /dev/null +++ b/dbms/src/Storages/S3/tests/gtest_s3client.cpp @@ -0,0 +1,82 @@ +// Copyright 2023 PingCAP, Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include + +namespace DB::S3::tests +{ + +class S3ClientTest : public ::testing::Test +{ +public: + void SetUp() override + { + client = ClientFactory::instance().sharedTiFlashClient(); + ::DB::tests::TiFlashTestEnv::deleteBucket(*client); + ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*client); + } + + std::shared_ptr client; +}; + +TEST_F(S3ClientTest, UploadRead) +try +{ + deleteObject(*client, "s999/manifest/mf_1"); + ASSERT_FALSE(objectExists(*client, "s999/manifest/mf_1")); + uploadEmptyFile(*client, "s999/manifest/mf_1"); + ASSERT_TRUE(objectExists(*client, "s999/manifest/mf_1")); + + uploadEmptyFile(*client, "s999/manifest/mf_2"); + uploadEmptyFile(*client, "s999/manifest/mf_789"); + + uploadEmptyFile(*client, "s999/data/dat_789_0"); + uploadEmptyFile(*client, "s999/data/dat_790_0"); + + uploadEmptyFile(*client, "s999/abcd"); + + { + Strings prefixes; + listPrefixWithDelimiter(*client, "s999/", "/", [&](const Aws::S3::Model::CommonPrefix & p) { + prefixes.emplace_back(p.GetPrefix()); + return PageResult{.num_keys = 1, .more = true}; + }); + ASSERT_EQ(prefixes.size(), 2) << fmt::format("{}", prefixes); + EXPECT_EQ(prefixes[0], "s999/data/"); + EXPECT_EQ(prefixes[1], "s999/manifest/"); + } + + // check the keys with raw `LIST` request + { + Strings prefixes; + rawListPrefix(*client, client->bucket(), client->root() + "s999/", "/", [&](const Aws::S3::Model::ListObjectsV2Result & result) { + const auto & ps = result.GetCommonPrefixes(); + for (const auto & p : ps) + { + prefixes.emplace_back(p.GetPrefix()); + } + return PageResult{.num_keys = ps.size(), .more = true}; + }); + ASSERT_EQ(prefixes.size(), 2) << fmt::format("{}", prefixes); + EXPECT_EQ(prefixes[0], client->root() + "s999/data/"); + EXPECT_EQ(prefixes[1], client->root() + "s999/manifest/"); + } +} +CATCH + +} // namespace DB::S3::tests diff --git a/dbms/src/Storages/S3/tests/gtest_s3file.cpp b/dbms/src/Storages/S3/tests/gtest_s3file.cpp index 7bc44648cf2..fb436baa8ec 100644 --- a/dbms/src/Storages/S3/tests/gtest_s3file.cpp +++ b/dbms/src/Storages/S3/tests/gtest_s3file.cpp @@ -67,10 +67,9 @@ class S3FileTest : public DB::base::TiFlashStorageTestBasic buf_unit.resize(256); std::iota(buf_unit.begin(), buf_unit.end(), 0); - s3_client = S3::ClientFactory::instance().sharedClient(); - bucket = S3::ClientFactory::instance().bucket(); + s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); data_store = std::make_shared(dbContext().getFileProvider()); - ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client, bucket)); + ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client)); } void reload() @@ -83,7 +82,7 @@ class S3FileTest : public DB::base::TiFlashStorageTestBasic protected: void writeFile(const String & key, size_t size, const WriteSettings & write_setting) { - S3WritableFile file(s3_client, bucket, key, write_setting); + S3WritableFile file(s3_client, key, write_setting); size_t write_size = 0; while (write_size < size) { @@ -99,7 +98,7 @@ class S3FileTest : public DB::base::TiFlashStorageTestBasic void verifyFile(const String & key, size_t size) { - S3RandomAccessFile file(s3_client, bucket, key); + S3RandomAccessFile file(s3_client, key); std::vector tmp_buf; size_t read_size = 0; while (read_size < size) @@ -152,7 +151,7 @@ class S3FileTest : public DB::base::TiFlashStorageTestBasic S3::S3Filename::fromTableID(oid.store_id, oid.table_id).toFullKey(), oid.file_id, DMFile::Status::READABLE); - return S3::listPrefixWithSize(*s3_client, bucket, dmfile_dir + "/"); + return S3::listPrefixWithSize(*s3_client, dmfile_dir + "/"); } DMFilePtr restoreDMFile(const DMFileOID & oid) @@ -162,8 +161,7 @@ class S3FileTest : public DB::base::TiFlashStorageTestBasic LoggerPtr log; std::vector buf_unit; - std::shared_ptr s3_client; - String bucket; + std::shared_ptr s3_client; S3WritableFile::UploadInfo last_upload_info; Remote::IDataStorePtr data_store; }; @@ -209,7 +207,7 @@ try WriteSettings write_setting; const String key = "/a/b/c/seek"; writeFile(key, size, write_setting); - S3RandomAccessFile file(s3_client, bucket, key); + S3RandomAccessFile file(s3_client, key); { std::vector tmp_buf(256); auto n = file.read(tmp_buf.data(), tmp_buf.size()); @@ -430,15 +428,14 @@ try data_store->putCheckpointFiles(checkpoint, store_id, sequence); // ensure CheckpointDataFile, theirs lock file and CheckpointManifest are uploaded - auto s3client = S3::ClientFactory::instance().sharedClient(); - auto s3bucket = S3::ClientFactory::instance().bucket(); + auto s3client = S3::ClientFactory::instance().sharedTiFlashClient(); auto cp_data0 = S3::S3Filename::newCheckpointData(store_id, sequence, 0); - ASSERT_TRUE(S3::objectExists(*s3client, s3bucket, cp_data0.toFullKey())); - ASSERT_TRUE(S3::objectExists(*s3client, s3bucket, cp_data0.toView().getLockKey(store_id, sequence))); + ASSERT_TRUE(S3::objectExists(*s3client, cp_data0.toFullKey())); + ASSERT_TRUE(S3::objectExists(*s3client, cp_data0.toView().getLockKey(store_id, sequence))); auto cp_data1 = S3::S3Filename::newCheckpointData(store_id, sequence, 1); - ASSERT_TRUE(S3::objectExists(*s3client, s3bucket, cp_data1.toFullKey())); - ASSERT_TRUE(S3::objectExists(*s3client, s3bucket, cp_data1.toView().getLockKey(store_id, sequence))); - ASSERT_TRUE(S3::objectExists(*s3client, s3bucket, S3::S3Filename::newCheckpointManifest(store_id, sequence).toFullKey())); + ASSERT_TRUE(S3::objectExists(*s3client, cp_data1.toFullKey())); + ASSERT_TRUE(S3::objectExists(*s3client, cp_data1.toView().getLockKey(store_id, sequence))); + ASSERT_TRUE(S3::objectExists(*s3client, S3::S3Filename::newCheckpointManifest(store_id, sequence).toFullKey())); } CATCH diff --git a/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp b/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp index 107ee4dc47e..a8244b7e7e8 100644 --- a/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp +++ b/dbms/src/Storages/S3/tests/gtest_s3gcmanager.cpp @@ -71,7 +71,7 @@ class S3GCManagerTest : public DB::base::TiFlashStorageTestBasic auto mock_pd_client = std::make_shared(); gc_mgr = std::make_unique(mock_pd_client, mock_gc_owner, mock_lock_client, config); - ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*mock_s3_client, mock_s3_client->bucket()); + ::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*mock_s3_client); dir = getTemporaryPath(); dropDataOnDisk(dir); @@ -80,7 +80,7 @@ class S3GCManagerTest : public DB::base::TiFlashStorageTestBasic void TearDown() override { - ::DB::tests::TiFlashTestEnv::deleteBucket(*mock_s3_client, mock_s3_client->bucket()); + ::DB::tests::TiFlashTestEnv::deleteBucket(*mock_s3_client); } protected: @@ -123,7 +123,7 @@ try for (const auto & [seq, diff_sec] : mfs) { auto key = S3Filename::newCheckpointManifest(store_id, seq).toFullKey(); - uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), key); + uploadEmptyFile(*mock_s3_client, key); objs.emplace_back(CheckpointManifestS3Object{ .key = key, .last_modification = timepoint + std::chrono::milliseconds(diff_sec * 1000), @@ -174,11 +174,11 @@ try if (seq == 4 || seq == 5) { // deleted - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), obj.key)); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, obj.key)); } else { - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), obj.key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, obj.key)); } } } @@ -190,28 +190,28 @@ try { auto timepoint = Aws::Utils::DateTime("2023-02-01T08:00:00Z", Aws::Utils::DateFormat::ISO_8601); { - uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), "datafile_key"); - uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), "datafile_key.del"); + uploadEmptyFile(*mock_s3_client, "datafile_key"); + uploadEmptyFile(*mock_s3_client, "datafile_key.del"); // delmark expired auto delmark_mtime = timepoint - std::chrono::milliseconds(3601 * 1000); gc_mgr->removeDataFileIfDelmarkExpired("datafile_key", "datafile_key.del", timepoint, delmark_mtime); // removed - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), "datafile_key")); - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), "datafile_key.del")); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, "datafile_key")); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, "datafile_key.del")); } { - uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), "datafile_key"); - uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), "datafile_key.del"); + uploadEmptyFile(*mock_s3_client, "datafile_key"); + uploadEmptyFile(*mock_s3_client, "datafile_key.del"); // delmark not expired auto delmark_mtime = timepoint - std::chrono::milliseconds(3599 * 1000); gc_mgr->removeDataFileIfDelmarkExpired("datafile_key", "datafile_key.del", timepoint, delmark_mtime); // removed - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), "datafile_key")); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), "datafile_key.del")); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, "datafile_key")); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, "datafile_key.del")); } } CATCH @@ -229,69 +229,69 @@ try auto timepoint = Aws::Utils::DateTime("2023-02-01T08:00:00Z", Aws::Utils::DateFormat::ISO_8601); auto clear_bucket = [&] { - DB::tests::TiFlashTestEnv::deleteBucket(*mock_s3_client, mock_s3_client->bucket()); - DB::tests::TiFlashTestEnv::createBucketIfNotExist(*mock_s3_client, mock_s3_client->bucket()); + DB::tests::TiFlashTestEnv::deleteBucket(*mock_s3_client); + DB::tests::TiFlashTestEnv::createBucketIfNotExist(*mock_s3_client); }; { clear_bucket(); // delmark not exist, and no more lockfile - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey()); - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), lock_key); + S3::uploadEmptyFile(*mock_s3_client, df.toFullKey()); + S3::uploadEmptyFile(*mock_s3_client, lock_key); - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), delmark_key)); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, delmark_key)); gc_mgr->cleanOneLock(lock_key, lock_view, timepoint); // lock is deleted and delmark is created - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), lock_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), delmark_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey())); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, lock_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, delmark_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, df.toFullKey())); } { clear_bucket(); // delmark not exist, but still locked by another lockfile - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey()); - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), lock_key); + S3::uploadEmptyFile(*mock_s3_client, df.toFullKey()); + S3::uploadEmptyFile(*mock_s3_client, lock_key); // another lock auto another_lock_key = df.toView().getLockKey(store_id + 1, 450); - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), another_lock_key); + S3::uploadEmptyFile(*mock_s3_client, another_lock_key); gc_mgr->cleanOneLock(lock_key, lock_view, timepoint); // lock is deleted but delmark is not created - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), lock_key)); - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), delmark_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), another_lock_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey())); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, lock_key)); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, delmark_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, another_lock_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, df.toFullKey())); } { clear_bucket(); // delmark exist, not expired - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey()); - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), delmark_key); + S3::uploadEmptyFile(*mock_s3_client, df.toFullKey()); + S3::uploadEmptyFile(*mock_s3_client, delmark_key); auto delmark_mtime = timepoint - std::chrono::milliseconds(3599 * 1000); - FailPointHelper::enableFailPoint(FailPoints::force_set_mocked_s3_object_mtime, std::map{{delmark_key, delmark_mtime}}); + FailPointHelper::enableFailPoint(FailPoints::force_set_mocked_s3_object_mtime, std::map{{mock_s3_client->root() + delmark_key, delmark_mtime}}); // mock_s3_client->head_result_mtime = delmark_mtime; gc_mgr->cleanOneLock(lock_key, lock_view, timepoint); // lock is deleted, datafile and delmark remain - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), lock_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), delmark_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey())); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, lock_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, delmark_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, df.toFullKey())); } { clear_bucket(); // delmark exist, expired - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey()); - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), delmark_key); + S3::uploadEmptyFile(*mock_s3_client, df.toFullKey()); + S3::uploadEmptyFile(*mock_s3_client, delmark_key); auto delmark_mtime = timepoint - std::chrono::milliseconds(3601 * 1000); - FailPointHelper::enableFailPoint(FailPoints::force_set_mocked_s3_object_mtime, std::map{{delmark_key, delmark_mtime}}); + FailPointHelper::enableFailPoint(FailPoints::force_set_mocked_s3_object_mtime, std::map{{mock_s3_client->root() + delmark_key, delmark_mtime}}); gc_mgr->cleanOneLock(lock_key, lock_view, timepoint); // lock datafile and delmark are deleted - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), lock_key)); - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), delmark_key)); - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey())); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, lock_key)); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, delmark_key)); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, df.toFullKey())); } } CATCH @@ -310,28 +310,29 @@ try auto timepoint = Aws::Utils::DateTime("2023-02-01T08:00:00Z", Aws::Utils::DateFormat::ISO_8601); auto clear_bucket = [&] { - DB::tests::TiFlashTestEnv::deleteBucket(*mock_s3_client, mock_s3_client->bucket()); - DB::tests::TiFlashTestEnv::createBucketIfNotExist(*mock_s3_client, mock_s3_client->bucket()); + DB::tests::TiFlashTestEnv::deleteBucket(*mock_s3_client); + DB::tests::TiFlashTestEnv::createBucketIfNotExist(*mock_s3_client); }; { clear_bucket(); // delmark not exist, and no more lockfile - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey()); - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), lock_key); + S3::uploadEmptyFile(*mock_s3_client, df.toFullKey()); + S3::uploadEmptyFile(*mock_s3_client, lock_key); - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), delmark_key)); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, delmark_key)); gc_mgr->cleanOneLock(lock_key, lock_view, timepoint); // lock is deleted and delmark is created, object is rewrite with tagging - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), lock_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), delmark_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey())); - const auto res = static_cast(mock_s3_client.get())->GetObjectTagging( // - Aws::S3::Model::GetObjectTaggingRequest() // - .WithBucket(mock_s3_client->bucket()) - .WithKey(df.toFullKey())); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, lock_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, delmark_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, df.toFullKey())); + + auto req = Aws::S3::Model::GetObjectTaggingRequest(); // + mock_s3_client->setBucketAndKeyWithRoot(req, df.toFullKey()); + const auto res = mock_s3_client->GetObjectTagging(req); + auto tags = res.GetResult().GetTagSet(); ASSERT_EQ(tags.size(), 1); EXPECT_EQ(tags[0].GetKey(), "tiflash_deleted"); @@ -340,18 +341,18 @@ try { clear_bucket(); // delmark not exist, but still locked by another lockfile - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey()); - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), lock_key); + S3::uploadEmptyFile(*mock_s3_client, df.toFullKey()); + S3::uploadEmptyFile(*mock_s3_client, lock_key); // another lock auto another_lock_key = df.toView().getLockKey(store_id + 1, 450); - S3::uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), another_lock_key); + S3::uploadEmptyFile(*mock_s3_client, another_lock_key); gc_mgr->cleanOneLock(lock_key, lock_view, timepoint); // lock is deleted but delmark is not created - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), lock_key)); - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), delmark_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), another_lock_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), df.toFullKey())); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, lock_key)); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, delmark_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, another_lock_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, df.toFullKey())); } } CATCH @@ -401,7 +402,7 @@ try // prepare for `LIST` for (const auto & k : keys) { - uploadEmptyFile(*mock_s3_client, mock_s3_client->bucket(), k); + uploadEmptyFile(*mock_s3_client, k); } } @@ -410,8 +411,8 @@ try gc_mgr->cleanUnusedLocks(lock_store_id, S3Filename::getLockPrefix(), safe_sequence, valid_lock_files, timepoint); // lock is deleted and delmark is created - ASSERT_FALSE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), expected_deleted_lock_key)); - ASSERT_TRUE(S3::objectExists(*mock_s3_client, mock_s3_client->bucket(), expected_created_delmark)); + ASSERT_FALSE(S3::objectExists(*mock_s3_client, expected_deleted_lock_key)); + ASSERT_TRUE(S3::objectExists(*mock_s3_client, expected_created_delmark)); } } CATCH @@ -475,7 +476,7 @@ try writer->writeSuffix(); writer.reset(); - S3::uploadFile(*mock_s3_client, mock_s3_client->bucket(), dir + "/" + mf_key, mf_key); + S3::uploadFile(*mock_s3_client, dir + "/" + mf_key, mf_key); } { // prepare the second manifest on S3 const String entry_data = "cherry_value"; @@ -507,7 +508,7 @@ try writer->writeSuffix(); writer.reset(); - S3::uploadFile(*mock_s3_client, mock_s3_client->bucket(), dir + "/" + mf_key2, mf_key2); + S3::uploadFile(*mock_s3_client, dir + "/" + mf_key2, mf_key2); } // read from S3 key diff --git a/dbms/src/Storages/Transaction/FastAddPeer.cpp b/dbms/src/Storages/Transaction/FastAddPeer.cpp index f7833d309d9..dc6bfd21ac7 100644 --- a/dbms/src/Storages/Transaction/FastAddPeer.cpp +++ b/dbms/src/Storages/Transaction/FastAddPeer.cpp @@ -286,13 +286,12 @@ CheckpointInfoPtr selectCheckpointInfo(Context & context, uint64_t region_id, ui auto & tmt_context = context.getTMTContext(); std::vector all_store_ids = getAllStoreIDsFromPD(tmt_context); auto current_store_id = tmt_context.getKVStore()->getStoreMeta().id(); - auto s3_client = S3::ClientFactory::instance().sharedClient(); - auto bucket = S3::ClientFactory::instance().bucket(); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); for (const auto & store_id : all_store_ids) { if (store_id == current_store_id) continue; - const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, bucket, store_id); + const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, store_id); if (manifests.empty()) { LOG_DEBUG(log, "no manifest on this store, skip store_id={}", store_id); diff --git a/dbms/src/Storages/Transaction/tests/gtest_kvstore_fast_add_peer.cpp b/dbms/src/Storages/Transaction/tests/gtest_kvstore_fast_add_peer.cpp index 73e7025aae5..f3715bcad8f 100644 --- a/dbms/src/Storages/Transaction/tests/gtest_kvstore_fast_add_peer.cpp +++ b/dbms/src/Storages/Transaction/tests/gtest_kvstore_fast_add_peer.cpp @@ -74,29 +74,6 @@ class RegionKVStoreTestFAP : public RegionKVStoreTest } protected: - bool createBucketIfNotExist() - { - auto s3_client = S3::ClientFactory::instance().sharedClient(); - auto bucket = S3::ClientFactory::instance().bucket(); - Aws::S3::Model::CreateBucketRequest request; - request.SetBucket(bucket); - auto outcome = s3_client->CreateBucket(request); - if (outcome.IsSuccess()) - { - LOG_DEBUG(Logger::get(), "Created bucket {}", bucket); - } - else if (outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou") - { - LOG_DEBUG(Logger::get(), "Bucket {} already exist", bucket); - } - else - { - const auto & err = outcome.GetError(); - LOG_ERROR(Logger::get(), "CreateBucket: {}:{}", err.GetExceptionName(), err.GetMessage()); - } - return outcome.IsSuccess() || outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou"; - } - void dumpCheckpoint() { auto & global_context = TiFlashTestEnv::getGlobalContext(); @@ -221,13 +198,12 @@ try auto [index, term] = proxy_instance->normalWrite(region_id, {34}, {"v2"}, {WriteCmdType::Put}, {ColumnFamilyType::Default}); persistAfterWrite(global_context, kvs, proxy_instance, page_storage, region_id, index); - ASSERT_TRUE(createBucketIfNotExist()); + auto s3_client = S3::ClientFactory::instance().sharedTiFlashClient(); + ASSERT_TRUE(::DB::tests::TiFlashTestEnv::createBucketIfNotExist(*s3_client)); dumpCheckpoint(); std::optional checkpoint_info; - auto s3_client = S3::ClientFactory::instance().sharedClient(); - auto bucket = S3::ClientFactory::instance().bucket(); - const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, bucket, store_id); + const auto manifests = S3::CheckpointManifestS3Set::getFromS3(*s3_client, store_id); ASSERT_TRUE(!manifests.empty()); const auto & latest_manifest_key = manifests.latestManifestKey(); auto temp_ps_wrapper = reuseOrCreateTempPageStorage(global_context, latest_manifest_key); diff --git a/dbms/src/TestUtils/TiFlashTestEnv.cpp b/dbms/src/TestUtils/TiFlashTestEnv.cpp index 59d77829f4f..fa788a8f580 100644 --- a/dbms/src/TestUtils/TiFlashTestEnv.cpp +++ b/dbms/src/TestUtils/TiFlashTestEnv.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -238,32 +239,31 @@ FileProviderPtr TiFlashTestEnv::getMockFileProvider() return std::make_shared(std::make_shared(encryption_enabled), encryption_enabled); } -bool TiFlashTestEnv::createBucketIfNotExist(Aws::S3::S3Client & s3_client, const String & bucket) +bool TiFlashTestEnv::createBucketIfNotExist(::DB::S3::TiFlashS3Client & s3_client) { - auto log = Logger::get(); Aws::S3::Model::CreateBucketRequest request; - request.SetBucket(bucket); + request.SetBucket(s3_client.bucket()); auto outcome = s3_client.CreateBucket(request); if (outcome.IsSuccess()) { - LOG_DEBUG(log, "Created bucket {}", bucket); + LOG_DEBUG(s3_client.log, "Created bucket {}", s3_client.bucket()); } else if (outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou") { - LOG_DEBUG(log, "Bucket {} already exist", bucket); + LOG_DEBUG(s3_client.log, "Bucket {} already exist", s3_client.bucket()); } else { const auto & err = outcome.GetError(); - LOG_ERROR(log, "CreateBucket: {}:{}", err.GetExceptionName(), err.GetMessage()); + LOG_ERROR(s3_client.log, "CreateBucket: {}:{}", err.GetExceptionName(), err.GetMessage()); } return outcome.IsSuccess() || outcome.GetError().GetExceptionName() == "BucketAlreadyOwnedByYou"; } -void TiFlashTestEnv::deleteBucket(Aws::S3::S3Client & s3_client, const String & bucket) +void TiFlashTestEnv::deleteBucket(::DB::S3::TiFlashS3Client & s3_client) { Aws::S3::Model::DeleteBucketRequest request; - request.SetBucket(bucket); + request.SetBucket(s3_client.bucket()); s3_client.DeleteBucket(request); } diff --git a/dbms/src/TestUtils/TiFlashTestEnv.h b/dbms/src/TestUtils/TiFlashTestEnv.h index 1036f69369d..2cc5a94701a 100644 --- a/dbms/src/TestUtils/TiFlashTestEnv.h +++ b/dbms/src/TestUtils/TiFlashTestEnv.h @@ -24,16 +24,16 @@ #include #include -namespace Aws::S3 -{ -class S3Client; -} namespace DB { struct Settings; class DAGContext; class MockStorage; +namespace S3 +{ +class TiFlashS3Client; +} } // namespace DB namespace DB::tests @@ -105,9 +105,9 @@ class TiFlashTestEnv static FileProviderPtr getMockFileProvider(); - static bool createBucketIfNotExist(Aws::S3::S3Client & s3_client, const String & bucket); + static bool createBucketIfNotExist(::DB::S3::TiFlashS3Client & s3_client); - static void deleteBucket(Aws::S3::S3Client & s3_client, const String & bucket); + static void deleteBucket(::DB::S3::TiFlashS3Client & s3_client); TiFlashTestEnv() = delete; diff --git a/dbms/src/TestUtils/gtests_dbms_main.cpp b/dbms/src/TestUtils/gtests_dbms_main.cpp index ad24ddb22b7..47a77671be0 100644 --- a/dbms/src/TestUtils/gtests_dbms_main.cpp +++ b/dbms/src/TestUtils/gtests_dbms_main.cpp @@ -83,7 +83,8 @@ int main(int argc, char ** argv) DB::RNRemoteReadTaskPool::initialize(/*max_threads*/ 20, /*max_free_threds*/ 10, /*queue_size*/ 1000); DB::RNPagePreparerPool::initialize(/*max_threads*/ 20, /*max_free_threds*/ 10, /*queue_size*/ 1000); const auto s3_endpoint = Poco::Environment::get("S3_ENDPOINT", ""); - const auto s3_bucket = Poco::Environment::get("S3_BUCKET", "mock_bucket"); + const auto s3_bucket = Poco::Environment::get("S3_BUCKET", "mockbucket"); + const auto s3_root = Poco::Environment::get("S3_ROOT", "tiflash_ut/"); const auto access_key_id = Poco::Environment::get("AWS_ACCESS_KEY_ID", ""); const auto secret_access_key = Poco::Environment::get("AWS_SECRET_ACCESS_KEY", ""); const auto mock_s3 = Poco::Environment::get("MOCK_S3", "true"); // In unit-tests, use MockS3Client by default. @@ -92,6 +93,7 @@ int main(int argc, char ** argv) .bucket = s3_bucket, .access_key_id = access_key_id, .secret_access_key = secret_access_key, + .root = s3_root, }; Poco::Environment::set("AWS_EC2_METADATA_DISABLED", "true"); // disable to speedup testing DB::S3::ClientFactory::instance().init(s3config, mock_s3 == "true"); From 0d7bc62cac3d16817101e5abef23f9267097776c Mon Sep 17 00:00:00 2001 From: jinhelin Date: Thu, 16 Mar 2023 10:42:39 +0800 Subject: [PATCH 17/18] Fix checksums of metav2. (#7077) ref pingcap/tiflash#6825 --- dbms/src/Storages/DeltaMerge/File/DMFile.cpp | 55 +++++++----------- dbms/src/Storages/DeltaMerge/File/DMFile.h | 6 +- .../DeltaMerge/tests/gtest_dm_file.cpp | 57 ++++++++++++++++++- 3 files changed, 79 insertions(+), 39 deletions(-) diff --git a/dbms/src/Storages/DeltaMerge/File/DMFile.cpp b/dbms/src/Storages/DeltaMerge/File/DMFile.cpp index 0c88cd8ac6e..d3d76ea4cfc 100644 --- a/dbms/src/Storages/DeltaMerge/File/DMFile.cpp +++ b/dbms/src/Storages/DeltaMerge/File/DMFile.cpp @@ -805,20 +805,16 @@ void DMFile::initializeIndices() } } -DMFile::MetaBlockHandle DMFile::writeSLPackStatToBuffer(WriteBuffer & buffer, DB::UnifiedDigestBaseBox & digest) +DMFile::MetaBlockHandle DMFile::writeSLPackStatToBuffer(WriteBuffer & buffer) { auto offset = buffer.count(); const char * data = reinterpret_cast(&pack_stats[0]); size_t size = pack_stats.size() * sizeof(PackStat); - if (digest) - { - digest->update(data, size); - } writeString(data, size, buffer); return MetaBlockHandle{MetaBlockType::PackStat, offset, buffer.count() - offset}; } -DMFile::MetaBlockHandle DMFile::writeSLPackPropertyToBuffer(WriteBuffer & buffer, DB::UnifiedDigestBaseBox & digest) +DMFile::MetaBlockHandle DMFile::writeSLPackPropertyToBuffer(WriteBuffer & buffer) { auto offset = buffer.count(); for (const auto & pb : pack_properties.property()) @@ -826,55 +822,44 @@ DMFile::MetaBlockHandle DMFile::writeSLPackPropertyToBuffer(WriteBuffer & buffer PackProperty tmp{pb}; const char * data = reinterpret_cast(&tmp); size_t size = sizeof(PackProperty); - if (digest) - { - digest->update(data, size); - } writeString(data, size, buffer); } return MetaBlockHandle{MetaBlockType::PackProperty, offset, buffer.count() - offset}; } -DMFile::MetaBlockHandle DMFile::writeColumnStatToBuffer(WriteBuffer & buffer, DB::UnifiedDigestBaseBox & digest) +DMFile::MetaBlockHandle DMFile::writeColumnStatToBuffer(WriteBuffer & buffer) { auto offset = buffer.count(); writeIntBinary(column_stats.size(), buffer); for (const auto & [id, stat] : column_stats) { - auto tmp_buffer = WriteBufferFromOwnString{}; - stat.serializeToBuffer(tmp_buffer); - auto serialized = tmp_buffer.releaseStr(); - if (digest) - { - digest->update(serialized.data(), serialized.length()); - } - writeString(serialized.data(), serialized.size(), buffer); + stat.serializeToBuffer(buffer); } return MetaBlockHandle{MetaBlockType::ColumnStat, offset, buffer.count() - offset}; } void DMFile::finalizeMetaV2(WriteBuffer & buffer) { + auto tmp_buffer = WriteBufferFromOwnString{}; auto digest = configuration ? configuration->createUnifiedDigest() : nullptr; - auto pack_stats_handle = writeSLPackStatToBuffer(buffer, digest); - auto pack_properties_handle = writeSLPackPropertyToBuffer(buffer, digest); - auto column_stats_handle = writeColumnStatToBuffer(buffer, digest); + auto pack_stats_handle = writeSLPackStatToBuffer(tmp_buffer); + auto pack_properties_handle = writeSLPackPropertyToBuffer(tmp_buffer); + auto column_stats_handle = writeColumnStatToBuffer(tmp_buffer); - writePODBinary(pack_stats_handle, buffer); - writePODBinary(pack_properties_handle, buffer); - writePODBinary(column_stats_handle, buffer); + writePODBinary(pack_stats_handle, tmp_buffer); + writePODBinary(pack_properties_handle, tmp_buffer); + writePODBinary(column_stats_handle, tmp_buffer); UInt64 meta_block_handle_count = 3; - writeIntBinary(meta_block_handle_count, buffer); - writeIntBinary(version, buffer); + writeIntBinary(meta_block_handle_count, tmp_buffer); + writeIntBinary(version, tmp_buffer); - if (digest) + // Write to file and do checksums. + auto s = tmp_buffer.releaseStr(); + writeString(s.data(), s.size(), buffer); + if (configuration) { - digest->update(reinterpret_cast(&pack_stats_handle), sizeof(MetaBlockHandle)); - digest->update(reinterpret_cast(&pack_properties_handle), sizeof(MetaBlockHandle)); - digest->update(reinterpret_cast(&column_stats_handle), sizeof(MetaBlockHandle)); - digest->update(reinterpret_cast(&meta_block_handle_count), sizeof(UInt64)); - digest->update(reinterpret_cast(&version), sizeof(DMFileFormat::Version)); - + auto digest = configuration->createUnifiedDigest(); + digest->update(s.data(), s.size()); auto checksum_result = digest->raw(); writeString(checksum_result.data(), checksum_result.size(), buffer); } @@ -929,7 +914,7 @@ void DMFile::parseMetaV2(std::string_view buffer) auto hash_size = digest->hashSize(); ptr = ptr - hash_size; digest->update(buffer.data(), buffer.size() - sizeof(MetaFooter) - hash_size); - if (unlikely(digest->compareRaw(ptr))) + if (unlikely(!digest->compareRaw(ptr))) { LOG_ERROR(log, "{} checksum invalid", metav2Path()); throw Exception(ErrorCodes::CORRUPTED_DATA, "{} checksum invalid", metav2Path()); diff --git a/dbms/src/Storages/DeltaMerge/File/DMFile.h b/dbms/src/Storages/DeltaMerge/File/DMFile.h index 9bc8b72d4b2..196e5250df5 100644 --- a/dbms/src/Storages/DeltaMerge/File/DMFile.h +++ b/dbms/src/Storages/DeltaMerge/File/DMFile.h @@ -444,9 +444,9 @@ class DMFile : private boost::noncopyable // Meta data is small and 64KB is enough. static constexpr size_t meta_buffer_size = 64 * 1024; void finalizeMetaV2(WriteBuffer & buffer); - MetaBlockHandle writeSLPackStatToBuffer(WriteBuffer & buffer, DB::UnifiedDigestBaseBox & digest); - MetaBlockHandle writeSLPackPropertyToBuffer(WriteBuffer & buffer, DB::UnifiedDigestBaseBox & digest); - MetaBlockHandle writeColumnStatToBuffer(WriteBuffer & buffer, DB::UnifiedDigestBaseBox & digest); + MetaBlockHandle writeSLPackStatToBuffer(WriteBuffer & buffer); + MetaBlockHandle writeSLPackPropertyToBuffer(WriteBuffer & buffer); + MetaBlockHandle writeColumnStatToBuffer(WriteBuffer & buffer); std::vector readMetaV2(const FileProviderPtr & file_provider); void parseMetaV2(std::string_view buffer); void parseColumnStat(std::string_view buffer); diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_file.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_file.cpp index 83aeeabef32..9e10a84b2c9 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_file.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_file.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -34,9 +35,12 @@ #include #include #include - namespace DB { +namespace ErrorCodes +{ +extern const int CORRUPTED_DATA; +} namespace FailPoints { extern const char exception_before_dmfile_remove_encryption[]; @@ -382,6 +386,57 @@ try } CATCH +TEST_P(DMFileTest, MetaV2Broken) +try +{ + auto cols = DMTestEnv::getDefaultColumns(DMTestEnv::PkType::HiddenTiDBRowID, /*add_nullable*/ true); + + const size_t num_rows_write = 128; + + DMFileBlockOutputStream::BlockProperty block_property1; + block_property1.effective_num_rows = 1; + block_property1.gc_hint_version = 1; + block_property1.deleted_rows = 1; + DMFileBlockOutputStream::BlockProperty block_property2; + block_property2.effective_num_rows = 2; + block_property2.gc_hint_version = 2; + block_property2.deleted_rows = 2; + std::vector block_propertys; + block_propertys.push_back(block_property1); + block_propertys.push_back(block_property2); + DMFilePtr dmfile; + + Block block1 = DMTestEnv::prepareSimpleWriteBlockWithNullable(0, num_rows_write / 2); + Block block2 = DMTestEnv::prepareSimpleWriteBlockWithNullable(num_rows_write / 2, num_rows_write); + auto mode = DMFileMode::DirectoryChecksum; + auto configuration = createConfiguration(mode); + dmfile = DMFile::create(1, parent_path, std::move(configuration), DMFileFormat::V3); + auto stream = std::make_shared(dbContext(), dmfile, *cols); + stream->writePrefix(); + stream->write(block1, block_property1); + stream->write(block2, block_property2); + stream->writeSuffix(); + + { + PosixWritableFile file(dmfile->metav2Path(), false, -1, 0666); + String s = "hello"; + auto n = file.pwrite(s.data(), s.size(), 0); + ASSERT_EQ(n, s.size()); + } + + try + { + auto file_provider = dbContext().getFileProvider(); + auto t = DMFile::restore(file_provider, dmfile->fileId(), dmfile->pageId(), dmfile->parentPath(), DMFile::ReadMetaMode::all()); + FAIL(); // Should not come here. + } + catch (const DB::Exception & e) + { + ASSERT_EQ(e.code(), ErrorCodes::CORRUPTED_DATA) << e.message(); + } +} +CATCH + TEST_P(DMFileTest, GcFlag) try { From 86050b53687d2f6d4ea7e2af7944f13fb540f739 Mon Sep 17 00:00:00 2001 From: yongman Date: Thu, 16 Mar 2023 11:46:39 +0800 Subject: [PATCH 18/18] Fix sync schema after schema version key be removed (#7072) close pingcap/tiflash#7071 --- dbms/src/Common/TiFlashMetrics.h | 3 +- dbms/src/TiDB/Schema/SchemaBuilder.cpp | 36 +++++++++++ dbms/src/TiDB/Schema/SchemaBuilder.h | 2 + dbms/src/TiDB/Schema/SchemaGetter.cpp | 2 +- dbms/src/TiDB/Schema/SchemaGetter.h | 2 + dbms/src/TiDB/Schema/SchemaSyncService.cpp | 8 +++ dbms/src/TiDB/Schema/SchemaSyncService.h | 1 + dbms/src/TiDB/Schema/SchemaSyncer.h | 5 ++ dbms/src/TiDB/Schema/TiDBSchemaSyncer.h | 73 ++++++++++++++++------ 9 files changed, 110 insertions(+), 22 deletions(-) diff --git a/dbms/src/Common/TiFlashMetrics.h b/dbms/src/Common/TiFlashMetrics.h index aad1bd0abc9..60993d13100 100644 --- a/dbms/src/Common/TiFlashMetrics.h +++ b/dbms/src/Common/TiFlashMetrics.h @@ -107,7 +107,8 @@ namespace DB M(tiflash_schema_version, "Current version of tiflash cached schema", Gauge) \ M(tiflash_schema_applying, "Whether the schema is applying or not (holding lock)", Gauge) \ M(tiflash_schema_apply_count, "Total number of each kinds of apply", Counter, F(type_diff, {"type", "diff"}), \ - F(type_full, {"type", "full"}), F(type_failed, {"type", "failed"})) \ + F(type_full, {"type", "full"}), F(type_failed, {"type", "failed"}), \ + F(type_drop_keyspace, {"type", "drop_keyspace"})) \ M(tiflash_schema_trigger_count, "Total number of each kinds of schema sync trigger", Counter, /**/ \ F(type_timer, {"type", "timer"}), F(type_raft_decode, {"type", "raft_decode"}), F(type_cop_read, {"type", "cop_read"})) \ M(tiflash_schema_internal_ddl_count, "Total number of each kinds of internal ddl operations", Counter, \ diff --git a/dbms/src/TiDB/Schema/SchemaBuilder.cpp b/dbms/src/TiDB/Schema/SchemaBuilder.cpp index f3e7105cbb8..71bbd32a337 100644 --- a/dbms/src/TiDB/Schema/SchemaBuilder.cpp +++ b/dbms/src/TiDB/Schema/SchemaBuilder.cpp @@ -1379,6 +1379,42 @@ void SchemaBuilder::syncAllSchema() LOG_INFO(log, "Loaded all schemas."); } +template +void SchemaBuilder::dropAllSchema() +{ + LOG_INFO(log, "Dropping all schemas."); + + auto & tmt_context = context.getTMTContext(); + + /// Drop all tables. + auto storage_map = tmt_context.getStorages().getAllStorage(); + for (const auto & storage : storage_map) + { + auto table_info = storage.second->getTableInfo(); + if (table_info.keyspace_id != keyspace_id) + { + continue; + } + applyDropPhysicalTable(storage.second->getDatabaseName(), table_info.id); + LOG_DEBUG(log, "Table {}.{} dropped during drop all schemas", storage.second->getDatabaseName(), name_mapper.debugTableName(table_info)); + } + + /// Drop all dbs. + const auto & dbs = context.getDatabases(); + for (const auto & db : dbs) + { + auto db_keyspace_id = SchemaNameMapper::getMappedNameKeyspaceID(db.first); + if (db_keyspace_id != keyspace_id) + { + continue; + } + applyDropSchema(db.first); + LOG_DEBUG(log, "DB {} dropped during drop all schemas", db.first); + } + + LOG_INFO(log, "Dropped all schemas."); +} + // product env template struct SchemaBuilder; // mock test diff --git a/dbms/src/TiDB/Schema/SchemaBuilder.h b/dbms/src/TiDB/Schema/SchemaBuilder.h index 4e8797e9504..de217df0292 100644 --- a/dbms/src/TiDB/Schema/SchemaBuilder.h +++ b/dbms/src/TiDB/Schema/SchemaBuilder.h @@ -51,6 +51,8 @@ struct SchemaBuilder void syncAllSchema(); + void dropAllSchema(); + private: void applyDropSchema(DatabaseID schema_id); diff --git a/dbms/src/TiDB/Schema/SchemaGetter.cpp b/dbms/src/TiDB/Schema/SchemaGetter.cpp index 636da7a4180..07807a418c9 100644 --- a/dbms/src/TiDB/Schema/SchemaGetter.cpp +++ b/dbms/src/TiDB/Schema/SchemaGetter.cpp @@ -199,7 +199,7 @@ Int64 SchemaGetter::getVersion() { String ver = TxnStructure::get(snap, schemaVersionKey); if (ver.empty()) - return 0; + return SchemaVersionNotExist; return std::stoll(ver); } diff --git a/dbms/src/TiDB/Schema/SchemaGetter.h b/dbms/src/TiDB/Schema/SchemaGetter.h index 8eb4644a19a..5666bcd75cc 100644 --- a/dbms/src/TiDB/Schema/SchemaGetter.h +++ b/dbms/src/TiDB/Schema/SchemaGetter.h @@ -129,6 +129,8 @@ struct SchemaDiff struct SchemaGetter { + static constexpr Int64 SchemaVersionNotExist = -1; + KeyspaceSnapshot snap; KeyspaceID keyspace_id; diff --git a/dbms/src/TiDB/Schema/SchemaSyncService.cpp b/dbms/src/TiDB/Schema/SchemaSyncService.cpp index e35521a285f..822fa7648cc 100644 --- a/dbms/src/TiDB/Schema/SchemaSyncService.cpp +++ b/dbms/src/TiDB/Schema/SchemaSyncService.cpp @@ -126,6 +126,8 @@ void SchemaSyncService::removeKeyspaceGCTasks() LOG_INFO(ks_log, "remove sync schema task"); background_pool.removeTask(ks_handle_iter->second); ks_handle_iter = ks_handle_map.erase(ks_handle_iter); + // remove schema version for this keyspace + removeCurrentVersion(ks); } } @@ -145,6 +147,12 @@ bool SchemaSyncService::syncSchemas(KeyspaceID keyspace_id) return context.getTMTContext().getSchemaSyncer()->syncSchemas(context, keyspace_id); } + +void SchemaSyncService::removeCurrentVersion(KeyspaceID keyspace_id) +{ + context.getTMTContext().getSchemaSyncer()->removeCurrentVersion(keyspace_id); +} + template inline bool isSafeForGC(const DatabaseOrTablePtr & ptr, Timestamp gc_safe_point) { diff --git a/dbms/src/TiDB/Schema/SchemaSyncService.h b/dbms/src/TiDB/Schema/SchemaSyncService.h index 6ff5d3c7904..b0ce85140a5 100644 --- a/dbms/src/TiDB/Schema/SchemaSyncService.h +++ b/dbms/src/TiDB/Schema/SchemaSyncService.h @@ -45,6 +45,7 @@ class SchemaSyncService private: bool syncSchemas(KeyspaceID keyspace_id); + void removeCurrentVersion(KeyspaceID keyspace_id); struct GCContext { diff --git a/dbms/src/TiDB/Schema/SchemaSyncer.h b/dbms/src/TiDB/Schema/SchemaSyncer.h index 4c4d41d978a..6c0db6e4ffa 100644 --- a/dbms/src/TiDB/Schema/SchemaSyncer.h +++ b/dbms/src/TiDB/Schema/SchemaSyncer.h @@ -48,6 +48,11 @@ class SchemaSyncer */ virtual bool syncSchemas(Context & context, KeyspaceID keyspace_id) = 0; + /** + * Remove current version of CH schema. + */ + virtual void removeCurrentVersion(KeyspaceID keyspace_id) = 0; + virtual void reset() = 0; virtual TiDB::DBInfoPtr getDBInfoByName(const String & database_name) = 0; diff --git a/dbms/src/TiDB/Schema/TiDBSchemaSyncer.h b/dbms/src/TiDB/Schema/TiDBSchemaSyncer.h index f33beaa9361..5243e022668 100644 --- a/dbms/src/TiDB/Schema/TiDBSchemaSyncer.h +++ b/dbms/src/TiDB/Schema/TiDBSchemaSyncer.h @@ -102,6 +102,13 @@ struct TiDBSchemaSyncer : public SchemaSyncer return it->second; } + // After all tables have been physical dropped, remove the `cur_version` of given keyspace + void removeCurrentVersion(KeyspaceID keyspace_id) override + { + std::lock_guard lock(schema_mutex); + cur_versions.erase(keyspace_id); + } + bool syncSchemas(Context & context, KeyspaceID keyspace_id) override { std::lock_guard lock(schema_mutex); @@ -110,37 +117,57 @@ struct TiDBSchemaSyncer : public SchemaSyncer auto getter = createSchemaGetter(keyspace_id); Int64 version = getter.getVersion(); - if (version <= cur_version) - { - return false; - } + Stopwatch watch; SCOPE_EXIT({ GET_METRIC(tiflash_schema_apply_duration_seconds).Observe(watch.elapsedSeconds()); }); - LOG_INFO(ks_log, "Start to sync schemas. current version is: {} and try to sync schema version to: {}", cur_version, version); - // Show whether the schema mutex is held for a long time or not. GET_METRIC(tiflash_schema_applying).Set(1.0); SCOPE_EXIT({ GET_METRIC(tiflash_schema_applying).Set(0.0); }); - GET_METRIC(tiflash_schema_apply_count, type_diff).Increment(); - // After the feature concurrent DDL, TiDB does `update schema version` before `set schema diff`, and they are done in separate transactions. - // So TiFlash may see a schema version X but no schema diff X, meaning that the transaction of schema diff X has not been committed or has - // been aborted. - // However, TiDB makes sure that if we get a schema version X, then the schema diff X-1 must exist. Otherwise the transaction of schema diff - // X-1 is aborted and we can safely ignore it. - // Since TiDB can not make sure the schema diff of the latest schema version X is not empty, under this situation we should set the `cur_version` - // to X-1 and try to fetch the schema diff X next time. - Int64 version_after_load_diff = 0; - if (version_after_load_diff = tryLoadSchemaDiffs(getter, cur_version, version, context, ks_log); version_after_load_diff == -1) + // If the schema version not exists, drop all schemas. + if (version == SchemaGetter::SchemaVersionNotExist) { - GET_METRIC(tiflash_schema_apply_count, type_full).Increment(); - version_after_load_diff = loadAllSchema(getter, version, context); + // Tables and databases are already tombstoned and waiting for GC. + if (SchemaGetter::SchemaVersionNotExist == cur_version) + return false; + + LOG_INFO(ks_log, "Start to drop schemas. schema version key not exists, keyspace should be deleted"); + GET_METRIC(tiflash_schema_apply_count, type_drop_keyspace).Increment(); + + // The key range of the given keyspace is deleted by `UnsafeDestroyRange`, so the return result + // of `SchemaGetter::listDBs` is not reliable. Directly mark all databases and tables of this keyspace + // as a tombstone and let the SchemaSyncService drop them physically. + dropAllSchema(getter, context); + cur_versions[keyspace_id] = SchemaGetter::SchemaVersionNotExist; } - cur_versions[keyspace_id] = version_after_load_diff; + else + { + if (version <= cur_version) + return false; + + LOG_INFO(ks_log, "Start to sync schemas. current version is: {} and try to sync schema version to: {}", cur_version, version); + GET_METRIC(tiflash_schema_apply_count, type_diff).Increment(); + + // After the feature concurrent DDL, TiDB does `update schema version` before `set schema diff`, and they are done in separate transactions. + // So TiFlash may see a schema version X but no schema diff X, meaning that the transaction of schema diff X has not been committed or has + // been aborted. + // However, TiDB makes sure that if we get a schema version X, then the schema diff X-1 must exist. Otherwise the transaction of schema diff + // X-1 is aborted and we can safely ignore it. + // Since TiDB can not make sure the schema diff of the latest schema version X is not empty, under this situation we should set the `cur_version` + // to X-1 and try to fetch the schema diff X next time. + Int64 version_after_load_diff = 0; + if (version_after_load_diff = tryLoadSchemaDiffs(getter, cur_version, version, context, ks_log); version_after_load_diff == -1) + { + GET_METRIC(tiflash_schema_apply_count, type_full).Increment(); + version_after_load_diff = loadAllSchema(getter, version, context); + } + cur_versions[keyspace_id] = version_after_load_diff; + } + // TODO: (keyspace) attach keyspace id to the metrics. GET_METRIC(tiflash_schema_version).Set(cur_version); - LOG_INFO(ks_log, "End sync schema, version has been updated to {}{}", keyspace_id, cur_version, cur_version == version ? "" : "(latest diff is empty)"); + LOG_INFO(ks_log, "End sync schema, version has been updated to {}{}", cur_version, cur_version == version ? "" : "(latest diff is empty)"); return true; } @@ -278,6 +305,12 @@ struct TiDBSchemaSyncer : public SchemaSyncer builder.syncAllSchema(); return version; } + + void dropAllSchema(Getter & getter, Context & context) + { + SchemaBuilder builder(getter, context, databases, -1); + builder.dropAllSchema(); + } }; } // namespace DB