diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index 33a0ee94745..6e737559de2 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -101,6 +101,7 @@ add_headers_and_sources(dbms src/Storages/Page/V3/WAL) add_headers_and_sources(dbms src/Storages/Page/V3/spacemap) add_headers_and_sources(dbms src/Storages/Page/V3/PageDirectory) add_headers_and_sources(dbms src/Storages/Page/V3/Blob) +add_headers_and_sources(dbms src/Storages/Page/V3/Universal) add_headers_and_sources(dbms src/Storages/Page/) add_headers_and_sources(dbms src/TiDB) add_headers_and_sources(dbms src/Client) diff --git a/dbms/src/IO/ReadBufferFromString.h b/dbms/src/IO/ReadBufferFromString.h index 3d514dd0df9..f0d250b07d9 100644 --- a/dbms/src/IO/ReadBufferFromString.h +++ b/dbms/src/IO/ReadBufferFromString.h @@ -15,6 +15,7 @@ #pragma once #include +#include namespace DB @@ -31,4 +32,14 @@ class ReadBufferFromString : public ReadBufferFromMemory {} }; +class ReadBufferFromOwnString : public String + , public ReadBufferFromString +{ +public: + explicit ReadBufferFromOwnString(std::string_view s_) + : String(s_) + , ReadBufferFromString(*this) + {} +}; + } // namespace DB diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile.h b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile.h index 47f7a52d841..7ae64d3ea6c 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile.h +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include namespace DB { diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.h b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.h index c2187f96f39..e17c8763fa4 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.h +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileBig.h @@ -67,7 +67,7 @@ class ColumnFileBig : public ColumnFilePersisted auto getFile() const { return file; } - PageId getDataPageId() { return file->pageId(); } + PageIdU64 getDataPageId() { return file->pageId(); } size_t getRows() const override { return valid_rows; } size_t getBytes() const override { return valid_bytes; }; diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.cpp b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.cpp index d6b2a26897a..e5efe09680d 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.cpp +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.cpp @@ -89,7 +89,7 @@ Columns ColumnFileTiny::readFromDisk(const PageReader & page_reader, // // Read the columns from disk and apply DDL cast if need auto page_map = page_reader.read({fields}); - Page page = page_map[data_page_id]; + Page page = page_map.at(data_page_id); for (size_t index = col_start; index < col_end; ++index) { const size_t index_in_read_columns = index - col_start; @@ -160,7 +160,7 @@ ColumnFilePersistedPtr ColumnFileTiny::deserializeMetadata(const DMContext & con if (unlikely(!schema)) throw Exception("Cannot deserialize DeltaPackBlock's schema", ErrorCodes::LOGICAL_ERROR); - PageId data_page_id; + PageIdU64 data_page_id; size_t rows, bytes; readIntBinary(data_page_id, buf); @@ -213,7 +213,7 @@ ColumnFileTinyPtr ColumnFileTiny::writeColumnFile(const DMContext & context, con return std::make_shared(schema, limit, bytes, page_id, cache); } -PageId ColumnFileTiny::writeColumnFileData(const DMContext & context, const Block & block, size_t offset, size_t limit, WriteBatches & wbs) +PageIdU64 ColumnFileTiny::writeColumnFileData(const DMContext & context, const Block & block, size_t offset, size_t limit, WriteBatches & wbs) { auto page_id = context.storage_pool.newLogPageId(); diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.h b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.h index 7680139e4b3..2e2f73c5bec 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.h +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFileTiny.h @@ -40,7 +40,7 @@ class ColumnFileTiny : public ColumnFilePersisted UInt64 bytes = 0; /// The id of data page which stores the data of this pack. - PageId data_page_id; + PageIdU64 data_page_id; /// The members below are not serialized. @@ -62,7 +62,7 @@ class ColumnFileTiny : public ColumnFilePersisted } public: - ColumnFileTiny(const ColumnFileSchemaPtr & schema_, UInt64 rows_, UInt64 bytes_, PageId data_page_id_, const CachePtr & cache_ = nullptr) + ColumnFileTiny(const ColumnFileSchemaPtr & schema_, UInt64 rows_, UInt64 bytes_, PageIdU64 data_page_id_, const CachePtr & cache_ = nullptr) : schema(schema_) , rows(rows_) , bytes(bytes_) @@ -81,7 +81,7 @@ class ColumnFileTiny : public ColumnFilePersisted /// The schema of this pack. Could be empty, i.e. a DeleteRange does not have a schema. ColumnFileSchemaPtr getSchema() const { return schema; } - ColumnFileTinyPtr cloneWith(PageId new_data_page_id) + ColumnFileTinyPtr cloneWith(PageIdU64 new_data_page_id) { auto new_tiny_file = std::make_shared(*this); new_tiny_file->data_page_id = new_data_page_id; @@ -98,13 +98,13 @@ class ColumnFileTiny : public ColumnFilePersisted void serializeMetadata(WriteBuffer & buf, bool save_schema) const override; - PageId getDataPageId() const { return data_page_id; } + PageIdU64 getDataPageId() const { return data_page_id; } Block readBlockForMinorCompaction(const PageReader & page_reader) const; static ColumnFileTinyPtr writeColumnFile(const DMContext & context, const Block & block, size_t offset, size_t limit, WriteBatches & wbs, const CachePtr & cache = nullptr); - static PageId writeColumnFileData(const DMContext & context, const Block & block, size_t offset, size_t limit, WriteBatches & wbs); + static PageIdU64 writeColumnFileData(const DMContext & context, const Block & block, size_t offset, size_t limit, WriteBatches & wbs); static ColumnFilePersistedPtr deserializeMetadata(const DMContext & context, ReadBuffer & buf, ColumnFileSchemaPtr & last_schema); diff --git a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile_V2.cpp b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile_V2.cpp index 51240795c3c..e0e9e120711 100644 --- a/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile_V2.cpp +++ b/dbms/src/Storages/DeltaMerge/ColumnFile/ColumnFile_V2.cpp @@ -27,7 +27,7 @@ struct ColumnFileV2 UInt64 bytes = 0; BlockPtr schema; RowKeyRange delete_range; - PageId data_page_id = 0; + PageIdU64 data_page_id = 0; bool isDeleteRange() const { return !delete_range.none(); } }; diff --git a/dbms/src/Storages/DeltaMerge/Delta/ColumnFileFlushTask.h b/dbms/src/Storages/DeltaMerge/Delta/ColumnFileFlushTask.h index 50bf28aa19c..93239de7963 100644 --- a/dbms/src/Storages/DeltaMerge/Delta/ColumnFileFlushTask.h +++ b/dbms/src/Storages/DeltaMerge/Delta/ColumnFileFlushTask.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include namespace DB @@ -47,7 +47,7 @@ class ColumnFileFlushTask ColumnFilePtr column_file; Block block_data; - PageId data_page = 0; + PageIdU64 data_page = 0; bool sorted = false; size_t rows_offset = 0; diff --git a/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.cpp b/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.cpp index b6b34df3542..5bbd80f6d05 100644 --- a/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.cpp +++ b/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.cpp @@ -28,7 +28,7 @@ namespace DB { namespace DM { -inline void serializeColumnFilePersisteds(WriteBatches & wbs, PageId id, const ColumnFilePersisteds & persisted_files) +inline void serializeColumnFilePersisteds(WriteBatches & wbs, PageIdU64 id, const ColumnFilePersisteds & persisted_files) { MemoryWriteBuffer buf(0, COLUMN_FILE_SERIALIZE_BUFFER_SIZE); serializeSavedColumnFiles(buf, persisted_files); @@ -76,7 +76,7 @@ void ColumnFilePersistedSet::checkColumnFiles(const ColumnFilePersisteds & new_c } ColumnFilePersistedSet::ColumnFilePersistedSet( // - PageId metadata_id_, + PageIdU64 metadata_id_, const ColumnFilePersisteds & persisted_column_files) : metadata_id(metadata_id_) , persisted_files(persisted_column_files) @@ -88,7 +88,7 @@ ColumnFilePersistedSet::ColumnFilePersistedSet( // ColumnFilePersistedSetPtr ColumnFilePersistedSet::restore( // DMContext & context, const RowKeyRange & segment_range, - PageId id) + PageIdU64 id) { Page page = context.storage_pool.metaReader()->read(id); ReadBufferFromMemory buf(page.data.begin(), page.data.size()); diff --git a/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.h b/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.h index 7f191bfa0ca..844392d6d81 100644 --- a/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.h +++ b/dbms/src/Storages/DeltaMerge/Delta/ColumnFilePersistedSet.h @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include namespace DB @@ -49,7 +49,7 @@ class ColumnFilePersistedSet : public std::enable_shared_from_this persisted_files_count = 0; @@ -70,11 +70,11 @@ class ColumnFilePersistedSet : public std::enable_shared_from_this(id_, persisted_files)) , mem_table_set(std::make_shared(in_memory_files)) , delta_index(std::make_shared()) @@ -55,7 +55,7 @@ void DeltaValueSpace::abandon(DMContext & context) manager->deleteRef(delta_index); } -DeltaValueSpacePtr DeltaValueSpace::restore(DMContext & context, const RowKeyRange & segment_range, PageId id) +DeltaValueSpacePtr DeltaValueSpace::restore(DMContext & context, const RowKeyRange & segment_range, PageIdU64 id) { auto persisted_file_set = ColumnFilePersistedSet::restore(context, segment_range, id); return std::make_shared(std::move(persisted_file_set)); @@ -114,7 +114,7 @@ std::vector CloneColumnFilesHelper::clone( else if (auto * t = column_file->tryToTinyFile(); t) { // Use a newly created page_id to reference the data page_id of current column file. - PageId new_data_page_id = context.storage_pool.newLogPageId(); + PageIdU64 new_data_page_id = context.storage_pool.newLogPageId(); wbs.log.putRefPage(new_data_page_id, t->getDataPageId()); auto new_column_file = t->cloneWith(new_data_page_id); cloned.push_back(new_column_file); diff --git a/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.h b/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.h index 738144f8d78..be4a90ba7c9 100644 --- a/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.h +++ b/dbms/src/Storages/DeltaMerge/Delta/DeltaValueSpace.h @@ -31,13 +31,13 @@ #include #include #include -#include +#include namespace DB { namespace DM { -using GenPageId = std::function; +using GenPageId = std::function; class DeltaValueSpace; class DeltaValueSnapshot; @@ -100,13 +100,13 @@ class DeltaValueSpace LoggerPtr log; public: - explicit DeltaValueSpace(PageId id_, const ColumnFilePersisteds & persisted_files = {}, const ColumnFiles & in_memory_files = {}); + explicit DeltaValueSpace(PageIdU64 id_, const ColumnFilePersisteds & persisted_files = {}, const ColumnFiles & in_memory_files = {}); explicit DeltaValueSpace(ColumnFilePersistedSetPtr && persisted_file_set_); /// Restore the metadata of this instance. /// Only called after reboot. - static DeltaValueSpacePtr restore(DMContext & context, const RowKeyRange & segment_range, PageId id); + static DeltaValueSpacePtr restore(DMContext & context, const RowKeyRange & segment_range, PageIdU64 id); /** * Resets the logger by using the one from the segment. @@ -167,7 +167,7 @@ class DeltaValueSpace const RowKeyRange & target_range, WriteBatches & wbs) const; - PageId getId() const { return persisted_file_set->getId(); } + PageIdU64 getId() const { return persisted_file_set->getId(); } size_t getColumnFileCount() const { return persisted_file_set->getColumnFileCount() + mem_table_set->getColumnFileCount(); } size_t getRows(bool use_unsaved = true) const diff --git a/dbms/src/Storages/DeltaMerge/DeltaIndex.h b/dbms/src/Storages/DeltaMerge/DeltaIndex.h index 9eda0b75870..61c47d7e7a5 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaIndex.h +++ b/dbms/src/Storages/DeltaMerge/DeltaIndex.h @@ -16,7 +16,7 @@ #include #include -#include +#include namespace DB { diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp index 753184af622..74a69c2d988 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.cpp @@ -308,7 +308,7 @@ void DeltaMergeStore::dropAllSegments(bool keep_first_segment) { std::unique_lock lock(read_write_mutex); auto segment_id = DELTA_MERGE_FIRST_SEGMENT_ID; - std::stack segment_ids; + std::stack segment_ids; while (segment_id != 0) { segment_ids.push(segment_id); diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h index b0a4feb86c4..d544ab76c0e 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore.h @@ -57,7 +57,7 @@ namespace tests class DeltaMergeStoreTest; } -inline static const PageId DELTA_MERGE_FIRST_SEGMENT_ID = 1; +inline static const PageIdU64 DELTA_MERGE_FIRST_SEGMENT_ID = 1; struct SegmentStats { @@ -168,7 +168,7 @@ class DeltaMergeStore : private boost::noncopyable static Settings EMPTY_SETTINGS; using SegmentSortedMap = std::map>; - using SegmentMap = std::unordered_map; + using SegmentMap = std::unordered_map; enum ThreadType { @@ -269,9 +269,9 @@ class DeltaMergeStore : private boost::noncopyable void deleteRange(const Context & db_context, const DB::Settings & db_settings, const RowKeyRange & delete_range); - std::tuple preAllocateIngestFile(); + std::tuple preAllocateIngestFile(); - void preIngestFile(const String & parent_path, PageId file_id, size_t file_size); + void preIngestFile(const String & parent_path, PageIdU64 file_id, size_t file_size); /// You must ensure external files are ordered and do not overlap. Otherwise exceptions will be thrown. /// You must ensure all of the external files are contained by the range. Otherwise exceptions will be thrown. diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore_Ingest.cpp b/dbms/src/Storages/DeltaMerge/DeltaMergeStore_Ingest.cpp index 98b072f5b83..4c3102ca814 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore_Ingest.cpp +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore_Ingest.cpp @@ -47,8 +47,7 @@ extern const char force_ingest_via_replace[]; namespace DM { - -std::tuple DeltaMergeStore::preAllocateIngestFile() +std::tuple DeltaMergeStore::preAllocateIngestFile() { if (shutdown_called.load(std::memory_order_relaxed)) return {}; @@ -59,7 +58,7 @@ std::tuple DeltaMergeStore::preAllocateIngestFile() return {parent_path, new_id}; } -void DeltaMergeStore::preIngestFile(const String & parent_path, const PageId file_id, size_t file_size) +void DeltaMergeStore::preIngestFile(const String & parent_path, const PageIdU64 file_id, size_t file_size) { if (shutdown_called.load(std::memory_order_relaxed)) return; diff --git a/dbms/src/Storages/DeltaMerge/DeltaMergeStore_InternalBg.cpp b/dbms/src/Storages/DeltaMerge/DeltaMergeStore_InternalBg.cpp index c70acce453c..4f3f3503a63 100644 --- a/dbms/src/Storages/DeltaMerge/DeltaMergeStore_InternalBg.cpp +++ b/dbms/src/Storages/DeltaMerge/DeltaMergeStore_InternalBg.cpp @@ -77,7 +77,7 @@ class LocalDMFileGcScanner final options.only_list_can_gc = true; for (auto & root_path : delegate.listPaths()) { - std::set ids_under_path; + std::set ids_under_path; auto file_ids_in_current_path = DMFile::listAllInPath(file_provider, root_path, options); path_and_ids_vec.emplace_back(root_path, std::move(file_ids_in_current_path)); } @@ -104,7 +104,7 @@ class LocalDMFileGcRemover final , logger(std::move(log)) {} - void operator()(const ExternalPageCallbacks::PathAndIdsVec & path_and_ids_vec, const std::set & valid_ids) + void operator()(const ExternalPageCallbacks::PathAndIdsVec & path_and_ids_vec, const std::set & valid_ids) { // If the StoragePathPool is invalid or shutdown flag is set, // meaning we call `remover` after shutdowning or dropping the table, @@ -177,7 +177,7 @@ void DeltaMergeStore::setUpBackgroundTask(const DMContextPtr & dm_context) // that callbacks is called after the `DeltaMergeStore` shutdown or dropped, // we must make the callbacks safe. ExternalPageCallbacks callbacks; - callbacks.ns_id = storage_pool->getNamespaceId(); + callbacks.prefix = storage_pool->getNamespaceId(); callbacks.scanner = LocalDMFileGcScanner(std::weak_ptr(path_pool), global_context.getFileProvider()); callbacks.remover = LocalDMFileGcRemover(std::weak_ptr(path_pool), global_context.getFileProvider(), log); // remember to unregister it when shutdown diff --git a/dbms/src/Storages/DeltaMerge/ExternalDTFileInfo.h b/dbms/src/Storages/DeltaMerge/ExternalDTFileInfo.h index c0b5c463da0..6992c463787 100644 --- a/dbms/src/Storages/DeltaMerge/ExternalDTFileInfo.h +++ b/dbms/src/Storages/DeltaMerge/ExternalDTFileInfo.h @@ -15,7 +15,7 @@ #pragma once #include -#include +#include #include namespace DB::DM @@ -26,7 +26,7 @@ struct ExternalDTFileInfo /** * The allocated PageId of the file. */ - PageId id; + PageIdU64 id; /** * The handle range of contained data. diff --git a/dbms/src/Storages/DeltaMerge/SSTFilesToDTFilesOutputStream.h b/dbms/src/Storages/DeltaMerge/SSTFilesToDTFilesOutputStream.h index 18a9bab7eec..10a9a01e929 100644 --- a/dbms/src/Storages/DeltaMerge/SSTFilesToDTFilesOutputStream.h +++ b/dbms/src/Storages/DeltaMerge/SSTFilesToDTFilesOutputStream.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Storages/DeltaMerge/Segment.cpp b/dbms/src/Storages/DeltaMerge/Segment.cpp index bbeed541f47..e8e13f5be2e 100644 --- a/dbms/src/Storages/DeltaMerge/Segment.cpp +++ b/dbms/src/Storages/DeltaMerge/Segment.cpp @@ -168,13 +168,13 @@ StableValueSpacePtr createNewStable( // DMContext & context, const ColumnDefinesPtr & schema_snap, const BlockInputStreamPtr & input_stream, - PageId stable_id, + PageIdU64 stable_id, WriteBatches & wbs) { auto delegator = context.path_pool.getStableDiskDelegator(); auto store_path = delegator.choosePath(); - PageId dtfile_id = context.storage_pool.newDataPageIdForDTFile(delegator, __PRETTY_FUNCTION__); + PageIdU64 dtfile_id = context.storage_pool.newDataPageIdForDTFile(delegator, __PRETTY_FUNCTION__); auto dtfile = writeIntoNewDMFile(context, schema_snap, input_stream, dtfile_id, store_path); auto stable = std::make_shared(stable_id); @@ -194,8 +194,8 @@ Segment::Segment( // const LoggerPtr & parent_log_, UInt64 epoch_, const RowKeyRange & rowkey_range_, - PageId segment_id_, - PageId next_segment_id_, + PageIdU64 segment_id_, + PageIdU64 next_segment_id_, const DeltaValueSpacePtr & delta_, const StableValueSpacePtr & stable_) : epoch(epoch_) @@ -220,10 +220,10 @@ SegmentPtr Segment::newSegment( // DMContext & context, const ColumnDefinesPtr & schema, const RowKeyRange & range, - PageId segment_id, - PageId next_segment_id, - PageId delta_id, - PageId stable_id) + PageIdU64 segment_id, + PageIdU64 next_segment_id, + PageIdU64 delta_id, + PageIdU64 stable_id) { WriteBatches wbs(context.storage_pool, context.getWriteLimiter()); @@ -248,8 +248,8 @@ SegmentPtr Segment::newSegment( // DMContext & context, const ColumnDefinesPtr & schema, const RowKeyRange & rowkey_range, - PageId segment_id, - PageId next_segment_id) + PageIdU64 segment_id, + PageIdU64 next_segment_id) { return newSegment( parent_log, @@ -265,7 +265,7 @@ SegmentPtr Segment::newSegment( // SegmentPtr Segment::restoreSegment( // const LoggerPtr & parent_log, DMContext & context, - PageId segment_id) + PageIdU64 segment_id) { Page page = context.storage_pool.metaReader()->read(segment_id); // not limit restore @@ -275,7 +275,7 @@ SegmentPtr Segment::restoreSegment( // readIntBinary(version, buf); UInt64 epoch; RowKeyRange rowkey_range; - PageId next_segment_id, delta_id, stable_id; + PageIdU64 next_segment_id, delta_id, stable_id; readIntBinary(epoch, buf); diff --git a/dbms/src/Storages/DeltaMerge/Segment.h b/dbms/src/Storages/DeltaMerge/Segment.h index c0faefcf817..f728266308b 100644 --- a/dbms/src/Storages/DeltaMerge/Segment.h +++ b/dbms/src/Storages/DeltaMerge/Segment.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include namespace DB::DM @@ -119,8 +119,8 @@ class Segment const LoggerPtr & parent_log_, UInt64 epoch_, const RowKeyRange & rowkey_range_, - PageId segment_id_, - PageId next_segment_id_, + PageIdU64 segment_id_, + PageIdU64 next_segment_id_, const DeltaValueSpacePtr & delta_, const StableValueSpacePtr & stable_); @@ -129,19 +129,19 @@ class Segment DMContext & context, const ColumnDefinesPtr & schema, const RowKeyRange & rowkey_range, - PageId segment_id, - PageId next_segment_id, - PageId delta_id, - PageId stable_id); + PageIdU64 segment_id, + PageIdU64 next_segment_id, + PageIdU64 delta_id, + PageIdU64 stable_id); static SegmentPtr newSegment( const LoggerPtr & parent_log, DMContext & context, const ColumnDefinesPtr & schema, const RowKeyRange & rowkey_range, - PageId segment_id, - PageId next_segment_id); + PageIdU64 segment_id, + PageIdU64 next_segment_id); - static SegmentPtr restoreSegment(const LoggerPtr & parent_log, DMContext & context, PageId segment_id); + static SegmentPtr restoreSegment(const LoggerPtr & parent_log, DMContext & context, PageIdU64 segment_id); void serialize(WriteBatch & wb); @@ -468,8 +468,8 @@ class Segment size_t getEstimatedRows() const { return delta->getRows() + stable->getRows(); } size_t getEstimatedBytes() const { return delta->getBytes() + stable->getBytes(); } - PageId segmentId() const { return segment_id; } - PageId nextSegmentId() const { return next_segment_id; } + PageIdU64 segmentId() const { return segment_id; } + PageIdU64 nextSegmentId() const { return next_segment_id; } UInt64 segmentEpoch() const { return epoch; }; void check(DMContext & dm_context, const String & when) const; @@ -644,8 +644,8 @@ class Segment RowKeyRange rowkey_range; bool is_common_handle; size_t rowkey_column_size; - const PageId segment_id; - const PageId next_segment_id; + const PageIdU64 segment_id; + const PageIdU64 next_segment_id; std::atomic last_check_gc_safe_point = 0; diff --git a/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp b/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp index f11fe77692a..06d5676d7b5 100644 --- a/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp +++ b/dbms/src/Storages/DeltaMerge/StableValueSpace.cpp @@ -87,7 +87,7 @@ void StableValueSpace::saveMeta(WriteBatch & meta_wb) meta_wb.putPage(id, 0, buf.tryGetReadBuffer(), data_size); } -StableValueSpacePtr StableValueSpace::restore(DMContext & context, PageId id) +StableValueSpacePtr StableValueSpace::restore(DMContext & context, PageIdU64 id) { auto stable = std::make_shared(id); diff --git a/dbms/src/Storages/DeltaMerge/StableValueSpace.h b/dbms/src/Storages/DeltaMerge/StableValueSpace.h index 8ed6120ac89..a74d0860949 100644 --- a/dbms/src/Storages/DeltaMerge/StableValueSpace.h +++ b/dbms/src/Storages/DeltaMerge/StableValueSpace.h @@ -39,12 +39,12 @@ using StableValueSpacePtr = std::shared_ptr; class StableValueSpace : public std::enable_shared_from_this { public: - StableValueSpace(PageId id_) + StableValueSpace(PageIdU64 id_) : id(id_) , log(Logger::get()) {} - static StableValueSpacePtr restore(DMContext & context, PageId id); + static StableValueSpacePtr restore(DMContext & context, PageIdU64 id); /** * Resets the logger by using the one from the segment. @@ -61,7 +61,7 @@ class StableValueSpace : public std::enable_shared_from_this // bytes and rows. void setFiles(const DMFiles & files_, const RowKeyRange & range, DMContext * dm_context = nullptr); - PageId getId() const { return id; } + PageIdU64 getId() const { return id; } void saveMeta(WriteBatch & meta_wb); size_t getRows() const; @@ -141,7 +141,7 @@ class StableValueSpace : public std::enable_shared_from_this { StableValueSpacePtr stable; - PageId id; + PageIdU64 id; UInt64 valid_rows; UInt64 valid_bytes; @@ -172,7 +172,7 @@ class StableValueSpace : public std::enable_shared_from_this return c; } - PageId getId() const { return id; } + PageIdU64 getId() const { return id; } size_t getRows() const { return valid_rows; } size_t getBytes() const { return valid_bytes; } @@ -244,7 +244,7 @@ class StableValueSpace : public std::enable_shared_from_this void drop(const FileProviderPtr & file_provider); private: - const PageId id; + const PageIdU64 id; // Valid rows is not always the sum of rows in file, // because after logical split, two segments could reference to a same file. diff --git a/dbms/src/Storages/DeltaMerge/StoragePool.cpp b/dbms/src/Storages/DeltaMerge/StoragePool.cpp index 123f143ec0a..02281a29152 100644 --- a/dbms/src/Storages/DeltaMerge/StoragePool.cpp +++ b/dbms/src/Storages/DeltaMerge/StoragePool.cpp @@ -378,7 +378,7 @@ void StoragePool::forceTransformDataV2toV3() WriteBatch write_batch_transform{ns_id}; WriteBatch write_batch_del_v2{ns_id}; - std::set created_dt_file_id; + PageIdU64Set created_dt_file_id; for (const auto page_id : all_page_ids) { // resolve the page_id into dtfile id @@ -663,12 +663,12 @@ void StoragePool::drop() } } -PageId StoragePool::newDataPageIdForDTFile(StableDiskDelegator & delegator, const char * who) +PageIdU64 StoragePool::newDataPageIdForDTFile(StableDiskDelegator & delegator, const char * who) { // In case that there is a DTFile created on disk but TiFlash crashes without persisting the ID. // After TiFlash process restored, the ID will be inserted into the stable delegator, but we may // get a duplicated ID from the `storage_pool.data`. (tics#2756) - PageId dtfile_id; + PageIdU64 dtfile_id; do { dtfile_id = ++max_data_page_id; diff --git a/dbms/src/Storages/DeltaMerge/StoragePool.h b/dbms/src/Storages/DeltaMerge/StoragePool.h index c49380b62e7..c6cf7f537a2 100644 --- a/dbms/src/Storages/DeltaMerge/StoragePool.h +++ b/dbms/src/Storages/DeltaMerge/StoragePool.h @@ -162,9 +162,9 @@ class StoragePool : private boost::noncopyable // StoragePool will assign the max_log_page_id/max_meta_page_id/max_data_page_id by the global max id // regardless of ns_id while being restored. This causes the ids in a table to not be continuously incremented. - PageId newDataPageIdForDTFile(StableDiskDelegator & delegator, const char * who); - PageId newLogPageId() { return ++max_log_page_id; } - PageId newMetaPageId() { return ++max_meta_page_id; } + PageIdU64 newDataPageIdForDTFile(StableDiskDelegator & delegator, const char * who); + PageIdU64 newLogPageId() { return ++max_log_page_id; } + PageIdU64 newMetaPageId() { return ++max_meta_page_id; } #ifndef DBMS_PUBLIC_GTEST private: @@ -208,9 +208,9 @@ class StoragePool : private boost::noncopyable Context & global_context; - std::atomic max_log_page_id = 0; - std::atomic max_data_page_id = 0; - std::atomic max_meta_page_id = 0; + std::atomic max_log_page_id = 0; + std::atomic max_data_page_id = 0; + std::atomic max_meta_page_id = 0; BackgroundProcessingPool::TaskHandle gc_handle = nullptr; diff --git a/dbms/src/Storages/DeltaMerge/WriteBatches.h b/dbms/src/Storages/DeltaMerge/WriteBatches.h index b5d2b00d728..bfdc4b1b08d 100644 --- a/dbms/src/Storages/DeltaMerge/WriteBatches.h +++ b/dbms/src/Storages/DeltaMerge/WriteBatches.h @@ -29,8 +29,8 @@ struct WriteBatches : private boost::noncopyable WriteBatch data; WriteBatch meta; - PageIds written_log; - PageIds written_data; + PageIdU64s written_log; + PageIdU64s written_data; WriteBatch removed_log; WriteBatch removed_data; @@ -86,7 +86,7 @@ struct WriteBatches : private boost::noncopyable void writeLogAndData() { - PageIds log_write_pages, data_write_pages; + PageIdU64s log_write_pages, data_write_pages; if constexpr (DM_RUN_CHECK) { diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_value_space.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_value_space.cpp index ddaa1b9c103..4dea75db2ea 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_value_space.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_delta_value_space.cpp @@ -124,7 +124,7 @@ class DeltaValueSpaceTest : public DB::base::TiFlashStorageTestBasic DeltaValueSpacePtr delta; static constexpr TableID table_id = 100; - static constexpr PageId delta_id = 1; + static constexpr PageIdU64 delta_id = 1; static constexpr size_t num_rows_write_per_batch = 100; }; diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_segment.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_segment.cpp index cf71819ce00..2973112bc4d 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_dm_segment.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_dm_segment.cpp @@ -1037,7 +1037,7 @@ class SegmentTest2 : public SegmentTest SegmentTest::SetUp(); } - std::pair genDMFile(DMContext & context, const Block & block) + std::pair genDMFile(DMContext & context, const Block & block) { auto delegator = context.path_pool.getStableDiskDelegator(); auto file_id = context.storage_pool.newDataPageIdForDTFile(delegator, __PRETTY_FUNCTION__); diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_segment.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_segment.cpp index fb80ec58dd5..147fa71aaf5 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_segment.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_segment.cpp @@ -243,7 +243,7 @@ try // Start a segment merge and suspend it before applyMerge auto sp_seg_split_apply = SyncPointCtl::enableInScope("before_Segment::applySplit"); - PageId new_seg_id; + PageIdU64 new_seg_id; auto th_seg_split = std::async([&]() { auto new_seg_id_opt = splitSegment(DELTA_MERGE_FIRST_SEGMENT_ID, Segment::SplitMode::Auto, /* check_rows */ false); ASSERT_TRUE(new_seg_id_opt.has_value()); diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_read_task_pool.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_read_task_pool.cpp index 397796198db..f8615bbeabf 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_read_task_pool.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_read_task_pool.cpp @@ -17,28 +17,27 @@ namespace DB::DM::tests { - -SegmentPtr createSegment(PageId seg_id) +SegmentPtr createSegment(PageIdU64 seg_id) { return std::make_shared(Logger::get(), 0, RowKeyRange{}, seg_id, seg_id + 1, nullptr, nullptr); } -SegmentReadTaskPtr createSegmentReadTask(PageId seg_id) +SegmentReadTaskPtr createSegmentReadTask(PageIdU64 seg_id) { return std::make_shared(createSegment(seg_id), nullptr, RowKeyRanges{}); } -SegmentReadTasks createSegmentReadTasks(const std::vector & seg_ids) +SegmentReadTasks createSegmentReadTasks(const std::vector & seg_ids) { SegmentReadTasks tasks; - for (PageId seg_id : seg_ids) + for (PageIdU64 seg_id : seg_ids) { tasks.push_back(createSegmentReadTask(seg_id)); } return tasks; } -static const std::vector test_seg_ids{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const std::vector test_seg_ids{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; TEST(SegmentReadTasksWrapperTest, Unordered) { @@ -61,9 +60,9 @@ TEST(SegmentReadTasksWrapperTest, Unordered) std::random_device rd; std::mt19937 g(rd()); - std::vector v = test_seg_ids; + std::vector v = test_seg_ids; std::shuffle(v.begin(), v.end(), g); - for (PageId seg_id : v) + for (PageIdU64 seg_id : v) { auto task = tasks_wrapper.getTask(seg_id); ASSERT_EQ(task->segment->segmentId(), seg_id); @@ -90,7 +89,7 @@ TEST(SegmentReadTasksWrapperTest, Ordered) ASSERT_FALSE(tasks_wrapper.empty()); - for (PageId seg_id : test_seg_ids) + for (PageIdU64 seg_id : test_seg_ids) { auto task = tasks_wrapper.nextTask(); ASSERT_EQ(task->segment->segmentId(), seg_id); diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_replace_data.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_replace_data.cpp index f54350d94a1..332ae156372 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_replace_data.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_replace_data.cpp @@ -84,7 +84,7 @@ try storage_pool->data_storage_v3->gc(/* not_skip */ true); ASSERT_EQ(storage_pool->log_storage_v3->getNumberOfPages(), 0); ASSERT_EQ(storage_pool->data_storage_v3->getNumberOfPages(), 1); // 1 DMFile - PageId replaced_stable_id{}; + PageIdU64 replaced_stable_id{}; { auto stable_page_ids = storage_pool->data_storage_v3->getAliveExternalPageIds(NAMESPACE_ID); ASSERT_EQ(1, stable_page_ids.size()); diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic.cpp index 064ed0c4387..88bd3923aac 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic.cpp @@ -64,7 +64,7 @@ void SegmentTestBasic::reloadWithOptions(SegmentTestOptions config) segments[DELTA_MERGE_FIRST_SEGMENT_ID] = root_segment; } -size_t SegmentTestBasic::getSegmentRowNumWithoutMVCC(PageId segment_id) +size_t SegmentTestBasic::getSegmentRowNumWithoutMVCC(PageIdU64 segment_id) { RUNTIME_CHECK(segments.find(segment_id) != segments.end()); auto segment = segments[segment_id]; @@ -72,7 +72,7 @@ size_t SegmentTestBasic::getSegmentRowNumWithoutMVCC(PageId segment_id) return getInputStreamNRows(in); } -size_t SegmentTestBasic::getSegmentRowNum(PageId segment_id) +size_t SegmentTestBasic::getSegmentRowNum(PageIdU64 segment_id) { RUNTIME_CHECK(segments.find(segment_id) != segments.end()); auto segment = segments[segment_id]; @@ -80,7 +80,7 @@ size_t SegmentTestBasic::getSegmentRowNum(PageId segment_id) return getInputStreamNRows(in); } -bool SegmentTestBasic::isSegmentDefinitelyEmpty(PageId segment_id) +bool SegmentTestBasic::isSegmentDefinitelyEmpty(PageIdU64 segment_id) { RUNTIME_CHECK(segments.find(segment_id) != segments.end()); auto segment = segments[segment_id]; @@ -89,7 +89,7 @@ bool SegmentTestBasic::isSegmentDefinitelyEmpty(PageId segment_id) return segment->isDefinitelyEmpty(*dm_context, snapshot); } -std::optional SegmentTestBasic::splitSegment(PageId segment_id, Segment::SplitMode split_mode, bool check_rows) +std::optional SegmentTestBasic::splitSegment(PageIdU64 segment_id, Segment::SplitMode split_mode, bool check_rows) { LOG_INFO(logger_op, "splitSegment, segment_id={} split_mode={}", segment_id, magic_enum::enum_name(split_mode)); @@ -123,7 +123,7 @@ std::optional SegmentTestBasic::splitSegment(PageId segment_id, Segment: return right->segmentId(); } -std::optional SegmentTestBasic::splitSegmentAt(PageId segment_id, Int64 split_at, Segment::SplitMode split_mode, bool check_rows) +std::optional SegmentTestBasic::splitSegmentAt(PageIdU64 segment_id, Int64 split_at, Segment::SplitMode split_mode, bool check_rows) { LOG_INFO(logger_op, "splitSegmentAt, segment_id={} split_at={} split_mode={}", segment_id, split_at, magic_enum::enum_name(split_mode)); @@ -170,7 +170,7 @@ std::optional SegmentTestBasic::splitSegmentAt(PageId segment_id, Int64 return right->segmentId(); } -void SegmentTestBasic::mergeSegment(const std::vector & segments_id, bool check_rows) +void SegmentTestBasic::mergeSegment(const PageIdU64s & segments_id, bool check_rows) { LOG_INFO(logger_op, "mergeSegment, segments=[{}]", fmt::join(segments_id, ",")); @@ -215,7 +215,7 @@ void SegmentTestBasic::mergeSegment(const std::vector & segments_id, boo operation_statistics["mergeTwo"]++; } -void SegmentTestBasic::mergeSegmentDelta(PageId segment_id, bool check_rows) +void SegmentTestBasic::mergeSegmentDelta(PageIdU64 segment_id, bool check_rows) { LOG_INFO(logger_op, "mergeSegmentDelta, segment_id={}", segment_id); @@ -231,7 +231,7 @@ void SegmentTestBasic::mergeSegmentDelta(PageId segment_id, bool check_rows) operation_statistics["mergeDelta"]++; } -void SegmentTestBasic::flushSegmentCache(PageId segment_id) +void SegmentTestBasic::flushSegmentCache(PageIdU64 segment_id) { LOG_INFO(logger_op, "flushSegmentCache, segment_id={}", segment_id); @@ -243,7 +243,7 @@ void SegmentTestBasic::flushSegmentCache(PageId segment_id) operation_statistics["flush"]++; } -std::pair SegmentTestBasic::getSegmentKeyRange(PageId segment_id) const +std::pair SegmentTestBasic::getSegmentKeyRange(PageIdU64 segment_id) const { RUNTIME_CHECK(segments.find(segment_id) != segments.end()); const auto & segment = segments.find(segment_id)->second; @@ -312,7 +312,7 @@ Block sortMergeBlocks(std::vector && blocks) return accumulated_block; } -Block SegmentTestBasic::prepareWriteBlockInSegmentRange(PageId segment_id, UInt64 total_write_rows, std::optional write_start_key, bool is_deleted) +Block SegmentTestBasic::prepareWriteBlockInSegmentRange(PageIdU64 segment_id, UInt64 total_write_rows, std::optional write_start_key, bool is_deleted) { RUNTIME_CHECK(total_write_rows < std::numeric_limits::max()); @@ -378,7 +378,7 @@ Block SegmentTestBasic::prepareWriteBlockInSegmentRange(PageId segment_id, UInt6 return sortMergeBlocks(std::move(blocks)); } -void SegmentTestBasic::writeSegment(PageId segment_id, UInt64 write_rows, std::optional start_at) +void SegmentTestBasic::writeSegment(PageIdU64 segment_id, UInt64 write_rows, std::optional start_at) { LOG_INFO(logger_op, "writeSegment, segment_id={} write_rows={}", segment_id, write_rows); @@ -398,7 +398,7 @@ void SegmentTestBasic::writeSegment(PageId segment_id, UInt64 write_rows, std::o operation_statistics["write"]++; } -void SegmentTestBasic::ingestDTFileIntoDelta(PageId segment_id, UInt64 write_rows, std::optional start_at, bool clear) +void SegmentTestBasic::ingestDTFileIntoDelta(PageIdU64 segment_id, UInt64 write_rows, std::optional start_at, bool clear) { LOG_INFO(logger_op, "ingestDTFileIntoDelta, segment_id={} write_rows={}", segment_id, write_rows); @@ -439,7 +439,7 @@ void SegmentTestBasic::ingestDTFileIntoDelta(PageId segment_id, UInt64 write_row operation_statistics["ingest"]++; } -void SegmentTestBasic::ingestDTFileByReplace(PageId segment_id, UInt64 write_rows, std::optional start_at, bool clear) +void SegmentTestBasic::ingestDTFileByReplace(PageIdU64 segment_id, UInt64 write_rows, std::optional start_at, bool clear) { LOG_INFO(logger_op, "ingestDTFileByReplace, segment_id={} write_rows={}", segment_id, write_rows); @@ -497,7 +497,7 @@ void SegmentTestBasic::ingestDTFileByReplace(PageId segment_id, UInt64 write_row EXPECT_EQ(getSegmentRowNumWithoutMVCC(segment_id), segment_row_num + write_rows); } -void SegmentTestBasic::writeSegmentWithDeletedPack(PageId segment_id, UInt64 write_rows, std::optional start_at) +void SegmentTestBasic::writeSegmentWithDeletedPack(PageIdU64 segment_id, UInt64 write_rows, std::optional start_at) { LOG_INFO(logger_op, "writeSegmentWithDeletedPack, segment_id={} write_rows={}", segment_id, write_rows); @@ -517,7 +517,7 @@ void SegmentTestBasic::writeSegmentWithDeletedPack(PageId segment_id, UInt64 wri operation_statistics["writeDelete"]++; } -void SegmentTestBasic::deleteRangeSegment(PageId segment_id) +void SegmentTestBasic::deleteRangeSegment(PageIdU64 segment_id) { LOG_INFO(logger_op, "deleteRangeSegment, segment_id={}", segment_id); @@ -527,7 +527,7 @@ void SegmentTestBasic::deleteRangeSegment(PageId segment_id) EXPECT_EQ(getSegmentRowNum(segment_id), 0); } -void SegmentTestBasic::replaceSegmentData(PageId segment_id, const Block & block, SegmentSnapshotPtr snapshot) +void SegmentTestBasic::replaceSegmentData(PageIdU64 segment_id, const Block & block, SegmentSnapshotPtr snapshot) { // This function always create a new DTFile for the block. @@ -553,7 +553,7 @@ void SegmentTestBasic::replaceSegmentData(PageId segment_id, const Block & block dm_file->enableGC(); } -void SegmentTestBasic::replaceSegmentData(PageId segment_id, const DMFilePtr & file, SegmentSnapshotPtr snapshot) +void SegmentTestBasic::replaceSegmentData(PageIdU64 segment_id, const DMFilePtr & file, SegmentSnapshotPtr snapshot) { LOG_INFO(logger_op, "replaceSegmentData, segment_id={} file_rows={} file=dmf_{}", segment_id, file->getRows(), file->fileId()); @@ -572,7 +572,7 @@ void SegmentTestBasic::replaceSegmentData(PageId segment_id, const DMFilePtr & f operation_statistics["replaceData"]++; } -bool SegmentTestBasic::areSegmentsSharingStable(const std::vector & segments_id) const +bool SegmentTestBasic::areSegmentsSharingStable(const std::vector & segments_id) const { RUNTIME_CHECK(segments_id.size() >= 2); for (auto segment_id : segments_id) @@ -587,7 +587,7 @@ bool SegmentTestBasic::areSegmentsSharingStable(const std::vector & segm return true; } -PageId SegmentTestBasic::getRandomSegmentId() // Complexity is O(n) +PageIdU64 SegmentTestBasic::getRandomSegmentId() // Complexity is O(n) { RUNTIME_CHECK(!segments.empty()); auto dist = std::uniform_int_distribution{0, segments.size() - 1}; diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic.h b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic.h index b6fcb709036..67a7754137f 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic.h +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic.h @@ -52,50 +52,50 @@ class SegmentTestBasic : public DB::base::TiFlashStorageTestBasic * When `check_rows` is true, it will compare the rows num before and after the segment update. * So if there is some write during the segment update, it will report false failure if `check_rows` is true. */ - std::optional splitSegment(PageId segment_id, Segment::SplitMode split_mode = Segment::SplitMode::Auto, bool check_rows = true); - std::optional splitSegmentAt(PageId segment_id, Int64 split_at, Segment::SplitMode split_mode = Segment::SplitMode::Auto, bool check_rows = true); - void mergeSegment(const std::vector & segments, bool check_rows = true); - void mergeSegmentDelta(PageId segment_id, bool check_rows = true); - void flushSegmentCache(PageId segment_id); + std::optional splitSegment(PageIdU64 segment_id, Segment::SplitMode split_mode = Segment::SplitMode::Auto, bool check_rows = true); + std::optional splitSegmentAt(PageIdU64 segment_id, Int64 split_at, Segment::SplitMode split_mode = Segment::SplitMode::Auto, bool check_rows = true); + void mergeSegment(const std::vector & segments, bool check_rows = true); + void mergeSegmentDelta(PageIdU64 segment_id, bool check_rows = true); + void flushSegmentCache(PageIdU64 segment_id); /** * When begin_key is specified, new rows will be written from specified key. Otherwise, new rows may be * written randomly in the segment range. */ - void writeSegment(PageId segment_id, UInt64 write_rows = 100, std::optional start_at = std::nullopt); - void ingestDTFileIntoDelta(PageId segment_id, UInt64 write_rows = 100, std::optional start_at = std::nullopt, bool clear = false); - void ingestDTFileByReplace(PageId segment_id, UInt64 write_rows = 100, std::optional start_at = std::nullopt, bool clear = false); - void writeSegmentWithDeletedPack(PageId segment_id, UInt64 write_rows = 100, std::optional start_at = std::nullopt); - void deleteRangeSegment(PageId segment_id); + void writeSegment(PageIdU64 segment_id, UInt64 write_rows = 100, std::optional start_at = std::nullopt); + void ingestDTFileIntoDelta(PageIdU64 segment_id, UInt64 write_rows = 100, std::optional start_at = std::nullopt, bool clear = false); + void ingestDTFileByReplace(PageIdU64 segment_id, UInt64 write_rows = 100, std::optional start_at = std::nullopt, bool clear = false); + void writeSegmentWithDeletedPack(PageIdU64 segment_id, UInt64 write_rows = 100, std::optional start_at = std::nullopt); + void deleteRangeSegment(PageIdU64 segment_id); /** * This function does not check rows. */ - void replaceSegmentData(PageId segment_id, const DMFilePtr & file, SegmentSnapshotPtr snapshot = nullptr); - void replaceSegmentData(PageId segment_id, const Block & block, SegmentSnapshotPtr snapshot = nullptr); + void replaceSegmentData(PageIdU64 segment_id, const DMFilePtr & file, SegmentSnapshotPtr snapshot = nullptr); + void replaceSegmentData(PageIdU64 segment_id, const Block & block, SegmentSnapshotPtr snapshot = nullptr); Block prepareWriteBlock(Int64 start_key, Int64 end_key, bool is_deleted = false); - Block prepareWriteBlockInSegmentRange(PageId segment_id, UInt64 total_write_rows, std::optional write_start_key = std::nullopt, bool is_deleted = false); + Block prepareWriteBlockInSegmentRange(PageIdU64 segment_id, UInt64 total_write_rows, std::optional write_start_key = std::nullopt, bool is_deleted = false); - size_t getSegmentRowNumWithoutMVCC(PageId segment_id); - size_t getSegmentRowNum(PageId segment_id); - bool isSegmentDefinitelyEmpty(PageId segment_id); + size_t getSegmentRowNumWithoutMVCC(PageIdU64 segment_id); + size_t getSegmentRowNum(PageIdU64 segment_id); + bool isSegmentDefinitelyEmpty(PageIdU64 segment_id); - PageId getRandomSegmentId(); + PageIdU64 getRandomSegmentId(); /** * You must pass at least 2 segments. Checks whether all segments passed in are sharing the same stable. */ - [[nodiscard]] bool areSegmentsSharingStable(const std::vector & segments_id) const; + [[nodiscard]] bool areSegmentsSharingStable(const PageIdU64s & segments_id) const; - std::pair getSegmentKeyRange(PageId segment_id) const; + std::pair getSegmentKeyRange(PageIdU64 segment_id) const; void printFinishedOperations() const; - std::vector readSegment(PageId segment_id, bool need_row_id, const RowKeyRanges & ranges); - ColumnPtr getSegmentRowId(PageId segment_id, const RowKeyRanges & ranges); - ColumnPtr getSegmentHandle(PageId segment_id, const RowKeyRanges & ranges); - void writeSegmentWithDeleteRange(PageId segment_id, Int64 begin, Int64 end); + std::vector readSegment(PageIdU64 segment_id, bool need_row_id, const RowKeyRanges & ranges); + ColumnPtr getSegmentRowId(PageIdU64 segment_id, const RowKeyRanges & ranges); + ColumnPtr getSegmentHandle(PageIdU64 segment_id, const RowKeyRanges & ranges); + void writeSegmentWithDeleteRange(PageIdU64 segment_id, Int64 begin, Int64 end); RowKeyValue buildRowKeyValue(Int64 key); RowKeyRange buildRowKeyRange(Int64 begin, Int64 end); @@ -103,7 +103,7 @@ class SegmentTestBasic : public DB::base::TiFlashStorageTestBasic std::mt19937 random; // - std::map segments; + std::map segments; // std::map operation_statistics; @@ -121,10 +121,10 @@ class SegmentTestBasic : public DB::base::TiFlashStorageTestBasic */ void reloadDMContext(); - std::pair getSegmentForRead(PageId segment_id); + std::pair getSegmentForRead(PageIdU64 segment_id); protected: - inline static constexpr PageId NAMESPACE_ID = 100; + inline static constexpr PageIdU64 NAMESPACE_ID = 100; /// all these var lives as ref in dm_context std::unique_ptr storage_path_pool; diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic_bitmap.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic_bitmap.cpp index 4a9d36ec323..fa73745e8db 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic_bitmap.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_basic_bitmap.cpp @@ -58,7 +58,7 @@ RowKeyRange SegmentTestBasic::buildRowKeyRange(Int64 begin, Int64 end) return RowKeyRange::fromHandleRange(range); } -std::pair SegmentTestBasic::getSegmentForRead(PageId segment_id) +std::pair SegmentTestBasic::getSegmentForRead(PageIdU64 segment_id) { RUNTIME_CHECK(segments.find(segment_id) != segments.end()); auto segment = segments[segment_id]; @@ -69,7 +69,7 @@ std::pair SegmentTestBasic::getSegmentForRead(Pa RUNTIME_CHECK(snapshot != nullptr); return {segment, snapshot}; } -std::vector SegmentTestBasic::readSegment(PageId segment_id, bool need_row_id, const RowKeyRanges & ranges) +std::vector SegmentTestBasic::readSegment(PageIdU64 segment_id, bool need_row_id, const RowKeyRanges & ranges) { auto [segment, snapshot] = getSegmentForRead(segment_id); ColumnDefines columns_to_read = {getExtraHandleColumnDefine(options.is_common_handle), @@ -91,7 +91,7 @@ std::vector SegmentTestBasic::readSegment(PageId segment_id, bool need_ro return blks; } -ColumnPtr SegmentTestBasic::getSegmentRowId(PageId segment_id, const RowKeyRanges & ranges) +ColumnPtr SegmentTestBasic::getSegmentRowId(PageIdU64 segment_id, const RowKeyRanges & ranges) { LOG_INFO(logger_op, "getSegmentRowId, segment_id={}", segment_id); auto blks = readSegment(segment_id, true, ranges); @@ -108,7 +108,7 @@ ColumnPtr SegmentTestBasic::getSegmentRowId(PageId segment_id, const RowKeyRange } } -ColumnPtr SegmentTestBasic::getSegmentHandle(PageId segment_id, const RowKeyRanges & ranges) +ColumnPtr SegmentTestBasic::getSegmentHandle(PageIdU64 segment_id, const RowKeyRanges & ranges) { LOG_INFO(logger_op, "getSegmentHandle, segment_id={}", segment_id); auto blks = readSegment(segment_id, false, ranges); @@ -125,7 +125,7 @@ ColumnPtr SegmentTestBasic::getSegmentHandle(PageId segment_id, const RowKeyRang } } -void SegmentTestBasic::writeSegmentWithDeleteRange(PageId segment_id, Int64 begin, Int64 end) +void SegmentTestBasic::writeSegmentWithDeleteRange(PageIdU64 segment_id, Int64 begin, Int64 end) { auto range = buildRowKeyRange(begin, end); RUNTIME_CHECK(segments.find(segment_id) != segments.end()); diff --git a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_randomized.cpp b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_randomized.cpp index 6ac5c476410..66397ad2c1e 100644 --- a/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_randomized.cpp +++ b/dbms/src/Storages/DeltaMerge/tests/gtest_segment_test_randomized.cpp @@ -92,18 +92,18 @@ class SegmentRandomizedTest : public SegmentTestBasic {0.25, &SegmentRandomizedTest::prepareReplaceDataSnapshot}}; SegmentSnapshotPtr for_update_snapshot; - std::optional for_update_snapshot_segment_id; + std::optional for_update_snapshot_segment_id; std::optional for_update_snapshot_rows; /** * (-∞, rand_min). Hack: This segment is intentionally removed from the "segments" map to avoid being picked up. */ - PageId outbound_left_seg{}; + PageIdU64 outbound_left_seg{}; /** * [rand_max, +∞). Hack: This segment is intentionally removed from the "segments" map to avoid being picked up. */ - PageId outbound_right_seg{}; + PageIdU64 outbound_right_seg{}; void clearReplaceDataSnapshot() { @@ -227,7 +227,7 @@ class SegmentRandomizedTest : public SegmentTestBasic if (segments.empty()) return; clearReplaceDataSnapshot(); - PageId random_segment_id = getRandomSegmentId(); + PageIdU64 random_segment_id = getRandomSegmentId(); LOG_DEBUG(logger, "start random merge delta, segment_id={} all_segments={}", random_segment_id, segments.size()); mergeSegmentDelta(random_segment_id); } @@ -236,7 +236,7 @@ class SegmentRandomizedTest : public SegmentTestBasic { if (segments.empty()) return; - PageId random_segment_id = getRandomSegmentId(); + PageIdU64 random_segment_id = getRandomSegmentId(); LOG_DEBUG(logger, "start random flush cache, segment_id={} all_segments={}", random_segment_id, segments.size()); flushSegmentCache(random_segment_id); } @@ -304,14 +304,14 @@ class SegmentRandomizedTest : public SegmentTestBasic } } - std::vector getRandomMergeableSegments() + std::vector getRandomMergeableSegments() { RUNTIME_CHECK(segments.size() >= 2, segments.size()); // Merge 2~6 segments (at most 1/2 of all segments). auto max_merge_segments = std::uniform_int_distribution{2, std::clamp(static_cast(segments.size()) / 2, 2, 6)}(random); - std::vector segments_id; + std::vector segments_id; segments_id.reserve(max_merge_segments); while (true) diff --git a/dbms/src/Storages/Page/Config.h b/dbms/src/Storages/Page/Config.h index 04589baabf1..a9a6968e17a 100644 --- a/dbms/src/Storages/Page/Config.h +++ b/dbms/src/Storages/Page/Config.h @@ -16,7 +16,7 @@ #include #include -#include +#include namespace DB { @@ -85,6 +85,14 @@ struct PageStorageConfig MVCC::VersionSetConfig version_set_config; + // Use a more easy gc config for v2 when all of its data will be transformed to v3. + static PageStorageConfig getEasyGCConfig() + { + PageStorageConfig gc_config; + gc_config.file_roll_size = PAGE_FILE_SMALL_SIZE; + return gc_config; + } + //========================================================================================== // V3 config //========================================================================================== diff --git a/dbms/src/Storages/Page/ExternalPageCallbacks.cpp b/dbms/src/Storages/Page/ExternalPageCallbacks.cpp new file mode 100644 index 00000000000..77f6da8f1e6 --- /dev/null +++ b/dbms/src/Storages/Page/ExternalPageCallbacks.cpp @@ -0,0 +1,21 @@ +// 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 + +namespace DB +{ +template struct ExternalPageCallbacksT; +template struct ExternalPageCallbacksT; +} // namespace DB diff --git a/dbms/src/Storages/Page/ExternalPageCallbacks.h b/dbms/src/Storages/Page/ExternalPageCallbacks.h index 09fcc94d090..dd4f113c0ba 100644 --- a/dbms/src/Storages/Page/ExternalPageCallbacks.h +++ b/dbms/src/Storages/Page/ExternalPageCallbacks.h @@ -14,25 +14,27 @@ #pragma once -#include +#include #include namespace DB { - -struct ExternalPageCallbacks +template +struct ExternalPageCallbacksT { // `scanner` for scanning available external page ids on disks. // `remover` will be called with living normal page ids after gc run a round, user should remove those // external pages(files) in `pending_external_pages` but not in `valid_normal_pages` - using PathAndIdsVec = std::vector>>; + using PathAndIdsVec = std::vector>>; using ExternalPagesScanner = std::function; using ExternalPagesRemover - = std::function & valid_normal_pages)>; + = std::function & valid_normal_pages)>; ExternalPagesScanner scanner = nullptr; ExternalPagesRemover remover = nullptr; - NamespaceId ns_id = MAX_NAMESPACE_ID; + Prefix prefix{}; }; +using ExternalPageCallbacks = ExternalPageCallbacksT; +using UniversalExternalPageCallbacks = ExternalPageCallbacksT; } // namespace DB diff --git a/dbms/src/Storages/Page/Page.h b/dbms/src/Storages/Page/Page.h index 974234bf1dd..2a355be115e 100644 --- a/dbms/src/Storages/Page/Page.h +++ b/dbms/src/Storages/Page/Page.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -52,30 +52,35 @@ struct FieldOffsetInsidePage struct Page { public: - // only take the low u64, ignoring the high u64(NamespaceId) - explicit Page(const PageIdV3Internal & page_id_v3_) - : page_id(page_id_v3_.low) + static Page invalidPage() { + Page page{INVALID_PAGE_U64_ID}; + page.is_valid = false; + return page; } - Page() - : page_id(INVALID_PAGE_ID) + explicit Page(PageIdU64 page_id_) + : page_id(page_id_) + , is_valid(true) {} - PageId page_id; + PageIdU64 page_id; ByteBuffer data; MemHolder mem_holder; // Field offsets inside this page. std::set field_offsets; +private: + bool is_valid; + public: - inline bool isValid() const { return page_id != INVALID_PAGE_ID; } + inline bool isValid() const { return is_valid; } ByteBuffer getFieldData(size_t index) const { auto iter = field_offsets.find(FieldOffsetInsidePage(index)); if (unlikely(iter == field_offsets.end())) - throw Exception(fmt::format("Try to getFieldData with invalid field index [page_id={}] [field_index={}]", page_id, index), + throw Exception(fmt::format("Try to getFieldData with invalid field index [page_id={}] [valid={}] [field_index={}]", page_id, is_valid, index), ErrorCodes::LOGICAL_ERROR); PageFieldOffset beg = iter->offset; @@ -107,9 +112,8 @@ struct Page }; using Pages = std::vector; -using PageMap = std::map; +using PageMapU64 = std::map; -// TODO: Move it into V2 // Indicate the page size && offset in PageFile. struct PageEntry { @@ -187,8 +191,6 @@ struct PageEntry return true; } }; -using PageIdAndEntry = std::pair; -using PageIdAndEntries = std::vector; - - +using PageIdU64AndEntry = std::pair; +using PageIdU64AndEntries = std::vector; } // namespace DB diff --git a/dbms/src/Storages/Page/PageDefines.h b/dbms/src/Storages/Page/PageDefinesBase.h similarity index 91% rename from dbms/src/Storages/Page/PageDefines.h rename to dbms/src/Storages/Page/PageDefinesBase.h index a03963748c2..2a6e1e45c80 100644 --- a/dbms/src/Storages/Page/PageDefines.h +++ b/dbms/src/Storages/Page/PageDefinesBase.h @@ -52,15 +52,15 @@ static constexpr NamespaceId KVSTORE_NAMESPACE_ID = 1000000UL; // just a random namespace id for test, the value doesn't matter static constexpr NamespaceId TEST_NAMESPACE_ID = 1000; -using PageId = UInt64; -using PageIds = std::vector; -using PageIdSet = std::unordered_set; -static constexpr PageId INVALID_PAGE_ID = 0; +using PageIdU64 = UInt64; +using PageIdU64s = std::vector; +using PageIdU64Set = std::unordered_set; +static constexpr PageIdU64 INVALID_PAGE_U64_ID = 0; using PageIdV3Internal = UInt128; using PageIdV3Internals = std::vector; -inline PageIdV3Internal buildV3Id(NamespaceId n_id, PageId p_id) +inline PageIdV3Internal buildV3Id(NamespaceId n_id, PageIdU64 p_id) { // low bits first return PageIdV3Internal(p_id, n_id); @@ -79,11 +79,6 @@ using PageFileIdAndLevels = std::vector; using PageSize = UInt64; -using BlobFileId = UInt64; -using BlobFileOffset = UInt64; -static constexpr BlobFileId INVALID_BLOBFILE_ID = 0; -static constexpr BlobFileOffset INVALID_BLOBFILE_OFFSET = std::numeric_limits::max(); - struct ByteBuffer { using Pos = char *; @@ -135,6 +130,7 @@ struct fmt::formatter return format_to(ctx.out(), "{}.{}", value.high, value.low); } }; + template <> struct fmt::formatter { diff --git a/dbms/src/Storages/Page/PageStorage.cpp b/dbms/src/Storages/Page/PageStorage.cpp index 1103daef4ce..49c60b5862b 100644 --- a/dbms/src/Storages/Page/PageStorage.cpp +++ b/dbms/src/Storages/Page/PageStorage.cpp @@ -51,16 +51,16 @@ class PageReaderImpl : private boost::noncopyable virtual ~PageReaderImpl() = default; - virtual DB::Page read(PageId page_id) const = 0; + virtual DB::Page read(PageIdU64 page_id) const = 0; - virtual PageMap read(const PageIds & page_ids) const = 0; + virtual PageMapU64 read(const PageIdU64s & page_ids) const = 0; using PageReadFields = PageStorage::PageReadFields; - virtual PageMap read(const std::vector & page_fields) const = 0; + virtual PageMapU64 read(const std::vector & page_fields) const = 0; - virtual PageId getNormalPageId(PageId page_id) const = 0; + virtual PageIdU64 getNormalPageId(PageIdU64 page_id) const = 0; - virtual PageEntry getPageEntry(PageId page_id) const = 0; + virtual PageEntry getPageEntry(PageIdU64 page_id) const = 0; virtual PageStorage::SnapshotPtr getSnapshot(const String & tracing_id) const = 0; @@ -93,28 +93,28 @@ class PageReaderImplNormal : public PageReaderImpl { } - DB::Page read(PageId page_id) const override + DB::Page read(PageIdU64 page_id) const override { return storage->read(ns_id, page_id, read_limiter, snap); } - PageMap read(const PageIds & page_ids) const override + PageMapU64 read(const PageIdU64s & page_ids) const override { return storage->read(ns_id, page_ids, read_limiter, snap); } using PageReadFields = PageStorage::PageReadFields; - PageMap read(const std::vector & page_fields) const override + PageMapU64 read(const std::vector & page_fields) const override { return storage->read(ns_id, page_fields, read_limiter, snap); } - PageId getNormalPageId(PageId page_id) const override + PageIdU64 getNormalPageId(PageIdU64 page_id) const override { return storage->getNormalPageId(ns_id, page_id, snap); } - PageEntry getPageEntry(PageId page_id) const override + PageEntry getPageEntry(PageIdU64 page_id) const override { return storage->getEntry(ns_id, page_id, snap); } @@ -179,7 +179,7 @@ class PageReaderImplMixed : public PageReaderImpl { } - DB::Page read(PageId page_id) const override + DB::Page read(PageIdU64 page_id) const override { const auto & page_from_v3 = storage_v3->read(ns_id, page_id, read_limiter, toConcreteV3Snapshot(), false); if (page_from_v3.isValid()) @@ -189,10 +189,10 @@ class PageReaderImplMixed : public PageReaderImpl return storage_v2->read(ns_id, page_id, read_limiter, toConcreteV2Snapshot()); } - PageMap read(const PageIds & page_ids) const override + PageMapU64 read(const PageIdU64s & page_ids) const override { auto page_maps = storage_v3->read(ns_id, page_ids, read_limiter, toConcreteV3Snapshot(), false); - PageIds invalid_page_ids; + PageIdU64s invalid_page_ids; for (const auto & [query_page_id, page] : page_maps) { if (!page.isValid()) @@ -206,7 +206,7 @@ class PageReaderImplMixed : public PageReaderImpl const auto & page_maps_from_v2 = storage_v2->read(ns_id, invalid_page_ids, read_limiter, toConcreteV2Snapshot()); for (const auto & [page_id_, page_] : page_maps_from_v2) { - page_maps[page_id_] = page_; + page_maps.at(page_id_) = page_; } } @@ -214,7 +214,7 @@ class PageReaderImplMixed : public PageReaderImpl } using PageReadFields = PageStorage::PageReadFields; - PageMap read(const std::vector & page_fields) const override + PageMapU64 read(const std::vector & page_fields) const override { auto page_maps = storage_v3->read(ns_id, page_fields, read_limiter, toConcreteV3Snapshot(), false); @@ -222,7 +222,7 @@ class PageReaderImplMixed : public PageReaderImpl for (const auto & page_field : page_fields) { - if (!page_maps[page_field.first].isValid()) + if (!page_maps.at(page_field.first).isValid()) { invalid_page_fields.emplace_back(page_field); } @@ -233,24 +233,24 @@ class PageReaderImplMixed : public PageReaderImpl auto page_maps_from_v2 = storage_v2->read(ns_id, invalid_page_fields, read_limiter, toConcreteV2Snapshot()); for (const auto & page_field : invalid_page_fields) { - page_maps[page_field.first] = page_maps_from_v2[page_field.first]; + page_maps.at(page_field.first) = page_maps_from_v2.at(page_field.first); } } return page_maps; } - PageId getNormalPageId(PageId page_id) const override + PageIdU64 getNormalPageId(PageIdU64 page_id) const override { - PageId resolved_page_id = storage_v3->getNormalPageId(ns_id, page_id, toConcreteV3Snapshot(), false); - if (resolved_page_id != INVALID_PAGE_ID) + PageIdU64 resolved_page_id = storage_v3->getNormalPageId(ns_id, page_id, toConcreteV3Snapshot(), false); + if (resolved_page_id != INVALID_PAGE_U64_ID) { return resolved_page_id; } return storage_v2->getNormalPageId(ns_id, page_id, toConcreteV2Snapshot()); } - PageEntry getPageEntry(PageId page_id) const override + PageEntry getPageEntry(PageIdU64 page_id) const override { PageEntry page_entry = storage_v3->getEntry(ns_id, page_id, toConcreteV3Snapshot()); if (page_entry.file_id != INVALID_BLOBFILE_ID) @@ -385,27 +385,27 @@ PageReader::PageReader(const PageStorageRunMode & run_mode_, NamespaceId ns_id_, PageReader::~PageReader() = default; -DB::Page PageReader::read(PageId page_id) const +DB::Page PageReader::read(PageIdU64 page_id) const { return impl->read(page_id); } -PageMap PageReader::read(const PageIds & page_ids) const +PageMapU64 PageReader::read(const PageIdU64s & page_ids) const { return impl->read(page_ids); } -PageMap PageReader::read(const std::vector & page_fields) const +PageMapU64 PageReader::read(const std::vector & page_fields) const { return impl->read(page_fields); } -PageId PageReader::getNormalPageId(PageId page_id) const +PageIdU64 PageReader::getNormalPageId(PageIdU64 page_id) const { return impl->getNormalPageId(page_id); } -PageEntry PageReader::getPageEntry(PageId page_id) const +PageEntry PageReader::getPageEntry(PageIdU64 page_id) const { return impl->getPageEntry(page_id); } @@ -478,7 +478,7 @@ void PageWriter::writeIntoMixMode(WriteBatch && write_batch, WriteLimiterPtr wri // We need hold mem from V2 pages after write. std::list mem_holders; - std::set page_ids_before_ref; + PageIdU64Set page_ids_before_ref; for (const auto & write : write_batch.getWrites()) { @@ -500,13 +500,13 @@ void PageWriter::writeIntoMixMode(WriteBatch && write_batch, WriteLimiterPtr wri case WriteBatchWriteType::REF: { // 1. Try to resolve normal page id - PageId resolved_page_id = storage_v3->getNormalPageId(ns_id, - write.ori_page_id, - /*snapshot*/ nullptr, - false); + PageIdU64 resolved_page_id = storage_v3->getNormalPageId(ns_id, + write.ori_page_id, + /*snapshot*/ nullptr, + false); // If the origin id is found in V3, then just apply the ref to v3 - if (resolved_page_id != INVALID_PAGE_ID) + if (resolved_page_id != INVALID_PAGE_U64_ID) { break; } diff --git a/dbms/src/Storages/Page/PageStorage.h b/dbms/src/Storages/Page/PageStorage.h index 9368b8eb30f..856397dca5a 100644 --- a/dbms/src/Storages/Page/PageStorage.h +++ b/dbms/src/Storages/Page/PageStorage.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -84,14 +84,6 @@ class PageStorage : private boost::noncopyable } PageStorageConfig getSettings() const { return config; } - // Use a more easy gc config for v2 when all of its data will be transformed to v3. - static PageStorageConfig getEasyGCConfig() - { - PageStorageConfig gc_config; - gc_config.file_roll_size = PAGE_FILE_SMALL_SIZE; - return gc_config; - } - public: static PageStoragePtr create( @@ -131,7 +123,7 @@ class PageStorage : private boost::noncopyable // this function returns the global max id regardless of ns_id. This causes the ids in a table // to not be continuously incremented. // Note that Page id 1 in each ns_id is special. - virtual PageId getMaxId() = 0; + virtual PageIdU64 getMaxId() = 0; virtual SnapshotPtr getSnapshot(const String & tracing_id) = 0; @@ -146,7 +138,7 @@ class PageStorage : private boost::noncopyable virtual size_t getNumberOfPages() = 0; - virtual std::set getAliveExternalPageIds(NamespaceId ns_id) = 0; + virtual std::set getAliveExternalPageIds(NamespaceId ns_id) = 0; void write(WriteBatch && write_batch, const WriteLimiterPtr & write_limiter = nullptr) { @@ -155,25 +147,25 @@ class PageStorage : private boost::noncopyable // If we can't get the entry. // Then the null entry will be return - PageEntry getEntry(NamespaceId ns_id, PageId page_id, SnapshotPtr snapshot = {}) + PageEntry getEntry(NamespaceId ns_id, PageIdU64 page_id, SnapshotPtr snapshot = {}) { return getEntryImpl(ns_id, page_id, snapshot); } - Page read(NamespaceId ns_id, PageId page_id, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) + Page read(NamespaceId ns_id, PageIdU64 page_id, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) { return readImpl(ns_id, page_id, read_limiter, snapshot, throw_on_not_exist); } - PageMap read(NamespaceId ns_id, const PageIds & page_ids, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) + PageMapU64 read(NamespaceId ns_id, const PageIdU64s & page_ids, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) { return readImpl(ns_id, page_ids, read_limiter, snapshot, throw_on_not_exist); } using FieldIndices = std::vector; - using PageReadFields = std::pair; + using PageReadFields = std::pair; - PageMap read(NamespaceId ns_id, const std::vector & page_fields, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) + PageMapU64 read(NamespaceId ns_id, const std::vector & page_fields, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) { return readImpl(ns_id, page_fields, read_limiter, snapshot, throw_on_not_exist); } @@ -188,7 +180,7 @@ class PageStorage : private boost::noncopyable traverseImpl(acceptor, snapshot); } - PageId getNormalPageId(NamespaceId ns_id, PageId page_id, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) + PageIdU64 getNormalPageId(NamespaceId ns_id, PageIdU64 page_id, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) { return getNormalPageIdImpl(ns_id, page_id, snapshot, throw_on_not_exist); } @@ -211,19 +203,19 @@ class PageStorage : private boost::noncopyable #endif virtual void writeImpl(WriteBatch && write_batch, const WriteLimiterPtr & write_limiter) = 0; - virtual PageEntry getEntryImpl(NamespaceId ns_id, PageId page_id, SnapshotPtr snapshot) = 0; + virtual PageEntry getEntryImpl(NamespaceId ns_id, PageIdU64 page_id, SnapshotPtr snapshot) = 0; - virtual Page readImpl(NamespaceId ns_id, PageId page_id, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; + virtual Page readImpl(NamespaceId ns_id, PageIdU64 page_id, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; - virtual PageMap readImpl(NamespaceId ns_id, const PageIds & page_ids, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; + virtual PageMapU64 readImpl(NamespaceId ns_id, const PageIdU64s & page_ids, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; - virtual PageMap readImpl(NamespaceId ns_id, const std::vector & page_fields, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; + virtual PageMapU64 readImpl(NamespaceId ns_id, const std::vector & page_fields, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; virtual Page readImpl(NamespaceId ns_id, const PageReadFields & page_field, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; virtual void traverseImpl(const std::function & acceptor, SnapshotPtr snapshot) = 0; - virtual PageId getNormalPageIdImpl(NamespaceId ns_id, PageId page_id, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; + virtual PageIdU64 getNormalPageIdImpl(NamespaceId ns_id, PageIdU64 page_id, SnapshotPtr snapshot, bool throw_on_not_exist) = 0; virtual bool gcImpl(bool not_skip, const WriteLimiterPtr & write_limiter, const ReadLimiterPtr & read_limiter) = 0; @@ -249,16 +241,16 @@ class PageReader : private boost::noncopyable ~PageReader(); - DB::Page read(PageId page_id) const; + DB::Page read(PageIdU64 page_id) const; - PageMap read(const PageIds & page_ids) const; + PageMapU64 read(const PageIdU64s & page_ids) const; using PageReadFields = PageStorage::PageReadFields; - PageMap read(const std::vector & page_fields) const; + PageMapU64 read(const std::vector & page_fields) const; - PageId getNormalPageId(PageId page_id) const; + PageIdU64 getNormalPageId(PageIdU64 page_id) const; - PageEntry getPageEntry(PageId page_id) const; + PageEntry getPageEntry(PageIdU64 page_id) const; PageStorage::SnapshotPtr getSnapshot(const String & tracing_id) const; diff --git a/dbms/src/Storages/Page/V1/Page.h b/dbms/src/Storages/Page/V1/Page.h index 8d1a46d4a1e..fcdd7d7b8b0 100644 --- a/dbms/src/Storages/Page/V1/Page.h +++ b/dbms/src/Storages/Page/V1/Page.h @@ -15,8 +15,13 @@ #pragma once #include +#include namespace DB::PS::V1 { +using PageId = DB::PS::V2::PageId; +using PageIds = PS::V2::PageIds; +using PageIdSet = PS::V2::PageIdSet; + struct Page { PageId page_id; diff --git a/dbms/src/Storages/Page/V1/PageEntries.h b/dbms/src/Storages/Page/V1/PageEntries.h index 6b22c362643..17028470d02 100644 --- a/dbms/src/Storages/Page/V1/PageEntries.h +++ b/dbms/src/Storages/Page/V1/PageEntries.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V1/PageFile.h b/dbms/src/Storages/Page/V1/PageFile.h index 4f49d049ac5..0b6a90c15cc 100644 --- a/dbms/src/Storages/Page/V1/PageFile.h +++ b/dbms/src/Storages/Page/V1/PageFile.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V1/PageStorage.h b/dbms/src/Storages/Page/V1/PageStorage.h index 824f0fcaa90..d778b7d2d08 100644 --- a/dbms/src/Storages/Page/V1/PageStorage.h +++ b/dbms/src/Storages/Page/V1/PageStorage.h @@ -15,7 +15,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V1/VersionSet/PageEntriesEdit.h b/dbms/src/Storages/Page/V1/VersionSet/PageEntriesEdit.h index 0af786a1add..dc1e3fa07de 100644 --- a/dbms/src/Storages/Page/V1/VersionSet/PageEntriesEdit.h +++ b/dbms/src/Storages/Page/V1/VersionSet/PageEntriesEdit.h @@ -15,7 +15,7 @@ #pragma once #include -#include +#include #include #include diff --git a/dbms/src/Storages/Page/V1/WriteBatch.h b/dbms/src/Storages/Page/V1/WriteBatch.h index 2d5eda2b9ce..324ff43cb35 100644 --- a/dbms/src/Storages/Page/V1/WriteBatch.h +++ b/dbms/src/Storages/Page/V1/WriteBatch.h @@ -15,7 +15,7 @@ #pragma once #include -#include +#include #include diff --git a/dbms/src/Storages/Page/V2/PageDefines.h b/dbms/src/Storages/Page/V2/PageDefines.h new file mode 100644 index 00000000000..134bf570d57 --- /dev/null +++ b/dbms/src/Storages/Page/V2/PageDefines.h @@ -0,0 +1,26 @@ +// 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 + +namespace DB::PS::V2 +{ +using PageId = PageIdU64; +using PageIds = PageIdU64s; +using PageIdSet = PageIdU64Set; +static constexpr PageId INVALID_PAGE_ID = INVALID_PAGE_U64_ID; + +} // namespace DB::PS::V2 diff --git a/dbms/src/Storages/Page/V2/PageEntries.h b/dbms/src/Storages/Page/V2/PageEntries.h index 7f82a6907a0..7f22f52e820 100644 --- a/dbms/src/Storages/Page/V2/PageEntries.h +++ b/dbms/src/Storages/Page/V2/PageEntries.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Storages/Page/V2/PageFile.cpp b/dbms/src/Storages/Page/V2/PageFile.cpp index d4642270822..e99f96d7cc0 100644 --- a/dbms/src/Storages/Page/V2/PageFile.cpp +++ b/dbms/src/Storages/Page/V2/PageFile.cpp @@ -918,8 +918,7 @@ PageMap PageFile::Reader::read(PageIdAndEntries & to_read, const ReadLimiterPtr } } - Page page; - page.page_id = page_id; + Page page(page_id); page.data = ByteBuffer(pos, pos + entry.size); page.mem_holder = mem_holder; @@ -1008,8 +1007,7 @@ PageMap PageFile::Reader::read(PageFile::Reader::FieldReadInfos & to_read, const write_offset += size_to_read; } - Page page; - page.page_id = page_id; + Page page(page_id); page.data = ByteBuffer(pos, write_offset); page.mem_holder = mem_holder; page.field_offsets.swap(fields_offset_in_page); @@ -1043,7 +1041,6 @@ Page PageFile::Reader::read(FieldReadInfo & to_read, const ReadLimiterPtr & read char * data_buf = static_cast(alloc(buf_size)); MemHolder mem_holder = createMemHolder(data_buf, [&, buf_size](char * p) { free(p, buf_size); }); - Page page_rc; std::set fields_offset_in_page; size_t read_size_this_entry = 0; @@ -1080,8 +1077,7 @@ Page PageFile::Reader::read(FieldReadInfo & to_read, const ReadLimiterPtr & read } } - Page page; - page.page_id = to_read.page_id; + Page page(to_read.page_id); page.data = ByteBuffer(data_buf, write_offset); page.mem_holder = mem_holder; page.field_offsets.swap(fields_offset_in_page); diff --git a/dbms/src/Storages/Page/V2/PageFile.h b/dbms/src/Storages/Page/V2/PageFile.h index d3209b99936..eaeb4d2f148 100644 --- a/dbms/src/Storages/Page/V2/PageFile.h +++ b/dbms/src/Storages/Page/V2/PageFile.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,10 @@ class Logger; namespace DB::PS::V2 { +using PageIdAndEntry = PageIdU64AndEntry; +using PageIdAndEntries = PageIdU64AndEntries; +using PageMap = PageMapU64; + /// A light-weight object which can be created and copied cheaply. /// Use createWriter()/createReader() to open write/read system file. class PageFile : public Allocator diff --git a/dbms/src/Storages/Page/V2/PageStorage.cpp b/dbms/src/Storages/Page/V2/PageStorage.cpp index 93f1c9d64be..eada0df7e60 100644 --- a/dbms/src/Storages/Page/V2/PageStorage.cpp +++ b/dbms/src/Storages/Page/V2/PageStorage.cpp @@ -653,7 +653,7 @@ DB::Page PageStorage::readImpl(NamespaceId /*ns_id*/, PageId page_id, const Read const auto file_id_level = page_entry->fileIdLevel(); PageIdAndEntries to_read = {{page_id, *page_entry}}; auto file_reader = getReader(file_id_level); - return file_reader->read(to_read, read_limiter)[page_id]; + return file_reader->read(to_read, read_limiter).at(page_id); } PageMap PageStorage::readImpl(NamespaceId /*ns_id*/, const PageIds & page_ids, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) diff --git a/dbms/src/Storages/Page/V2/PageStorage.h b/dbms/src/Storages/Page/V2/PageStorage.h index 0d1dcbb67a7..f2a63f855f6 100644 --- a/dbms/src/Storages/Page/V2/PageStorage.h +++ b/dbms/src/Storages/Page/V2/PageStorage.h @@ -17,8 +17,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -92,7 +92,7 @@ class PageStorage : public DB::PageStorage const FileProviderPtr & file_provider_, BackgroundProcessingPool & ver_compact_pool_, bool no_more_insert_ = false); - ~PageStorage() override { shutdown(); } + ~PageStorage() override { shutdown(); } // NOLINT(clang-analyzer-optin.cplusplus.VirtualCall) void restore() override; diff --git a/dbms/src/Storages/Page/V2/VersionSet/PageEntriesEdit.h b/dbms/src/Storages/Page/V2/VersionSet/PageEntriesEdit.h index f077392a19a..6b9dee18f74 100644 --- a/dbms/src/Storages/Page/V2/VersionSet/PageEntriesEdit.h +++ b/dbms/src/Storages/Page/V2/VersionSet/PageEntriesEdit.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include namespace DB::PS::V2 diff --git a/dbms/src/Storages/Page/V2/VersionSet/PageEntriesVersionSetWithDelta.h b/dbms/src/Storages/Page/V2/VersionSet/PageEntriesVersionSetWithDelta.h index 9045aa01b26..797d4ba2a4b 100644 --- a/dbms/src/Storages/Page/V2/VersionSet/PageEntriesVersionSetWithDelta.h +++ b/dbms/src/Storages/Page/V2/VersionSet/PageEntriesVersionSetWithDelta.h @@ -20,8 +20,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V2/VersionSet/PageEntriesView.h b/dbms/src/Storages/Page/V2/VersionSet/PageEntriesView.h index fe51c629663..2970c70b1ae 100644 --- a/dbms/src/Storages/Page/V2/VersionSet/PageEntriesView.h +++ b/dbms/src/Storages/Page/V2/VersionSet/PageEntriesView.h @@ -15,7 +15,7 @@ #pragma once #include -#include +#include #include #include diff --git a/dbms/src/Storages/Page/V2/gc/LegacyCompactor.h b/dbms/src/Storages/Page/V2/gc/LegacyCompactor.h index 7ba64396ca2..0722b87b056 100644 --- a/dbms/src/Storages/Page/V2/gc/LegacyCompactor.h +++ b/dbms/src/Storages/Page/V2/gc/LegacyCompactor.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V2/tests/gtest_legacy_compactor.cpp b/dbms/src/Storages/Page/V2/tests/gtest_legacy_compactor.cpp index 4ca0980bf64..e3522530c59 100644 --- a/dbms/src/Storages/Page/V2/tests/gtest_legacy_compactor.cpp +++ b/dbms/src/Storages/Page/V2/tests/gtest_legacy_compactor.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V2/tests/gtest_page_file.cpp b/dbms/src/Storages/Page/V2/tests/gtest_page_file.cpp index 351daabe5fa..ca6ebdd9f6d 100644 --- a/dbms/src/Storages/Page/V2/tests/gtest_page_file.cpp +++ b/dbms/src/Storages/Page/V2/tests/gtest_page_file.cpp @@ -86,7 +86,7 @@ TEST(Page_test, GetField) for (size_t i = 0; i < buf_sz; ++i) c_buff[i] = i % 0xff; - Page page; + Page page{1}; page.data = ByteBuffer(c_buff, c_buff + buf_sz); std::set fields{// {field_index, data_offset} {2, 0}, diff --git a/dbms/src/Storages/Page/V2/tests/gtest_page_storage.cpp b/dbms/src/Storages/Page/V2/tests/gtest_page_storage.cpp index 49060f9fdfe..18dc7aad01a 100644 --- a/dbms/src/Storages/Page/V2/tests/gtest_page_storage.cpp +++ b/dbms/src/Storages/Page/V2/tests/gtest_page_storage.cpp @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -1286,7 +1286,7 @@ TEST_F(PageStorageWith2Pages_test, SnapshotReadSnapshotVersion) }; auto pages = storage->read(ids, nullptr, snapshot); ASSERT_EQ(pages.count(1), 1UL); - ASSERT_EQ(*pages[1].data.begin(), ch_before); + ASSERT_EQ(*pages.at(1).data.begin(), ch_before); // TODO read(vec, callback) with snapshot // new page do appear while read with snapshot @@ -1343,13 +1343,13 @@ TEST_F(PageStorageWith2Pages_test, GetIdenticalSnapshots) // read(vec) with snapshot auto pages = storage->read(ids, nullptr, s1); ASSERT_EQ(pages.count(1), 1UL); - ASSERT_EQ(*pages[1].data.begin(), ch_before); + ASSERT_EQ(*pages.at(1).data.begin(), ch_before); pages = storage->read(ids, nullptr, s2); ASSERT_EQ(pages.count(1), 1UL); - ASSERT_EQ(*pages[1].data.begin(), ch_before); + ASSERT_EQ(*pages.at(1).data.begin(), ch_before); pages = storage->read(ids, nullptr, s3); ASSERT_EQ(pages.count(1), 1UL); - ASSERT_EQ(*pages[1].data.begin(), ch_before); + ASSERT_EQ(*pages.at(1).data.begin(), ch_before); // TODO read(vec, callback) with snapshot // without snapshot p1_entry = storage->getEntry(1); @@ -1369,13 +1369,13 @@ TEST_F(PageStorageWith2Pages_test, GetIdenticalSnapshots) page1 = storage->read(1, nullptr, s3); ASSERT_EQ(*page1.data.begin(), ch_before); // read(vec) with snapshot - ASSERT_EQ(*pages[1].data.begin(), ch_before); + ASSERT_EQ(*pages.at(1).data.begin(), ch_before); pages = storage->read(ids, nullptr, s2); ASSERT_EQ(pages.count(1), 1UL); - ASSERT_EQ(*pages[1].data.begin(), ch_before); + ASSERT_EQ(*pages.at(1).data.begin(), ch_before); pages = storage->read(ids, nullptr, s3); ASSERT_EQ(pages.count(1), 1UL); - ASSERT_EQ(*pages[1].data.begin(), ch_before); + ASSERT_EQ(*pages.at(1).data.begin(), ch_before); // TODO read(vec, callback) with snapshot // without snapshot p1_entry = storage->getEntry(1); @@ -1393,7 +1393,7 @@ TEST_F(PageStorageWith2Pages_test, GetIdenticalSnapshots) // read(vec) with snapshot pages = storage->read(ids, nullptr, s3); ASSERT_EQ(pages.count(1), 1UL); - ASSERT_EQ(*pages[1].data.begin(), ch_before); + ASSERT_EQ(*pages.at(1).data.begin(), ch_before); // TODO read(vec, callback) with snapshot // without snapshot p1_entry = storage->getEntry(1); diff --git a/dbms/src/Storages/Page/V2/tests/gtest_page_storage_multi_paths.cpp b/dbms/src/Storages/Page/V2/tests/gtest_page_storage_multi_paths.cpp index 178c3a3edcd..11a8496e486 100644 --- a/dbms/src/Storages/Page/V2/tests/gtest_page_storage_multi_paths.cpp +++ b/dbms/src/Storages/Page/V2/tests/gtest_page_storage_multi_paths.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V2/tests/gtest_page_storage_multi_writers.cpp b/dbms/src/Storages/Page/V2/tests/gtest_page_storage_multi_writers.cpp index 5cc7be170d6..afc3df1bcab 100644 --- a/dbms/src/Storages/Page/V2/tests/gtest_page_storage_multi_writers.cpp +++ b/dbms/src/Storages/Page/V2/tests/gtest_page_storage_multi_writers.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V3/Blob/BlobConfig.h b/dbms/src/Storages/Page/V3/Blob/BlobConfig.h index 55b25ef3c1d..303bc881d68 100644 --- a/dbms/src/Storages/Page/V3/Blob/BlobConfig.h +++ b/dbms/src/Storages/Page/V3/Blob/BlobConfig.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/dbms/src/Storages/Page/V3/Blob/BlobFile.h b/dbms/src/Storages/Page/V3/Blob/BlobFile.h index 4aee0695ee0..c45428e62cc 100644 --- a/dbms/src/Storages/Page/V3/Blob/BlobFile.h +++ b/dbms/src/Storages/Page/V3/Blob/BlobFile.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Storages/Page/V3/Blob/BlobStat.h b/dbms/src/Storages/Page/V3/Blob/BlobStat.h index e7a20fc9861..16633493a8b 100644 --- a/dbms/src/Storages/Page/V3/Blob/BlobStat.h +++ b/dbms/src/Storages/Page/V3/Blob/BlobStat.h @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -187,6 +186,7 @@ class BlobStats #endif void restoreByEntry(const PageEntryV3 & entry); void restore(); + template friend class PageDirectoryFactory; #ifndef DBMS_PUBLIC_GTEST diff --git a/dbms/src/Storages/Page/V3/BlobStore.cpp b/dbms/src/Storages/Page/V3/BlobStore.cpp index 85eb79457f1..8da5bcafd5b 100644 --- a/dbms/src/Storages/Page/V3/BlobStore.cpp +++ b/dbms/src/Storages/Page/V3/BlobStore.cpp @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -71,7 +71,8 @@ using ChecksumClass = Digest::CRC64; * BlobStore methods * *********************/ -BlobStore::BlobStore(String storage_name, const FileProviderPtr & file_provider_, PSDiskDelegatorPtr delegator_, const BlobConfig & config_) +template +BlobStore::BlobStore(const String & storage_name, const FileProviderPtr & file_provider_, PSDiskDelegatorPtr delegator_, const BlobConfig & config_) : delegator(std::move(delegator_)) , file_provider(file_provider_) , config(config_) @@ -80,7 +81,8 @@ BlobStore::BlobStore(String storage_name, const FileProviderPtr & file_provider_ { } -void BlobStore::registerPaths() +template +void BlobStore::registerPaths() { for (const auto & path : delegator->listPaths()) { @@ -114,7 +116,8 @@ void BlobStore::registerPaths() } } -void BlobStore::reloadConfig(const BlobConfig & rhs) +template +void BlobStore::reloadConfig(const BlobConfig & rhs) { // Currently, we don't add any config for `file_limit_size`, so it won't reload at run time. // And if we support it in the future(although it seems there is no need to do that), @@ -127,7 +130,8 @@ void BlobStore::reloadConfig(const BlobConfig & rhs) config.heavy_gc_valid_rate = rhs.heavy_gc_valid_rate; } -FileUsageStatistics BlobStore::getFileUsageStatistics() const +template +FileUsageStatistics BlobStore::getFileUsageStatistics() const { FileUsageStatistics usage; @@ -159,7 +163,9 @@ FileUsageStatistics BlobStore::getFileUsageStatistics() const return usage; } -PageEntriesEdit BlobStore::handleLargeWrite(DB::WriteBatch & wb, const WriteLimiterPtr & write_limiter) +template +typename BlobStore::PageEntriesEdit +BlobStore::handleLargeWrite(typename Trait::WriteBatch & wb, const WriteLimiterPtr & write_limiter) { PageEntriesEdit edit; for (auto & write : wb.getWrites()) @@ -239,7 +245,9 @@ PageEntriesEdit BlobStore::handleLargeWrite(DB::WriteBatch & wb, const WriteLimi return edit; } -PageEntriesEdit BlobStore::write(DB::WriteBatch & wb, const WriteLimiterPtr & write_limiter) +template +typename BlobStore::PageEntriesEdit +BlobStore::write(typename Trait::WriteBatch & wb, const WriteLimiterPtr & write_limiter) { ProfileEvents::increment(ProfileEvents::PSMWritePages, wb.putWriteCount()); @@ -405,7 +413,8 @@ PageEntriesEdit BlobStore::write(DB::WriteBatch & wb, const WriteLimiterPtr & wr return edit; } -void BlobStore::remove(const PageEntriesV3 & del_entries) +template +void BlobStore::remove(const PageEntries & del_entries) { std::set blob_updated; for (const auto & entry : del_entries) @@ -453,7 +462,8 @@ void BlobStore::remove(const PageEntriesV3 & del_entries) } } -std::pair BlobStore::getPosFromStats(size_t size) +template +std::pair BlobStore::getPosFromStats(size_t size) { Stopwatch watch; BlobStatPtr stat; @@ -509,7 +519,8 @@ std::pair BlobStore::getPosFromStats(size_t size) return std::make_pair(stat->id, offset); } -void BlobStore::removePosFromStats(BlobFileId blob_id, BlobFileOffset offset, size_t size) +template +void BlobStore::removePosFromStats(BlobFileId blob_id, BlobFileOffset offset, size_t size) { const auto & stat = blob_stats.blobIdToStat(blob_id); { @@ -550,7 +561,9 @@ void BlobStore::removePosFromStats(BlobFileId blob_id, BlobFileOffset offset, si } } -PageMap BlobStore::read(FieldReadInfos & to_read, const ReadLimiterPtr & read_limiter) +template +typename BlobStore::PageMap +BlobStore::read(FieldReadInfos & to_read, const ReadLimiterPtr & read_limiter) { if (to_read.empty()) { @@ -606,9 +619,9 @@ PageMap BlobStore::read(FieldReadInfos & to_read, const ReadLimiterPtr & read_li for (const auto & [page_id, entry, fields] : to_read) { UNUSED(entry, fields); - Page page(page_id); + Page page(Trait::PageIdTrait::getU64ID(page_id)); page.data = ByteBuffer(nullptr, nullptr); - page_map.emplace(page_id.low, std::move(page)); + page_map.emplace(Trait::PageIdTrait::getPageMapKey(page_id), std::move(page)); } return page_map; } @@ -663,12 +676,12 @@ PageMap BlobStore::read(FieldReadInfos & to_read, const ReadLimiterPtr & read_li write_offset += size_to_read; } - Page page(page_id_v3); + Page page(Trait::PageIdTrait::getU64ID(page_id_v3)); page.data = ByteBuffer(pos, write_offset); page.mem_holder = shared_mem_holder; page.field_offsets.swap(fields_offset_in_page); fields_offset_in_page.clear(); - page_map.emplace(page_id_v3.low, std::move(page)); + page_map.emplace(Trait::PageIdTrait::getPageMapKey(page_id_v3), std::move(page)); pos = write_offset; } @@ -692,7 +705,9 @@ PageMap BlobStore::read(FieldReadInfos & to_read, const ReadLimiterPtr & read_li return page_map; } -PageMap BlobStore::read(PageIDAndEntriesV3 & entries, const ReadLimiterPtr & read_limiter) +template +typename BlobStore::PageMap +BlobStore::read(PageIdAndEntries & entries, const ReadLimiterPtr & read_limiter) { if (entries.empty()) { @@ -722,8 +737,8 @@ PageMap BlobStore::read(PageIDAndEntriesV3 & entries, const ReadLimiterPtr & rea { (void)entry; LOG_DEBUG(log, "Read entry [page_id={}] without entry size.", page_id_v3); - Page page(page_id_v3); - page_map.emplace(page_id_v3.low, page); + Page page(Trait::PageIdTrait::getU64ID(page_id_v3)); + page_map.emplace(Trait::PageIdTrait::getPageMapKey(page_id_v3), page); } return page_map; } @@ -757,7 +772,7 @@ PageMap BlobStore::read(PageIDAndEntriesV3 & entries, const ReadLimiterPtr & rea } } - Page page(page_id_v3); + Page page(Trait::PageIdTrait::getU64ID(page_id_v3)); page.data = ByteBuffer(pos, pos + entry.size); page.mem_holder = mem_holder; @@ -768,7 +783,7 @@ PageMap BlobStore::read(PageIDAndEntriesV3 & entries, const ReadLimiterPtr & rea page.field_offsets.emplace(index, offset); } - page_map.emplace(page_id_v3.low, std::move(page)); + page_map.emplace(Trait::PageIdTrait::getPageMapKey(page_id_v3), std::move(page)); pos += entry.size; } @@ -779,7 +794,7 @@ PageMap BlobStore::read(PageIDAndEntriesV3 & entries, const ReadLimiterPtr & rea buf.joinStr( entries.begin(), entries.end(), - [](const PageIDAndEntryV3 & id_entry, FmtBuffer & fb) { + [](const PageIdAndEntry & id_entry, FmtBuffer & fb) { fb.fmtAppend("{{page_id: {}, entry: {}}}", id_entry.first, toDebugString(id_entry.second)); }, ","); @@ -793,15 +808,15 @@ PageMap BlobStore::read(PageIDAndEntriesV3 & entries, const ReadLimiterPtr & rea return page_map; } -Page BlobStore::read(const PageIDAndEntryV3 & id_entry, const ReadLimiterPtr & read_limiter) +template +Page BlobStore::read(const PageIdAndEntry & id_entry, const ReadLimiterPtr & read_limiter) { const auto & [page_id_v3, entry] = id_entry; const size_t buf_size = entry.size; if (!entry.isValid()) { - Page page_not_found(buildV3Id(id_entry.first.high, INVALID_PAGE_ID)); - return page_not_found; + return Page::invalidPage(); } // When we read `WriteBatch` which is `WriteType::PUT_EXTERNAL`. @@ -809,7 +824,7 @@ Page BlobStore::read(const PageIDAndEntryV3 & id_entry, const ReadLimiterPtr & r if (buf_size == 0) { LOG_DEBUG(log, "Read entry [page_id={}] without entry size.", page_id_v3); - Page page(page_id_v3); + Page page(Trait::PageIdTrait::getU64ID(page_id_v3)); return page; } @@ -837,7 +852,7 @@ Page BlobStore::read(const PageIDAndEntryV3 & id_entry, const ReadLimiterPtr & r } } - Page page(page_id_v3); + Page page(Trait::PageIdTrait::getU64ID(page_id_v3)); page.data = ByteBuffer(data_buf, data_buf + buf_size); page.mem_holder = mem_holder; @@ -851,7 +866,8 @@ Page BlobStore::read(const PageIDAndEntryV3 & id_entry, const ReadLimiterPtr & r return page; } -BlobFilePtr BlobStore::read(const PageIdV3Internal & page_id_v3, BlobFileId blob_id, BlobFileOffset offset, char * buffers, size_t size, const ReadLimiterPtr & read_limiter, bool background) +template +BlobFilePtr BlobStore::read(const typename BlobStore::PageId & page_id_v3, BlobFileId blob_id, BlobFileOffset offset, char * buffers, size_t size, const ReadLimiterPtr & read_limiter, bool background) { assert(buffers != nullptr); BlobFilePtr blob_file = getBlobFile(blob_id); @@ -959,7 +975,8 @@ struct BlobStoreGCInfo } }; -std::vector BlobStore::getGCStats() +template +std::vector BlobStore::getGCStats() { // Get a copy of stats map to avoid the big lock on stats map const auto stats_list = blob_stats.getStats(); @@ -1062,11 +1079,12 @@ std::vector BlobStore::getGCStats() return blob_need_gc; } - -PageEntriesEdit BlobStore::gc(std::map & entries_need_gc, - const PageSize & total_page_size, - const WriteLimiterPtr & write_limiter, - const ReadLimiterPtr & read_limiter) +template +typename BlobStore::PageEntriesEdit +BlobStore::gc(GcEntriesMap & entries_need_gc, + const PageSize & total_page_size, + const WriteLimiterPtr & write_limiter, + const ReadLimiterPtr & read_limiter) { std::vector> written_blobs; PageEntriesEdit edit; @@ -1214,8 +1232,8 @@ PageEntriesEdit BlobStore::gc(std::map & return edit; } - -String BlobStore::getBlobFileParentPath(BlobFileId blob_id) +template +String BlobStore::getBlobFileParentPath(BlobFileId blob_id) { PageFileIdAndLevel id_lvl{blob_id, 0}; String parent_path = delegator->getPageFilePath(id_lvl); @@ -1226,7 +1244,8 @@ String BlobStore::getBlobFileParentPath(BlobFileId blob_id) return parent_path; } -BlobFilePtr BlobStore::getBlobFile(BlobFileId blob_id) +template +BlobFilePtr BlobStore::getBlobFile(BlobFileId blob_id) { std::lock_guard files_gurad(mtx_blob_files); if (auto iter = blob_files.find(blob_id); iter != blob_files.end()) @@ -1236,5 +1255,7 @@ BlobFilePtr BlobStore::getBlobFile(BlobFileId blob_id) return file; } +template class BlobStore; +template class BlobStore; } // namespace PS::V3 } // namespace DB diff --git a/dbms/src/Storages/Page/V3/BlobStore.h b/dbms/src/Storages/Page/V3/BlobStore.h index 5c73692da86..fcbb936c648 100644 --- a/dbms/src/Storages/Page/V3/BlobStore.h +++ b/dbms/src/Storages/Page/V3/BlobStore.h @@ -18,12 +18,14 @@ #include #include #include -#include #include #include #include +#include +#include #include #include +#include #include #include #include @@ -40,12 +42,21 @@ extern const int LOGICAL_ERROR; namespace PS::V3 { -using PageIdAndVersionedEntries = std::vector>; - +template class BlobStore : private Allocator { public: - BlobStore(String storage_name, const FileProviderPtr & file_provider_, PSDiskDelegatorPtr delegator_, const BlobConfig & config); + using PageId = typename Trait::PageId; + using PageEntries = PageEntriesV3; + using PageEntriesEdit = DB::PS::V3::PageEntriesEdit; + using GcEntries = std::vector>; + using GcEntriesMap = std::map; + using PageIdAndEntry = std::pair; + using PageIdAndEntries = std::vector; + using PageMap = typename Trait::PageMap; + +public: + BlobStore(const String & storage_name, const FileProviderPtr & file_provider_, PSDiskDelegatorPtr delegator_, const BlobConfig & config); void registerPaths(); @@ -55,26 +66,26 @@ class BlobStore : private Allocator std::vector getGCStats(); - PageEntriesEdit gc(std::map & entries_need_gc, + PageEntriesEdit gc(GcEntriesMap & entries_need_gc, const PageSize & total_page_size, const WriteLimiterPtr & write_limiter = nullptr, const ReadLimiterPtr & read_limiter = nullptr); - PageEntriesEdit write(DB::WriteBatch & wb, const WriteLimiterPtr & write_limiter = nullptr); + PageEntriesEdit write(typename Trait::WriteBatch & wb, const WriteLimiterPtr & write_limiter = nullptr); - void remove(const PageEntriesV3 & del_entries); + void remove(const PageEntries & del_entries); - PageMap read(PageIDAndEntriesV3 & entries, const ReadLimiterPtr & read_limiter = nullptr); + PageMap read(PageIdAndEntries & entries, const ReadLimiterPtr & read_limiter = nullptr); - Page read(const PageIDAndEntryV3 & entry, const ReadLimiterPtr & read_limiter = nullptr); + Page read(const PageIdAndEntry & entry, const ReadLimiterPtr & read_limiter = nullptr); struct FieldReadInfo { - PageIdV3Internal page_id; + PageId page_id; PageEntryV3 entry; std::vector fields; - FieldReadInfo(PageIdV3Internal id_, PageEntryV3 entry_, std::vector fields_) + FieldReadInfo(const PageId & id_, PageEntryV3 entry_, std::vector fields_) : page_id(id_) , entry(entry_) , fields(std::move(fields_)) @@ -87,9 +98,9 @@ class BlobStore : private Allocator private: #endif - PageEntriesEdit handleLargeWrite(DB::WriteBatch & wb, const WriteLimiterPtr & write_limiter = nullptr); + PageEntriesEdit handleLargeWrite(typename Trait::WriteBatch & wb, const WriteLimiterPtr & write_limiter = nullptr); - BlobFilePtr read(const PageIdV3Internal & page_id_v3, BlobFileId blob_id, BlobFileOffset offset, char * buffers, size_t size, const ReadLimiterPtr & read_limiter = nullptr, bool background = false); + BlobFilePtr read(const PageId & page_id_v3, BlobFileId blob_id, BlobFileOffset offset, char * buffers, size_t size, const ReadLimiterPtr & read_limiter = nullptr, bool background = false); /** * Ask BlobStats to get a span from BlobStat. @@ -108,6 +119,7 @@ class BlobStore : private Allocator BlobFilePtr getBlobFile(BlobFileId blob_id); + template friend class PageDirectoryFactory; friend class PageStorageControlV3; @@ -127,7 +139,27 @@ class BlobStore : private Allocator std::mutex mtx_blob_files; std::unordered_map blob_files; }; -using BlobStorePtr = std::shared_ptr; - +namespace u128 +{ +struct BlobStoreTrait +{ + using PageId = PageIdV3Internal; + using PageMap = std::map; + using PageIdTrait = PageIdTrait; + using WriteBatch = DB::WriteBatch; +}; +using BlobStoreType = BlobStore; +} // namespace u128 +namespace universal +{ +struct BlobStoreTrait +{ + using PageId = UniversalPageId; + using PageMap = std::map; + using PageIdTrait = PageIdTrait; + using WriteBatch = UniversalWriteBatch; +}; +using BlobStoreType = BlobStore; +} // namespace universal } // namespace PS::V3 } // namespace DB diff --git a/dbms/src/Storages/Page/V3/GCDefines.cpp b/dbms/src/Storages/Page/V3/GCDefines.cpp new file mode 100644 index 00000000000..98d39de7a4c --- /dev/null +++ b/dbms/src/Storages/Page/V3/GCDefines.cpp @@ -0,0 +1,302 @@ +// 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 + + +namespace DB +{ +namespace FailPoints +{ +extern const char force_ps_wal_compact[]; +} +namespace PS::V3 +{ +String GCTimeStatistics::toLogging() const +{ + const std::string_view stage_suffix = [this]() { + switch (stage) + { + case GCStageType::Unknown: + return " "; + case GCStageType::OnlyInMem: + return " without full gc"; + case GCStageType::FullGCNothingMoved: + return " without moving any entry"; + case GCStageType::FullGC: + return ""; + } + }(); + const auto get_external_msg = [this]() -> String { + if (clean_external_page_ms == 0) + return String(""); + static constexpr double SCALE_NS_TO_MS = 1'000'000.0; + return fmt::format( + " [external_callbacks={}] [external_gc={}ms] [scanner={:.2f}ms] [get_alive={:.2f}ms] [remover={:.2f}ms]", + num_external_callbacks, + clean_external_page_ms, + external_page_scan_ns / SCALE_NS_TO_MS, + external_page_get_alive_ns / SCALE_NS_TO_MS, + external_page_remove_ns / SCALE_NS_TO_MS); + }; + return fmt::format("GC finished{}." + " [total time={}ms]" + " [compact wal={}ms] [compact directory={}ms] [compact spacemap={}ms]" + " [gc status={}ms] [gc entries={}ms] [gc data={}ms]" + " [gc apply={}ms]" + "{}", // a placeholder for external page gc at last + stage_suffix, + total_cost_ms, + compact_wal_ms, + compact_directory_ms, + compact_spacemap_ms, + full_gc_prepare_ms, + full_gc_get_entries_ms, + full_gc_blobstore_copy_ms, + full_gc_apply_ms, + get_external_msg()); +} + +void GCTimeStatistics::finishCleanExternalPage(UInt64 clean_cost_ms) +{ + clean_external_page_ms = clean_cost_ms; + GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_clean_external).Observe(clean_external_page_ms / 1000.0); +} + +template +void ExternalPageCallbacksManager::registerExternalPagesCallbacks(const ExternalPageCallbacks & callbacks) +{ + std::scoped_lock lock{callbacks_mutex}; + assert(callbacks.scanner != nullptr); + assert(callbacks.remover != nullptr); + if constexpr (std::is_same_v) + { + assert(callbacks.prefix != 0); + } + else if constexpr (std::is_same_v) + { + assert(callbacks.prefix != ""); + } + // NamespaceId(TableID) should not be reuse + RUNTIME_CHECK_MSG( + callbacks_container.count(callbacks.prefix) == 0, + "Try to create callbacks for duplicated prefix {}", + callbacks.prefix); + // `emplace` won't invalid other iterator + callbacks_container.emplace(callbacks.prefix, std::make_shared(callbacks)); +} + +template +void ExternalPageCallbacksManager::unregisterExternalPagesCallbacks(const Prefix & prefix) +{ + std::scoped_lock lock{callbacks_mutex}; + callbacks_container.erase(prefix); +} + +template +bool ExternalPageCallbacksManager::gc( + typename Trait::BlobStore & blob_store, + typename Trait::PageDirectory & page_directory, + const WriteLimiterPtr & write_limiter, + const ReadLimiterPtr & read_limiter, + LoggerPtr log) +{ + // If another thread is running gc, just return; + bool v = false; + if (!gc_is_running.compare_exchange_strong(v, true)) + return false; + + const GCTimeStatistics statistics = doGC(blob_store, page_directory, write_limiter, read_limiter); + assert(statistics.stage != GCStageType::Unknown); // `doGC` must set the stage + LOG_DEBUG(log, statistics.toLogging()); + + return statistics.executeNextImmediately(); +} + +// Remove external pages for all tables +// TODO: `clean_external_page` for all tables may slow down the whole gc process when there are lots of table. +template +void ExternalPageCallbacksManager::cleanExternalPage(PageDirectory & page_directory, Stopwatch & gc_watch, GCTimeStatistics & statistics) +{ + // Fine grained lock on `callbacks_mutex`. + // So that adding/removing a storage will not be blocked for the whole + // processing time of `cleanExternalPage`. + std::shared_ptr ns_callbacks; + { + std::scoped_lock lock{callbacks_mutex}; + // check and get the begin iter + statistics.num_external_callbacks = callbacks_container.size(); + auto iter = callbacks_container.begin(); + if (iter == callbacks_container.end()) // empty + { + statistics.finishCleanExternalPage(gc_watch.elapsedMillisecondsFromLastTime()); + return; + } + + assert(iter != callbacks_container.end()); // early exit in the previous code + // keep the shared_ptr so that erasing ns_id from PageStorage won't invalid the `ns_callbacks` + ns_callbacks = iter->second; + } + + Stopwatch external_watch; + + SYNC_FOR("before_PageStorageImpl::cleanExternalPage_execute_callbacks"); + + while (true) + { + // 1. Note that we must call `scanner` before `getAliveExternalIds`. + // Or some committed external ids is not included in `alive_ids` + // but exist in `pending_external_pages`. They will be removed by + // accident with `remover` under this situation. + // 2. Assume calling the callbacks after erasing ns_is is safe. + + // the external pages on disks. + auto pending_external_pages = ns_callbacks->scanner(); + statistics.external_page_scan_ns += external_watch.elapsedFromLastTime(); + auto alive_external_ids = page_directory.getAliveExternalIds(ns_callbacks->prefix); + statistics.external_page_get_alive_ns += external_watch.elapsedFromLastTime(); + if (alive_external_ids) + { + // remove the external pages that is not alive now. + ns_callbacks->remover(pending_external_pages, *alive_external_ids); + } // else the ns_id is invalid, just skip + statistics.external_page_remove_ns += external_watch.elapsedFromLastTime(); + + // move to next namespace callbacks + { + std::scoped_lock lock{callbacks_mutex}; + // next ns_id that is greater than `ns_id` + auto iter = callbacks_container.upper_bound(ns_callbacks->prefix); + if (iter == callbacks_container.end()) + break; + ns_callbacks = iter->second; + } + } + + statistics.finishCleanExternalPage(gc_watch.elapsedMillisecondsFromLastTime()); +} + +template +GCTimeStatistics ExternalPageCallbacksManager::doGC( + typename Trait::BlobStore & blob_store, + typename Trait::PageDirectory & page_directory, + const WriteLimiterPtr & write_limiter, + const ReadLimiterPtr & read_limiter) +{ + Stopwatch gc_watch; + SCOPE_EXIT({ + GET_METRIC(tiflash_storage_page_gc_count, type_v3).Increment(); + GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_v3).Observe(gc_watch.elapsedSeconds()); + bool is_running = true; + gc_is_running.compare_exchange_strong(is_running, false); + }); + + GCTimeStatistics statistics; + + // TODO: rewrite the GC process and split it into smaller interface + bool force_wal_compact = false; + fiu_do_on(FailPoints::force_ps_wal_compact, { force_wal_compact = true; }); + + // 1. Do the MVCC gc, clean up expired snapshot. + // And get the expired entries. + if (page_directory.tryDumpSnapshot(read_limiter, write_limiter, force_wal_compact)) + { + GET_METRIC(tiflash_storage_page_gc_count, type_v3_mvcc_dumped).Increment(); + } + statistics.compact_wal_ms = gc_watch.elapsedMillisecondsFromLastTime(); + GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_compact_wal).Observe(statistics.compact_wal_ms / 1000.0); + + const auto & del_entries = page_directory.gcInMemEntries(); + statistics.compact_directory_ms = gc_watch.elapsedMillisecondsFromLastTime(); + GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_compact_directory).Observe(statistics.compact_directory_ms / 1000.0); + + SYNC_FOR("before_PageStorageImpl::doGC_fullGC_prepare"); + + // 2. Remove the expired entries in BlobStore. + // It won't delete the data on the disk. + // It will only update the SpaceMap which in memory. + blob_store.remove(del_entries); + statistics.compact_spacemap_ms = gc_watch.elapsedMillisecondsFromLastTime(); + GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_compact_spacemap).Observe(statistics.compact_spacemap_ms / 1000.0); + + // Note that if full GC is not executed, below metrics won't be shown on grafana but it should + // only take few ms to fininsh these in-memory operations. Check them out by the logs if + // the total time cost not match. + + // 3. Check whether there are BlobFiles that need to do `full GC`. + // This function will also try to use `ftruncate` to reduce space amplification. + const auto & blob_ids_need_gc = blob_store.getGCStats(); + statistics.full_gc_prepare_ms = gc_watch.elapsedMillisecondsFromLastTime(); + if (blob_ids_need_gc.empty()) + { + cleanExternalPage(page_directory, gc_watch, statistics); + statistics.stage = GCStageType::OnlyInMem; + statistics.total_cost_ms = gc_watch.elapsedMilliseconds(); + return statistics; + } + + // Execute full gc + GET_METRIC(tiflash_storage_page_gc_count, type_v3_bs_full_gc).Increment(blob_ids_need_gc.size()); + // 4. Filter out entries in MVCC by BlobId. + // We also need to filter the version of the entry. + // So that the `gc_apply` can proceed smoothly. + auto [blob_gc_info, total_page_size] = page_directory.getEntriesByBlobIds(blob_ids_need_gc); + statistics.full_gc_get_entries_ms = gc_watch.elapsedMillisecondsFromLastTime(); + if (blob_gc_info.empty()) + { + cleanExternalPage(page_directory, gc_watch, statistics); + statistics.stage = GCStageType::FullGCNothingMoved; + statistics.total_cost_ms = gc_watch.elapsedMilliseconds(); + return statistics; + } + + SYNC_FOR("before_PageStorageImpl::doGC_fullGC_commit"); + + // 5. Do the BlobStore GC + // After BlobStore GC, these entries will be migrated to a new blob. + // Then we should notify MVCC apply the change. + PageEntriesEdit gc_edit = blob_store.gc(blob_gc_info, total_page_size, write_limiter, read_limiter); + statistics.full_gc_blobstore_copy_ms = gc_watch.elapsedMillisecondsFromLastTime(); + GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_fullgc_rewrite).Observe( // + (statistics.full_gc_prepare_ms + statistics.full_gc_get_entries_ms + statistics.full_gc_blobstore_copy_ms) / 1000.0); + RUNTIME_CHECK_MSG(!gc_edit.empty(), "Something wrong after BlobStore GC"); + + // 6. MVCC gc apply + // MVCC will apply the migrated entries. + // Also it will generate a new version for these entries. + // Note that if the process crash between step 5 and step 6, the stats in BlobStore will + // be reset to correct state during restore. If any exception thrown, then some BlobFiles + // will be remained as "read-only" files while entries in them are useless in actual. + // Those BlobFiles should be cleaned during next restore. + page_directory.gcApply(std::move(gc_edit), write_limiter); + statistics.full_gc_apply_ms = gc_watch.elapsedMillisecondsFromLastTime(); + GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_fullgc_commit).Observe(statistics.full_gc_apply_ms / 1000.0); + + SYNC_FOR("after_PageStorageImpl::doGC_fullGC_commit"); + + cleanExternalPage(page_directory, gc_watch, statistics); + statistics.stage = GCStageType::FullGC; + statistics.total_cost_ms = gc_watch.elapsedMilliseconds(); + return statistics; +} + +template class ExternalPageCallbacksManager; +template class ExternalPageCallbacksManager; +} // namespace PS::V3 +} // namespace DB diff --git a/dbms/src/Storages/Page/V3/GCDefines.h b/dbms/src/Storages/Page/V3/GCDefines.h new file mode 100644 index 00000000000..23ea94c5034 --- /dev/null +++ b/dbms/src/Storages/Page/V3/GCDefines.h @@ -0,0 +1,132 @@ +// 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 +#include +#include +#include + +namespace DB::PS::V3 +{ +enum class GCStageType +{ + Unknown, + OnlyInMem, + FullGCNothingMoved, + FullGC, +}; +struct GCTimeStatistics +{ + GCStageType stage = GCStageType::Unknown; + bool executeNextImmediately() const { return stage == GCStageType::FullGC; }; + + UInt64 total_cost_ms = 0; + + UInt64 compact_wal_ms = 0; + UInt64 compact_directory_ms = 0; + UInt64 compact_spacemap_ms = 0; + // Full GC + UInt64 full_gc_prepare_ms = 0; + UInt64 full_gc_get_entries_ms = 0; + UInt64 full_gc_blobstore_copy_ms = 0; + UInt64 full_gc_apply_ms = 0; + + // GC external page + UInt64 num_external_callbacks = 0; + // Breakdown the duration for cleaning external pages + // ms is usually too big for these operation, store by ns (10^-9) + UInt64 external_page_scan_ns = 0; + UInt64 external_page_get_alive_ns = 0; + UInt64 external_page_remove_ns = 0; + +private: + // Total time of cleaning external pages + UInt64 clean_external_page_ms = 0; + +public: + void finishCleanExternalPage(UInt64 clean_cost_ms); + + String toLogging() const; +}; + +template +class ExternalPageCallbacksManager +{ +public: + using PageId = typename Trait::PageId; + using Prefix = typename Trait::Prefix; + using PageEntriesEdit = DB::PS::V3::PageEntriesEdit; + using ExternalPageCallbacks = typename Trait::ExternalPageCallbacks; + using BlobStore = typename Trait::BlobStore; + using PageDirectory = typename Trait::PageDirectory; + +public: + void registerExternalPagesCallbacks(const ExternalPageCallbacks & callbacks); + + void unregisterExternalPagesCallbacks(const Prefix & prefix); + + bool gc( + typename Trait::BlobStore & blob_store, + typename Trait::PageDirectory & page_directory, + const WriteLimiterPtr & write_limiter, + const ReadLimiterPtr & read_limiter, + LoggerPtr log); + +private: + void cleanExternalPage(PageDirectory & page_directory, Stopwatch & gc_watch, GCTimeStatistics & statistics); + + GCTimeStatistics doGC( + typename Trait::BlobStore & blob_store, + typename Trait::PageDirectory & page_directory, + const WriteLimiterPtr & write_limiter, + const ReadLimiterPtr & read_limiter); + +private: + std::atomic gc_is_running = false; + + std::mutex callbacks_mutex; + // Only std::map not std::unordered_map. We need insert/erase do not invalid other iterators. + using ExternalPageCallbacksContainer = std::map>; + ExternalPageCallbacksContainer callbacks_container; +}; + +namespace u128 +{ +struct ExternalPageCallbacksManagerTrait +{ + using PageId = PageIdV3Internal; + using Prefix = NamespaceId; + using ExternalPageCallbacks = DB::ExternalPageCallbacks; + using PageDirectory = PageDirectoryType; + using BlobStore = BlobStoreType; +}; +using ExternalPageCallbacksManager = ExternalPageCallbacksManager; +} // namespace u128 +namespace universal +{ +struct ExternalPageCallbacksManagerTrait +{ + using PageId = UniversalPageId; + using Prefix = String; + using ExternalPageCallbacks = UniversalExternalPageCallbacks; + using PageDirectory = PageDirectoryType; + using BlobStore = BlobStoreType; +}; +using ExternalPageCallbacksManager = ExternalPageCallbacksManager; +} // namespace universal +} // namespace DB::PS::V3 diff --git a/dbms/src/Storages/Page/V3/PageDefines.h b/dbms/src/Storages/Page/V3/PageDefines.h new file mode 100644 index 00000000000..7ab1206211a --- /dev/null +++ b/dbms/src/Storages/Page/V3/PageDefines.h @@ -0,0 +1,25 @@ +// 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 + +namespace DB +{ +using BlobFileId = UInt64; +using BlobFileOffset = UInt64; +static constexpr BlobFileId INVALID_BLOBFILE_ID = 0; +static constexpr BlobFileOffset INVALID_BLOBFILE_OFFSET = std::numeric_limits::max(); +} // namespace DB diff --git a/dbms/src/Storages/Page/V3/PageDirectory.cpp b/dbms/src/Storages/Page/V3/PageDirectory.cpp index 9fc19f3b6a3..dfb9f1c740c 100644 --- a/dbms/src/Storages/Page/V3/PageDirectory.cpp +++ b/dbms/src/Storages/Page/V3/PageDirectory.cpp @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -40,10 +40,10 @@ #ifdef FIU_ENABLE -#include - -#include #include + +#include "Common/randomSeed.h" +#include "pcg_random.hpp" #endif // FIU_ENABLE namespace CurrentMetrics @@ -73,7 +73,8 @@ namespace PS::V3 * VersionedPageEntries methods * ********************************/ -void VersionedPageEntries::createNewEntry(const PageVersion & ver, const PageEntryV3 & entry) +template +void VersionedPageEntries::createNewEntry(const PageVersion & ver, const PageEntryV3 & entry) { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_DELETE) @@ -124,7 +125,8 @@ void VersionedPageEntries::createNewEntry(const PageVersion & ver, const PageEnt ErrorCodes::PS_DIR_APPLY_INVALID_STATUS); } -PageIdV3Internal VersionedPageEntries::createUpsertEntry(const PageVersion & ver, const PageEntryV3 & entry) +template +typename VersionedPageEntries::PageId VersionedPageEntries::createUpsertEntry(const PageVersion & ver, const PageEntryV3 & entry) { auto page_lock = acquireLock(); @@ -159,7 +161,7 @@ PageIdV3Internal VersionedPageEntries::createUpsertEntry(const PageVersion & ver // create a new version that inherit the `being_ref_count` of the last entry entries.emplace(ver, EntryOrDelete::newReplacingEntry(last_iter->second, entry)); } - return buildV3Id(0, INVALID_PAGE_ID); + return Trait::PageIdTrait::getInvalidID(); } if (type == EditRecordType::VAR_REF) @@ -204,7 +206,8 @@ PageIdV3Internal VersionedPageEntries::createUpsertEntry(const PageVersion & ver // Create a new external version with version=`ver`. // If create success, then return a shared_ptr as a holder for page_id. The holder // will be release when this external version is totally removed. -std::shared_ptr VersionedPageEntries::createNewExternal(const PageVersion & ver) +template +std::shared_ptr::PageId> VersionedPageEntries::createNewExternal(const PageVersion & ver) { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_DELETE) @@ -215,7 +218,7 @@ std::shared_ptr VersionedPageEntries::createNewExternal(const delete_ver = PageVersion(0); being_ref_count = 1; // return the new created holder to caller to set the page_id - external_holder = std::make_shared(0, 0); + external_holder = std::make_shared(); return external_holder; } @@ -231,7 +234,7 @@ std::shared_ptr VersionedPageEntries::createNewExternal(const delete_ver = PageVersion(0); being_ref_count = 1; // return the new created holder to caller to set the page_id - external_holder = std::make_shared(0, 0); + external_holder = std::make_shared(); return external_holder; } else @@ -257,7 +260,8 @@ std::shared_ptr VersionedPageEntries::createNewExternal(const } // Create a new delete version with version=`ver`. -void VersionedPageEntries::createDelete(const PageVersion & ver) +template +void VersionedPageEntries::createDelete(const PageVersion & ver) { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_ENTRY) @@ -292,7 +296,8 @@ void VersionedPageEntries::createDelete(const PageVersion & ver) // Create a new reference version with version=`ver` and `ori_page_id_`. // If create success, then return true, otherwise return false. -bool VersionedPageEntries::createNewRef(const PageVersion & ver, PageIdV3Internal ori_page_id_) +template +bool VersionedPageEntries::createNewRef(const PageVersion & ver, const PageId & ori_page_id_) { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_DELETE) @@ -345,7 +350,8 @@ bool VersionedPageEntries::createNewRef(const PageVersion & ver, PageIdV3Interna ErrorCodes::PS_DIR_APPLY_INVALID_STATUS); } -std::shared_ptr VersionedPageEntries::fromRestored(const PageEntriesEdit::EditRecord & rec) +template +std::shared_ptr::PageId> VersionedPageEntries::fromRestored(const typename PageEntriesEdit::EditRecord & rec) { auto page_lock = acquireLock(); switch (rec.type) @@ -364,7 +370,7 @@ std::shared_ptr VersionedPageEntries::fromRestored(const PageE is_deleted = false; create_ver = rec.version; being_ref_count = rec.being_ref_count; - external_holder = std::make_shared(rec.page_id); + external_holder = std::make_shared(rec.page_id); return external_holder; } case EditRecordType::VAR_ENTRY: @@ -380,8 +386,9 @@ std::shared_ptr VersionedPageEntries::fromRestored(const PageE } } -std::tuple -VersionedPageEntries::resolveToPageId(UInt64 seq, bool ignore_delete, PageEntryV3 * entry) +template +std::tuple::PageId, PageVersion> +VersionedPageEntries::resolveToPageId(UInt64 seq, bool ignore_delete, PageEntryV3 * entry) { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_ENTRY) @@ -393,7 +400,7 @@ VersionedPageEntries::resolveToPageId(UInt64 seq, bool ignore_delete, PageEntryV if (!ignore_delete && iter->second.isDelete()) { // the page is not visible - return {ResolveResult::FAIL, buildV3Id(0, 0), PageVersion(0)}; + return {ResolveResult::FAIL, Trait::PageIdTrait::getInvalidID(), PageVersion(0)}; } // If `ignore_delete` is true, we need the page entry even if it is logical deleted. @@ -410,7 +417,7 @@ VersionedPageEntries::resolveToPageId(UInt64 seq, bool ignore_delete, PageEntryV // copy and return the entry if (entry != nullptr) *entry = iter->second.entry; - return {ResolveResult::TO_NORMAL, buildV3Id(0, 0), PageVersion(0)}; + return {ResolveResult::TO_NORMAL, Trait::PageIdTrait::getInvalidID(), PageVersion(0)}; } // else fallthrough to FAIL } // else fallthrough to FAIL @@ -422,7 +429,7 @@ VersionedPageEntries::resolveToPageId(UInt64 seq, bool ignore_delete, PageEntryV bool ok = ignore_delete || (!is_deleted || seq < delete_ver.sequence); if (create_ver.sequence <= seq && ok) { - return {ResolveResult::TO_NORMAL, buildV3Id(0, 0), PageVersion(0)}; + return {ResolveResult::TO_NORMAL, Trait::PageIdTrait::getInvalidID(), PageVersion(0)}; } } else if (type == EditRecordType::VAR_REF) @@ -438,10 +445,11 @@ VersionedPageEntries::resolveToPageId(UInt64 seq, bool ignore_delete, PageEntryV LOG_WARNING(&Poco::Logger::get("VersionedPageEntries"), "Can't resolve the EditRecordType {}", static_cast(type)); } - return {ResolveResult::FAIL, buildV3Id(0, 0), PageVersion(0)}; + return {ResolveResult::FAIL, Trait::PageIdTrait::getInvalidID(), PageVersion(0)}; } -std::optional VersionedPageEntries::getEntry(UInt64 seq) const +template +std::optional VersionedPageEntries::getEntry(UInt64 seq) const { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_ENTRY) @@ -458,7 +466,8 @@ std::optional VersionedPageEntries::getEntry(UInt64 seq) const return std::nullopt; } -std::optional VersionedPageEntries::getLastEntry(std::optional seq) const +template +std::optional VersionedPageEntries::getLastEntry(std::optional seq) const { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_ENTRY) @@ -479,7 +488,8 @@ std::optional VersionedPageEntries::getLastEntry(std::optional +bool VersionedPageEntries::isVisible(UInt64 seq) const { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_DELETE) @@ -512,7 +522,8 @@ bool VersionedPageEntries::isVisible(UInt64 seq) const ErrorCodes::LOGICAL_ERROR); } -Int64 VersionedPageEntries::incrRefCount(const PageVersion & ver) +template +Int64 VersionedPageEntries::incrRefCount(const PageVersion & ver) { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_ENTRY) @@ -549,11 +560,12 @@ Int64 VersionedPageEntries::incrRefCount(const PageVersion & ver) throw Exception(fmt::format("The entry to be added ref count is not found [ver={}] [state={}]", ver, toDebugString()), ErrorCodes::LOGICAL_ERROR); } -PageSize VersionedPageEntries::getEntriesByBlobIds( +template +PageSize VersionedPageEntries::getEntriesByBlobIds( const std::unordered_set & blob_ids, - PageIdV3Internal page_id, - std::map & blob_versioned_entries, - std::map> & ref_ids_maybe_rewrite) + const PageId & page_id, + GcEntriesMap & blob_versioned_entries, + std::map> & ref_ids_maybe_rewrite) { // `blob_versioned_entries`: // blob_file_0, [, @@ -596,9 +608,10 @@ PageSize VersionedPageEntries::getEntriesByBlobIds( return entry_size_full_gc; } -bool VersionedPageEntries::cleanOutdatedEntries( +template +bool VersionedPageEntries::cleanOutdatedEntries( UInt64 lowest_seq, - std::map> * normal_entries_to_deref, + std::map> * normal_entries_to_deref, PageEntriesV3 * entries_removed, const PageLock & /*page_lock*/) { @@ -642,7 +655,7 @@ bool VersionedPageEntries::cleanOutdatedEntries( auto iter = MapUtils::findLess(entries, PageVersion(lowest_seq + 1)); // If we can't find any seq lower than `lowest_seq` then // all version in this list don't need gc. - if (iter == entries.begin() || iter == entries.end()) + if (iter == entries.begin() || iter == entries.end()) // NOLINT(misc-redundant-expression) { return false; } @@ -696,7 +709,13 @@ bool VersionedPageEntries::cleanOutdatedEntries( return entries.empty() || (entries.size() == 1 && entries.begin()->second.isDelete()); } -bool VersionedPageEntries::derefAndClean(UInt64 lowest_seq, PageIdV3Internal page_id, const PageVersion & deref_ver, const Int64 deref_count, PageEntriesV3 * entries_removed) +template +bool VersionedPageEntries::derefAndClean( + UInt64 lowest_seq, + const typename Trait::PageId & page_id, + const PageVersion & deref_ver, + const Int64 deref_count, + PageEntriesV3 * entries_removed) { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_EXTERNAL) @@ -745,7 +764,8 @@ bool VersionedPageEntries::derefAndClean(UInt64 lowest_seq, PageIdV3Internal pag throw Exception(fmt::format("calling derefAndClean with invalid state [state={}]", toDebugString())); } -void VersionedPageEntries::collapseTo(const UInt64 seq, const PageIdV3Internal page_id, PageEntriesEdit & edit) +template +void VersionedPageEntries::collapseTo(const UInt64 seq, const PageId & page_id, PageEntriesEdit & edit) { auto page_lock = acquireLock(); if (type == EditRecordType::VAR_REF) @@ -831,7 +851,8 @@ void VersionedPageEntries::collapseTo(const UInt64 seq, const PageIdV3Internal p * PageDirectory methods * *************************/ -PageDirectory::PageDirectory(String storage_name, WALStorePtr && wal_, UInt64 max_persisted_log_files_) +template +PageDirectory::PageDirectory(String storage_name, WALStorePtr && wal_, UInt64 max_persisted_log_files_) : max_page_id(0) , sequence(0) , wal(std::move(wal_)) @@ -840,7 +861,8 @@ PageDirectory::PageDirectory(String storage_name, WALStorePtr && wal_, UInt64 ma { } -PageDirectorySnapshotPtr PageDirectory::createSnapshot(const String & tracing_id) const +template +PageDirectorySnapshotPtr PageDirectory::createSnapshot(const String & tracing_id) const { auto snap = std::make_shared(sequence.load(), tracing_id); { @@ -852,7 +874,8 @@ PageDirectorySnapshotPtr PageDirectory::createSnapshot(const String & tracing_id return snap; } -SnapshotsStatistics PageDirectory::getSnapshotsStat() const +template +SnapshotsStatistics PageDirectory::getSnapshotsStat() const { SnapshotsStatistics stat; DB::Int64 num_snapshots_removed = 0; @@ -892,7 +915,8 @@ SnapshotsStatistics PageDirectory::getSnapshotsStat() const return stat; } -PageIDAndEntryV3 PageDirectory::getByIDImpl(PageIdV3Internal page_id, const PageDirectorySnapshotPtr & snap, bool throw_on_not_exist) const +template +typename PageDirectory::PageIdAndEntry PageDirectory::getByIDImpl(const PageId & page_id, const PageDirectorySnapshotPtr & snap, bool throw_on_not_exist) const { PageEntryV3 entry_got; @@ -924,12 +948,12 @@ PageIDAndEntryV3 PageDirectory::getByIDImpl(PageIdV3Internal page_id, const Page // resolve ref id 11 to 10 with seq=2, and continue to ignore all "delete"s in the version chain in // page 10 until we find the "entryX". - PageIdV3Internal id_to_resolve = page_id; + PageId id_to_resolve = page_id; PageVersion ver_to_resolve(snap->sequence, 0); bool ok = true; while (ok) { - MVCCMapType::const_iterator iter; + typename MVCCMapType::const_iterator iter; { std::shared_lock read_lock(table_rw_mutex); iter = mvcc_table_directory.find(id_to_resolve); @@ -946,7 +970,7 @@ PageIDAndEntryV3 PageDirectory::getByIDImpl(PageIdV3Internal page_id, const Page } else { - return PageIDAndEntryV3{page_id, PageEntryV3{.file_id = INVALID_BLOBFILE_ID}}; + return PageIdAndEntry{page_id, PageEntryV3{.file_id = INVALID_BLOBFILE_ID}}; } } } @@ -954,7 +978,7 @@ PageIDAndEntryV3 PageDirectory::getByIDImpl(PageIdV3Internal page_id, const Page switch (resolve_state) { case ResolveResult::TO_NORMAL: - return PageIDAndEntryV3(page_id, entry_got); + return PageIdAndEntry(page_id, entry_got); case ResolveResult::FAIL: ok = false; break; @@ -979,22 +1003,24 @@ PageIDAndEntryV3 PageDirectory::getByIDImpl(PageIdV3Internal page_id, const Page } else { - return PageIDAndEntryV3{page_id, PageEntryV3{.file_id = INVALID_BLOBFILE_ID}}; + return PageIdAndEntry{page_id, PageEntryV3{.file_id = INVALID_BLOBFILE_ID}}; } } -std::pair PageDirectory::getByIDsImpl(const PageIdV3Internals & page_ids, const PageDirectorySnapshotPtr & snap, bool throw_on_not_exist) const +template +std::pair::PageIdAndEntries, typename PageDirectory::PageIds> +PageDirectory::getByIDsImpl(const typename PageDirectory::PageIds & page_ids, const PageDirectorySnapshotPtr & snap, bool throw_on_not_exist) const { PageEntryV3 entry_got; PageIds page_not_found = {}; const PageVersion init_ver_to_resolve(snap->sequence, 0); - auto get_one = [&entry_got, init_ver_to_resolve, throw_on_not_exist, this](PageIdV3Internal page_id, PageVersion ver_to_resolve, size_t idx) { - PageIdV3Internal id_to_resolve = page_id; + auto get_one = [&entry_got, init_ver_to_resolve, throw_on_not_exist, this](PageId page_id, PageVersion ver_to_resolve, size_t idx) { + PageId id_to_resolve = page_id; bool ok = true; while (ok) { - MVCCMapType::const_iterator iter; + typename MVCCMapType::const_iterator iter; { std::shared_lock read_lock(table_rw_mutex); iter = mvcc_table_directory.find(id_to_resolve); @@ -1040,7 +1066,7 @@ std::pair PageDirectory::getByIDsImpl(const PageIdV } }; - PageIDAndEntriesV3 id_entries; + PageIdAndEntries id_entries; for (size_t idx = 0; idx < page_ids.size(); ++idx) { if (auto ok = get_one(page_ids[idx], init_ver_to_resolve, idx); ok) @@ -1056,15 +1082,16 @@ std::pair PageDirectory::getByIDsImpl(const PageIdV return std::make_pair(id_entries, page_not_found); } -PageIdV3Internal PageDirectory::getNormalPageId(PageIdV3Internal page_id, const DB::PageStorageSnapshotPtr & snap_, bool throw_on_not_exist) const +template +typename PageDirectory::PageId PageDirectory::getNormalPageId(const typename PageDirectory::PageId & page_id, const DB::PageStorageSnapshotPtr & snap_, bool throw_on_not_exist) const { auto snap = toConcreteSnapshot(snap_); - PageIdV3Internal id_to_resolve = page_id; + PageId id_to_resolve = page_id; PageVersion ver_to_resolve(snap->sequence, 0); bool keep_resolve = true; while (keep_resolve) { - MVCCMapType::const_iterator iter; + typename MVCCMapType::const_iterator iter; { std::shared_lock read_lock(table_rw_mutex); iter = mvcc_table_directory.find(id_to_resolve); @@ -1076,7 +1103,7 @@ PageIdV3Internal PageDirectory::getNormalPageId(PageIdV3Internal page_id, const } else { - return buildV3Id(0, INVALID_PAGE_ID); + return Trait::PageIdTrait::getInvalidID(); } } } @@ -1113,19 +1140,21 @@ PageIdV3Internal PageDirectory::getNormalPageId(PageIdV3Internal page_id, const } else { - return buildV3Id(0, INVALID_PAGE_ID); + return Trait::PageIdTrait::getInvalidID(); } } -PageId PageDirectory::getMaxId() const +template +UInt64 PageDirectory::getMaxId() const { std::shared_lock read_lock(table_rw_mutex); return max_page_id; } -std::set PageDirectory::getAllPageIds() +template +typename PageDirectory::PageIdSet PageDirectory::getAllPageIds() { - std::set page_ids; + std::set page_ids; std::shared_lock read_lock(table_rw_mutex); const auto seq = sequence.load(); @@ -1138,10 +1167,38 @@ std::set PageDirectory::getAllPageIds() return page_ids; } -void PageDirectory::applyRefEditRecord( +template +typename PageDirectory::PageIdSet PageDirectory::getAllPageIdsWithPrefix(const String & prefix, const DB::PageStorageSnapshotPtr & snap_) +{ + UNUSED(snap_); + if constexpr (std::is_same_v) + { + PageIdSet page_ids; + auto seq = toConcreteSnapshot(snap_)->sequence; + std::shared_lock read_lock(table_rw_mutex); + for (auto iter = mvcc_table_directory.lower_bound(prefix); + iter != mvcc_table_directory.end(); + ++iter) + { + if (!iter->first.isPrefix(prefix)) + break; + // Only return the page_id that is visible + if (iter->second->isVisible(seq)) + page_ids.insert(iter->first); + } + return page_ids; + } + else + { + throw Exception("", ErrorCodes::NOT_IMPLEMENTED); + } +} + +template +void PageDirectory::applyRefEditRecord( MVCCMapType & mvcc_table_directory, const VersionedPageEntriesPtr & version_list, - const PageEntriesEdit::EditRecord & rec, + const typename PageEntriesEdit::EditRecord & rec, const PageVersion & version) { // Assume the `mvcc_table_directory` is: @@ -1175,13 +1232,13 @@ void PageDirectory::applyRefEditRecord( // non-collapse ref chain is much harder and long ref chain make the time of accessing an entry // not stable. - auto [resolve_success, resolved_id, resolved_ver] = [&mvcc_table_directory, ori_page_id = rec.ori_page_id](PageIdV3Internal id_to_resolve, PageVersion ver_to_resolve) - -> std::tuple { + auto [resolve_success, resolved_id, resolved_ver] = [&mvcc_table_directory, ori_page_id = rec.ori_page_id](PageId id_to_resolve, PageVersion ver_to_resolve) + -> std::tuple { while (true) { auto resolve_ver_iter = mvcc_table_directory.find(id_to_resolve); if (resolve_ver_iter == mvcc_table_directory.end()) - return {false, buildV3Id(0, 0), PageVersion(0)}; + return {false, Trait::PageIdTrait::getInvalidID(), PageVersion(0)}; const VersionedPageEntriesPtr & resolve_version_list = resolve_ver_iter->second; auto [resolve_state, next_id_to_resolve, next_ver_to_resolve] = resolve_version_list->resolveToPageId( @@ -1242,7 +1299,8 @@ void PageDirectory::applyRefEditRecord( SYNC_FOR("after_PageDirectory::applyRefEditRecord_incr_ref_count"); } -void PageDirectory::apply(PageEntriesEdit && edit, const WriteLimiterPtr & write_limiter) +template +void PageDirectory::apply(PageEntriesEdit && edit, const WriteLimiterPtr & write_limiter) { // We need to make sure there is only one apply thread to write wal and then increase `sequence`. // Note that, as read threads use current `sequence` as read_seq, we cannot increase `sequence` @@ -1270,7 +1328,7 @@ void PageDirectory::apply(PageEntriesEdit && edit, const WriteLimiterPtr & write r.version = PageVersion(max_sequence, 0); } - wal->apply(ser::serializeTo(edit), write_limiter); + wal->apply(Trait::Serializer::serializeTo(edit), write_limiter); GET_METRIC(tiflash_storage_page_write_duration_seconds, type_wal).Observe(watch.elapsedSeconds()); watch.restart(); SCOPE_EXIT({ GET_METRIC(tiflash_storage_page_write_duration_seconds, type_commit).Observe(watch.elapsedSeconds()); }); @@ -1282,12 +1340,12 @@ void PageDirectory::apply(PageEntriesEdit && edit, const WriteLimiterPtr & write for (const auto & r : edit.getRecords()) { // Protected in write_lock - max_page_id = std::max(max_page_id, r.page_id.low); + max_page_id = std::max(max_page_id, Trait::PageIdTrait::getU64ID(r.page_id)); auto [iter, created] = mvcc_table_directory.insert(std::make_pair(r.page_id, nullptr)); if (created) { - iter->second = std::make_shared(); + iter->second = std::make_shared>(); } auto & version_list = iter->second; @@ -1335,7 +1393,8 @@ void PageDirectory::apply(PageEntriesEdit && edit, const WriteLimiterPtr & write } } -void PageDirectory::gcApply(PageEntriesEdit && migrated_edit, const WriteLimiterPtr & write_limiter) +template +void PageDirectory::gcApply(PageEntriesEdit && migrated_edit, const WriteLimiterPtr & write_limiter) { // Increase the epoch for migrated records for (auto & record : migrated_edit.getMutRecords()) @@ -1344,12 +1403,12 @@ void PageDirectory::gcApply(PageEntriesEdit && migrated_edit, const WriteLimiter } // Apply migrate edit into WAL with the increased epoch version - wal->apply(ser::serializeTo(migrated_edit), write_limiter); + wal->apply(Trait::Serializer::serializeTo(migrated_edit), write_limiter); // Apply migrate edit to the mvcc map for (const auto & record : migrated_edit.getRecords()) { - MVCCMapType::const_iterator iter; + typename MVCCMapType::const_iterator iter; { std::shared_lock read_lock(table_rw_mutex); iter = mvcc_table_directory.find(record.page_id); @@ -1359,10 +1418,10 @@ void PageDirectory::gcApply(PageEntriesEdit && migrated_edit, const WriteLimiter // Append the gc version to version list const auto & versioned_entries = iter->second; auto id_to_deref = versioned_entries->createUpsertEntry(record.version, record.entry); - if (id_to_deref.low != INVALID_PAGE_ID) + if (id_to_deref != Trait::PageIdTrait::getInvalidID()) { // The ref-page is rewritten into a normal page, we need to decrease the ref-count of original page - MVCCMapType::const_iterator deref_iter; + typename MVCCMapType::const_iterator deref_iter; { std::shared_lock read_lock(table_rw_mutex); deref_iter = mvcc_table_directory.find(id_to_deref); @@ -1376,8 +1435,9 @@ void PageDirectory::gcApply(PageEntriesEdit && migrated_edit, const WriteLimiter LOG_INFO(log, "GC apply done. [edit size={}]", migrated_edit.size()); } -std::pair, PageSize> -PageDirectory::getEntriesByBlobIds(const std::vector & blob_ids) const +template +std::pair::GcEntriesMap, PageSize> +PageDirectory::getEntriesByBlobIds(const std::vector & blob_ids) const { std::unordered_set blob_id_set; for (const auto blob_id : blob_ids) @@ -1385,13 +1445,13 @@ PageDirectory::getEntriesByBlobIds(const std::vector & blob_ids) con assert(blob_id_set.size() == blob_ids.size()); // TODO: return the max entry.size to make `BlobStore::gc` more clean - std::map blob_versioned_entries; + typename PageDirectory::GcEntriesMap blob_versioned_entries; PageSize total_page_size = 0; UInt64 total_page_nums = 0; - std::map> ref_ids_maybe_rewrite; + std::map> ref_ids_maybe_rewrite; { - MVCCMapType::const_iterator iter; + typename MVCCMapType::const_iterator iter; { std::shared_lock read_lock(table_rw_mutex); iter = mvcc_table_directory.cbegin(); @@ -1406,8 +1466,11 @@ PageDirectory::getEntriesByBlobIds(const std::vector & blob_ids) con auto page_id = iter->first; const auto & version_entries = iter->second; fiu_do_on(FailPoints::pause_before_full_gc_prepare, { - if (page_id.low == 101) - SYNC_FOR("before_PageDirectory::getEntriesByBlobIds_id_101"); + if constexpr (std::is_same_v) + { + if (page_id.low == 101) + SYNC_FOR("before_PageDirectory::getEntriesByBlobIds_id_101"); + } }); auto single_page_size = version_entries->getEntriesByBlobIds(blob_id_set, page_id, blob_versioned_entries, ref_ids_maybe_rewrite); total_page_size += single_page_size; @@ -1432,7 +1495,7 @@ PageDirectory::getEntriesByBlobIds(const std::vector & blob_ids) con { const auto ori_id = std::get<0>(ori_id_ver); const auto ver = std::get<1>(ori_id_ver); - MVCCMapType::const_iterator page_iter; + typename MVCCMapType::const_iterator page_iter; { std::shared_lock read_lock(table_rw_mutex); page_iter = mvcc_table_directory.find(ori_id); @@ -1460,7 +1523,8 @@ PageDirectory::getEntriesByBlobIds(const std::vector & blob_ids) con return std::make_pair(std::move(blob_versioned_entries), total_page_size); } -bool PageDirectory::tryDumpSnapshot(const ReadLimiterPtr & read_limiter, const WriteLimiterPtr & write_limiter, bool force) +template +bool PageDirectory::tryDumpSnapshot(const ReadLimiterPtr & read_limiter, const WriteLimiterPtr & write_limiter, bool force) { // Only apply compact logs when files snapshot is valid auto files_snap = wal->tryGetFilesSnapshot(max_persisted_log_files, force); @@ -1475,20 +1539,38 @@ bool PageDirectory::tryDumpSnapshot(const ReadLimiterPtr & read_limiter, const W auto log_num = files_snap.persisted_log_files.rbegin()->log_num; auto identifier = fmt::format("{}.dump_{}", wal->name(), log_num); auto snapshot_reader = wal->createReaderForFiles(identifier, files_snap.persisted_log_files, read_limiter); - PageDirectoryFactory factory; // we just use the `collapsed_dir` to dump edit of the snapshot, should never call functions like `apply` that // persist new logs into disk. So we pass `nullptr` as `wal` to the factory. - PageDirectoryPtr collapsed_dir = factory.createFromReader( - identifier, - std::move(snapshot_reader), - /* wal */ nullptr); + auto collapsed_dir = [&]() { + // we just use the `collapsed_dir` to dump edit of the snapshot, should never call functions like `apply` that + // persist new logs into disk. So we pass `nullptr` as `wal` to the factory. + static_assert(std::is_same_v || std::is_same_v, + "unknown impl"); + if constexpr (std::is_same_v) + { + u128::PageDirectoryFactory factory; + return factory.createFromReader( + identifier, + std::move(snapshot_reader), + /* wal */ nullptr); + } + else if constexpr (std::is_same_v) + { + universal::PageDirectoryFactory factory; + return factory.createFromReader( + identifier, + std::move(snapshot_reader), + /* wal */ nullptr); + } + }(); // The records persisted in `files_snap` is older than or equal to all records in `edit` auto edit_from_disk = collapsed_dir->dumpSnapshotToEdit(); - bool done_any_io = wal->saveSnapshot(std::move(files_snap), ser::serializeTo(edit_from_disk), edit_from_disk.size(), write_limiter); + bool done_any_io = wal->saveSnapshot(std::move(files_snap), Trait::Serializer::serializeTo(edit_from_disk), edit_from_disk.size(), write_limiter); return done_any_io; } -PageEntriesV3 PageDirectory::gcInMemEntries(bool return_removed_entries) +template +typename PageDirectory::PageEntries PageDirectory::gcInMemEntries(bool return_removed_entries) { UInt64 lowest_seq = sequence.load(); @@ -1530,7 +1612,7 @@ PageEntriesV3 PageDirectory::gcInMemEntries(bool return_removed_entries) } PageEntriesV3 all_del_entries; - MVCCMapType::iterator iter; + typename MVCCMapType::iterator iter; { std::shared_lock read_lock(table_rw_mutex); iter = mvcc_table_directory.begin(); @@ -1543,7 +1625,7 @@ PageEntriesV3 PageDirectory::gcInMemEntries(bool return_removed_entries) // The page_id that we need to decrease ref count // { id_0: , id_1: <...>, ... } - std::map> normal_entries_to_deref; + std::map> normal_entries_to_deref; // Iterate all page_id and try to clean up useless var entries while (true) { @@ -1578,7 +1660,7 @@ PageEntriesV3 PageDirectory::gcInMemEntries(bool return_removed_entries) // Iterate all page_id that need to decrease ref count of specified version. for (const auto & [page_id, deref_counter] : normal_entries_to_deref) { - MVCCMapType::iterator iter; + typename MVCCMapType::iterator iter; { std::shared_lock read_lock(table_rw_mutex); iter = mvcc_table_directory.find(page_id); @@ -1622,7 +1704,8 @@ PageEntriesV3 PageDirectory::gcInMemEntries(bool return_removed_entries) return all_del_entries; } -PageEntriesEdit PageDirectory::dumpSnapshotToEdit(PageDirectorySnapshotPtr snap) +template +typename PageDirectory::PageEntriesEdit PageDirectory::dumpSnapshotToEdit(PageDirectorySnapshotPtr snap) { if (!snap) { @@ -1630,7 +1713,7 @@ PageEntriesEdit PageDirectory::dumpSnapshotToEdit(PageDirectorySnapshotPtr snap) } PageEntriesEdit edit; - MVCCMapType::iterator iter; + typename MVCCMapType::iterator iter; { std::shared_lock read_lock(table_rw_mutex); iter = mvcc_table_directory.begin(); @@ -1653,5 +1736,11 @@ PageEntriesEdit PageDirectory::dumpSnapshotToEdit(PageDirectorySnapshotPtr snap) return edit; } +template class VersionedPageEntries; +template class VersionedPageEntries; + +template class PageDirectory; +template class PageDirectory; + } // namespace PS::V3 } // namespace DB diff --git a/dbms/src/Storages/Page/V3/PageDirectory.h b/dbms/src/Storages/Page/V3/PageDirectory.h index 627a868485f..4543ecdc358 100644 --- a/dbms/src/Storages/Page/V3/PageDirectory.h +++ b/dbms/src/Storages/Page/V3/PageDirectory.h @@ -20,14 +20,16 @@ #include #include #include -#include #include #include #include +#include #include #include #include +#include #include +#include #include #include @@ -132,8 +134,6 @@ struct EntryOrDelete } }; -class VersionedPageEntries; -using VersionedPageEntriesPtr = std::shared_ptr; using PageLock = std::lock_guard; enum class ResolveResult @@ -143,15 +143,23 @@ enum class ResolveResult TO_NORMAL, }; +template class VersionedPageEntries { +public: + using PageId = typename Trait::PageId; + using PageEntriesEdit = DB::PS::V3::PageEntriesEdit; + + using GcEntries = std::vector>; + using GcEntriesMap = std::map; + public: VersionedPageEntries() : type(EditRecordType::VAR_DELETE) , is_deleted(false) , create_ver(0) , delete_ver(0) - , ori_page_id(0) + , ori_page_id{} , being_ref_count(1) {} @@ -166,17 +174,17 @@ class VersionedPageEntries // Return a PageId, if the page id is valid, it means it rewrite a RefPage into // a normal Page. Caller must call `derefAndClean` to decrease the ref-count of // the returing page id. - [[nodiscard]] PageIdV3Internal createUpsertEntry(const PageVersion & ver, const PageEntryV3 & entry); + [[nodiscard]] PageId createUpsertEntry(const PageVersion & ver, const PageEntryV3 & entry); - bool createNewRef(const PageVersion & ver, PageIdV3Internal ori_page_id); + bool createNewRef(const PageVersion & ver, const PageId & ori_page_id); - std::shared_ptr createNewExternal(const PageVersion & ver); + std::shared_ptr createNewExternal(const PageVersion & ver); void createDelete(const PageVersion & ver); - std::shared_ptr fromRestored(const PageEntriesEdit::EditRecord & rec); + std::shared_ptr fromRestored(const typename PageEntriesEdit::EditRecord & rec); - std::tuple + std::tuple resolveToPageId(UInt64 seq, bool ignore_delete, PageEntryV3 * entry); Int64 incrRefCount(const PageVersion & ver); @@ -194,9 +202,9 @@ class VersionedPageEntries */ PageSize getEntriesByBlobIds( const std::unordered_set & blob_ids, - PageIdV3Internal page_id, - std::map & blob_versioned_entries, - std::map> & ref_ids_maybe_rewrite); + const PageId & page_id, + GcEntriesMap & blob_versioned_entries, + std::map> & ref_ids_maybe_rewrite); /** * Given a `lowest_seq`, this will clean all outdated entries before `lowest_seq`. @@ -211,7 +219,7 @@ class VersionedPageEntries */ [[nodiscard]] bool cleanOutdatedEntries( UInt64 lowest_seq, - std::map> * normal_entries_to_deref, + std::map> * normal_entries_to_deref, PageEntriesV3 * entries_removed, const PageLock & page_lock); /** @@ -223,12 +231,12 @@ class VersionedPageEntries */ [[nodiscard]] bool derefAndClean( UInt64 lowest_seq, - PageIdV3Internal page_id, + const PageId & page_id, const PageVersion & deref_ver, Int64 deref_count, PageEntriesV3 * entries_removed); - void collapseTo(UInt64 seq, PageIdV3Internal page_id, PageEntriesEdit & edit); + void collapseTo(UInt64 seq, const PageId & page_id, PageEntriesEdit & edit); size_t size() const { @@ -272,11 +280,11 @@ class VersionedPageEntries // The deleted version, valid when type == VAR_REF/VAR_EXTERNAL && is_deleted = true PageVersion delete_ver; // Original page id, valid when type == VAR_REF - PageIdV3Internal ori_page_id; + PageId ori_page_id; // Being ref counter, valid when type == VAR_EXTERNAL Int64 being_ref_count; // A shared ptr to a holder, valid when type == VAR_EXTERNAL - std::shared_ptr external_holder; + std::shared_ptr external_holder; }; // `PageDirectory` store multi-versions entries for the same @@ -286,10 +294,22 @@ class VersionedPageEntries // User should call `gc` periodic to remove outdated version // of entries in order to keep the memory consumption as well // as the restoring time in a reasonable level. -class PageDirectory; -using PageDirectoryPtr = std::unique_ptr; +template class PageDirectory { +public: + using PageId = typename Trait::PageId; + using PageEntriesEdit = DB::PS::V3::PageEntriesEdit; + + using GcEntries = std::vector>; + using GcEntriesMap = std::map; + + using PageIdSet = std::set; + using PageIds = std::vector; + using PageEntries = std::vector; + using PageIdAndEntry = std::pair; + using PageIdAndEntries = std::vector; + public: explicit PageDirectory(String storage_name, WALStorePtr && wal, UInt64 max_persisted_log_files_ = MAX_PERSISTED_LOG_FILES); @@ -297,33 +317,35 @@ class PageDirectory SnapshotsStatistics getSnapshotsStat() const; - PageIDAndEntryV3 getByID(PageIdV3Internal page_id, const DB::PageStorageSnapshotPtr & snap) const + PageIdAndEntry getByID(const PageId & page_id, const DB::PageStorageSnapshotPtr & snap) const { return getByIDImpl(page_id, toConcreteSnapshot(snap), /*throw_on_not_exist=*/true); } - PageIDAndEntryV3 getByIDOrNull(PageIdV3Internal page_id, const DB::PageStorageSnapshotPtr & snap) const + PageIdAndEntry getByIDOrNull(const PageId & page_id, const DB::PageStorageSnapshotPtr & snap) const { return getByIDImpl(page_id, toConcreteSnapshot(snap), /*throw_on_not_exist=*/false); } - PageIDAndEntriesV3 getByIDs(const PageIdV3Internals & page_ids, const DB::PageStorageSnapshotPtr & snap) const + PageIdAndEntries getByIDs(const PageIds & page_ids, const DB::PageStorageSnapshotPtr & snap) const { return std::get<0>(getByIDsImpl(page_ids, toConcreteSnapshot(snap), /*throw_on_not_exist=*/true)); } - std::pair getByIDsOrNull(PageIdV3Internals page_ids, const DB::PageStorageSnapshotPtr & snap) const + std::pair getByIDsOrNull(const PageIds & page_ids, const DB::PageStorageSnapshotPtr & snap) const { return getByIDsImpl(page_ids, toConcreteSnapshot(snap), /*throw_on_not_exist=*/false); } - PageIdV3Internal getNormalPageId(PageIdV3Internal page_id, const DB::PageStorageSnapshotPtr & snap_, bool throw_on_not_exist) const; + PageId getNormalPageId(const PageId & page_id, const DB::PageStorageSnapshotPtr & snap_, bool throw_on_not_exist) const; + + UInt64 getMaxId() const; - PageId getMaxId() const; + PageIdSet getAllPageIds(); - std::set getAllPageIds(); + PageIdSet getAllPageIdsWithPrefix(const String & prefix, const DB::PageStorageSnapshotPtr & snap_); void apply(PageEntriesEdit && edit, const WriteLimiterPtr & write_limiter = nullptr); - std::pair, PageSize> + std::pair getEntriesByBlobIds(const std::vector & blob_ids) const; void gcApply(PageEntriesEdit && migrated_edit, const WriteLimiterPtr & write_limiter = nullptr); @@ -335,11 +357,11 @@ class PageDirectory // Perform a GC for in-memory entries and return the removed entries. // If `return_removed_entries` is false, then just return an empty set. - PageEntriesV3 gcInMemEntries(bool return_removed_entries = true); + PageEntries gcInMemEntries(bool return_removed_entries = true); // Get the external id that is not deleted or being ref by another id by // `ns_id`. - std::optional> getAliveExternalIds(NamespaceId ns_id) const + std::optional> getAliveExternalIds(const typename Trait::PageIdTrait::Prefix & ns_id) const { return external_ids_by_ns.getAliveIds(ns_id); } @@ -347,7 +369,7 @@ class PageDirectory // After table dropped, the `getAliveIds` with specified // `ns_id` will not be cleaned. We need this method to // cleanup all external id ptrs. - void unregisterNamespace(NamespaceId ns_id) + void unregisterNamespace(const typename Trait::PageIdTrait::Prefix & ns_id) { external_ids_by_ns.unregisterNamespace(ns_id); } @@ -371,24 +393,26 @@ class PageDirectory // No copying and no moving DISALLOW_COPY_AND_MOVE(PageDirectory); + template friend class PageDirectoryFactory; friend class PageStorageControlV3; private: - PageIDAndEntryV3 getByIDImpl(PageIdV3Internal page_id, const PageDirectorySnapshotPtr & snap, bool throw_on_not_exist) const; - std::pair - getByIDsImpl(const PageIdV3Internals & page_ids, const PageDirectorySnapshotPtr & snap, bool throw_on_not_exist) const; + PageIdAndEntry getByIDImpl(const PageId & page_id, const PageDirectorySnapshotPtr & snap, bool throw_on_not_exist) const; + std::pair + getByIDsImpl(const PageIds & page_ids, const PageDirectorySnapshotPtr & snap, bool throw_on_not_exist) const; private: // Only `std::map` is allow for `MVCCMap`. Cause `std::map::insert` ensure that // "No iterators or references are invalidated" // https://en.cppreference.com/w/cpp/container/map/insert - using MVCCMapType = std::map; + using VersionedPageEntriesPtr = std::shared_ptr>; + using MVCCMapType = std::map; static void applyRefEditRecord( MVCCMapType & mvcc_table_directory, const VersionedPageEntriesPtr & version_list, - const PageEntriesEdit::EditRecord & rec, + const typename PageEntriesEdit::EditRecord & rec, const PageVersion & version); static inline PageDirectorySnapshotPtr @@ -398,7 +422,7 @@ class PageDirectory } private: - PageId max_page_id; + UInt64 max_page_id; std::atomic sequence; // Used for avoid concurrently apply edits to wal and mvcc_table_directory. @@ -411,11 +435,37 @@ class PageDirectory mutable std::mutex snapshots_mutex; mutable std::list> snapshots; - mutable ExternalIdsByNamespace external_ids_by_ns; + mutable ExternalIdsByNamespace external_ids_by_ns; WALStorePtr wal; const UInt64 max_persisted_log_files; LoggerPtr log; }; +namespace u128 +{ +struct PageDirectoryTrait +{ + using PageId = PageIdV3Internal; + using PageIdTrait = PageIdTrait; + using Serializer = Serializer; +}; +using PageDirectoryType = PageDirectory; +using PageDirectoryPtr = std::unique_ptr; +using VersionedPageEntries = DB::PS::V3::VersionedPageEntries; +using VersionedPageEntriesPtr = std::shared_ptr; +} // namespace u128 +namespace universal +{ +struct PageDirectoryTrait +{ + using PageId = UniversalPageId; + using PageIdTrait = PageIdTrait; + using Serializer = Serializer; +}; +using PageDirectoryType = PageDirectory; +using PageDirectoryPtr = std::unique_ptr; +using VersionedPageEntries = DB::PS::V3::VersionedPageEntries; +using VersionedPageEntriesPtr = std::shared_ptr; +} // namespace universal } // namespace DB::PS::V3 diff --git a/dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.cpp b/dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.cpp index 445f2fc7d2c..9ba8de901d4 100644 --- a/dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.cpp +++ b/dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include #include #include @@ -20,22 +20,25 @@ namespace DB::PS::V3 { -void ExternalIdsByNamespace::addExternalIdUnlock(const std::shared_ptr & external_id) +template +void ExternalIdsByNamespace::addExternalIdUnlock(const std::shared_ptr & external_id) { - const NamespaceId & ns_id = external_id->high; + const Prefix & ns_id = Trait::getPrefix(*external_id); // create a new ExternalIds if the ns_id is not exists, else return // the existing one. auto [ns_iter, new_inserted] = ids_by_ns.try_emplace(ns_id, ExternalIds{}); - ns_iter->second.emplace_back(std::weak_ptr(external_id)); + ns_iter->second.emplace_back(std::weak_ptr(external_id)); } -void ExternalIdsByNamespace::addExternalId(const std::shared_ptr & external_id) +template +void ExternalIdsByNamespace::addExternalId(const std::shared_ptr & external_id) { std::unique_lock map_guard(mu); addExternalIdUnlock(external_id); } -std::optional> ExternalIdsByNamespace::getAliveIds(NamespaceId ns_id) const +template +std::optional> ExternalIdsByNamespace::getAliveIds(const Prefix & ns_id) const { // Now we assume a lock among all NamespaceIds is good enough. std::unique_lock map_guard(mu); @@ -45,7 +48,7 @@ std::optional> ExternalIdsByNamespace::getAliveIds(NamespaceId return std::nullopt; // Only scan the given `ns_id` - std::set valid_external_ids; + std::set valid_external_ids; auto & external_ids = ns_iter->second; for (auto iter = external_ids.begin(); iter != external_ids.end(); /*empty*/) { @@ -58,7 +61,7 @@ std::optional> ExternalIdsByNamespace::getAliveIds(NamespaceId } else { - valid_external_ids.emplace(holder->low); + valid_external_ids.emplace(Trait::getU64ID(*holder)); ++iter; } } @@ -67,10 +70,14 @@ std::optional> ExternalIdsByNamespace::getAliveIds(NamespaceId return valid_external_ids; } -void ExternalIdsByNamespace::unregisterNamespace(NamespaceId ns_id) +template +void ExternalIdsByNamespace::unregisterNamespace(const Prefix & ns_id) { std::unique_lock map_guard(mu); // free all weak_ptrs of this namespace ids_by_ns.erase(ns_id); } + +template class ExternalIdsByNamespace; +template class ExternalIdsByNamespace; } // namespace DB::PS::V3 diff --git a/dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.h b/dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.h index 0635ca8ca5e..1cbf69e0009 100644 --- a/dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.h +++ b/dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.h @@ -15,7 +15,8 @@ #pragma once #include -#include +#include +#include #include #include @@ -28,31 +29,36 @@ namespace DB::PS::V3 // A thread-safe class to manage external ids. // Manage all external ids by NamespaceId. +template class ExternalIdsByNamespace { +private: + using PageId = typename Trait::PageId; + using Prefix = typename Trait::Prefix; + public: ExternalIdsByNamespace() = default; // Add a external ids - void addExternalId(const std::shared_ptr & external_id); + void addExternalId(const std::shared_ptr & external_id); // non thread-safe version, only for restore - void addExternalIdUnlock(const std::shared_ptr & external_id); + void addExternalIdUnlock(const std::shared_ptr & external_id); // Get all alive external ids of given `ns_id` // Will also cleanup the invalid external ids. // If the ns_id is invalid, std::nullopt will be returned. - std::optional> getAliveIds(NamespaceId ns_id) const; + std::optional> getAliveIds(const Prefix & ns_id) const; // After table dropped, the `getAliveIds` with specified // `ns_id` will not be cleaned. We need this method to // cleanup all external id ptrs. - void unregisterNamespace(NamespaceId ns_id); + void unregisterNamespace(const Prefix & ns_id); // Check whether `ns_id` exist. Expose for testing. // Note that the result is meaningless unless `getAliveIds` // or `unregisterNamespace` is called to cleanup invalid // external ids. - bool existNamespace(NamespaceId ns_id) const + bool existNamespace(const Prefix & ns_id) const { std::lock_guard map_guard(mu); return ids_by_ns.count(ns_id) > 0; @@ -64,8 +70,8 @@ class ExternalIdsByNamespace mutable std::mutex mu; // Only store weak_ptrs. The weak_ptrs will be invalid after the external id // in PageDirectory get removed. - using ExternalIds = std::list>; - using NamespaceMap = std::unordered_map; + using ExternalIds = std::list>; + using NamespaceMap = std::unordered_map; mutable NamespaceMap ids_by_ns; }; } // namespace DB::PS::V3 diff --git a/dbms/src/Storages/Page/V3/PageDirectory/PageIdTrait.h b/dbms/src/Storages/Page/V3/PageDirectory/PageIdTrait.h new file mode 100644 index 00000000000..9ee7405eec7 --- /dev/null +++ b/dbms/src/Storages/Page/V3/PageDirectory/PageIdTrait.h @@ -0,0 +1,78 @@ +// 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::PS::V3 +{ +namespace u128 +{ +struct PageIdTrait +{ + using PageId = PageIdV3Internal; + using Prefix = NamespaceId; + + static inline PageId getInvalidID() + { + return buildV3Id(0, DB::INVALID_PAGE_U64_ID); + } + static inline PageIdU64 getU64ID(const PageId & page_id) + { + return page_id.low; + } + static inline Prefix getPrefix(const PageId & page_id) + { + return page_id.high; + } + static inline PageIdU64 getPageMapKey(const PageId & page_id) + { + return page_id.low; + } +}; +} // namespace u128 +namespace universal +{ +struct PageIdTrait +{ + using PageId = UniversalPageId; + using Prefix = String; + + static inline PageId getInvalidID() + { + return UniversalPageId{}; + } + static inline PageIdU64 getU64ID(const PageId & page_id) + { + if (page_id.size() >= sizeof(UInt64)) + return UniversalPageIdFormat::decodeUInt64(page_id.data() + page_id.size() - sizeof(UInt64)); + else + return INVALID_PAGE_U64_ID; + } + static inline Prefix getPrefix(const PageId & page_id) + { + if (page_id.size() >= sizeof(UInt64)) + return page_id.substr(0, page_id.size() - sizeof(UInt64)).toStr(); + else + return ""; + } + static inline PageId getPageMapKey(const PageId & page_id) + { + return page_id; + } +}; +} // namespace universal +} // namespace DB::PS::V3 diff --git a/dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp b/dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp index 1b2493b9c35..7ddd132ed8f 100644 --- a/dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp +++ b/dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include #include #include #include @@ -31,15 +31,19 @@ extern const int PS_DIR_APPLY_INVALID_STATUS; } // namespace ErrorCodes namespace PS::V3 { -PageDirectoryPtr PageDirectoryFactory::create(String storage_name, FileProviderPtr & file_provider, PSDiskDelegatorPtr & delegator, WALConfig config) +template +typename PageDirectoryFactory::PageDirectoryPtr +PageDirectoryFactory::create(const String & storage_name, FileProviderPtr & file_provider, PSDiskDelegatorPtr & delegator, const WALConfig & config) { auto [wal, reader] = WALStore::create(storage_name, file_provider, delegator, config); return createFromReader(storage_name, reader, std::move(wal)); } -PageDirectoryPtr PageDirectoryFactory::createFromReader(String storage_name, WALStoreReaderPtr reader, WALStorePtr wal) +template +typename PageDirectoryFactory::PageDirectoryPtr +PageDirectoryFactory::createFromReader(const String & storage_name, WALStoreReaderPtr reader, WALStorePtr wal) { - PageDirectoryPtr dir = std::make_unique(storage_name, std::move(wal)); + PageDirectoryPtr dir = std::make_unique(storage_name, std::move(wal)); loadFromDisk(dir, std::move(reader)); // Reset the `sequence` to the maximum of persisted. @@ -78,11 +82,13 @@ PageDirectoryPtr PageDirectoryFactory::createFromReader(String storage_name, WAL } // just for test -PageDirectoryPtr PageDirectoryFactory::createFromEdit(String storage_name, FileProviderPtr & file_provider, PSDiskDelegatorPtr & delegator, PageEntriesEdit & edit) +template +typename PageDirectoryFactory::PageDirectoryPtr +PageDirectoryFactory::createFromEdit(const String & storage_name, FileProviderPtr & file_provider, PSDiskDelegatorPtr & delegator, PageEntriesEdit & edit) { auto [wal, reader] = WALStore::create(storage_name, file_provider, delegator, WALConfig()); (void)reader; - PageDirectoryPtr dir = std::make_unique(std::move(storage_name), std::move(wal)); + PageDirectoryPtr dir = std::make_unique(std::move(storage_name), std::move(wal)); // Allocate mock sequence to run gc UInt64 mock_sequence = 0; @@ -126,7 +132,8 @@ PageDirectoryPtr PageDirectoryFactory::createFromEdit(String storage_name, FileP return dir; } -void PageDirectoryFactory::loadEdit(const PageDirectoryPtr & dir, const PageEntriesEdit & edit) +template +void PageDirectoryFactory::loadEdit(const PageDirectoryPtr & dir, const PageEntriesEdit & edit) { for (const auto & r : edit.getRecords()) { @@ -139,17 +146,25 @@ void PageDirectoryFactory::loadEdit(const PageDirectoryPtr & dir, const PageEntr } } -void PageDirectoryFactory::applyRecord( +template +void PageDirectoryFactory::applyRecord( const PageDirectoryPtr & dir, - const PageEntriesEdit::EditRecord & r) + const typename PageEntriesEdit::EditRecord & r) { auto [iter, created] = dir->mvcc_table_directory.insert(std::make_pair(r.page_id, nullptr)); if (created) { - iter->second = std::make_shared(); + if constexpr (std::is_same_v) + { + iter->second = std::make_shared>(); + } + else if constexpr (std::is_same_v) + { + iter->second = std::make_shared>(); + } } - dir->max_page_id = std::max(dir->max_page_id, r.page_id.low); + dir->max_page_id = std::max(dir->max_page_id, Trait::PageIdTrait::getU64ID(r.page_id)); const auto & version_list = iter->second; const auto & restored_version = r.version; @@ -189,7 +204,7 @@ void PageDirectoryFactory::applyRecord( version_list->createDelete(restored_version); break; case EditRecordType::REF: - PageDirectory::applyRefEditRecord( + Trait::PageDirectory::applyRefEditRecord( dir->mvcc_table_directory, version_list, r, @@ -198,7 +213,7 @@ void PageDirectoryFactory::applyRecord( case EditRecordType::UPSERT: { auto id_to_deref = version_list->createUpsertEntry(restored_version, r.entry); - if (id_to_deref.low != INVALID_PAGE_ID) + if (Trait::PageIdTrait::getU64ID(id_to_deref) != INVALID_PAGE_U64_ID) { // The ref-page is rewritten into a normal page, we need to decrease the ref-count of the original page auto deref_iter = dir->mvcc_table_directory.find(id_to_deref); @@ -217,7 +232,8 @@ void PageDirectoryFactory::applyRecord( } } -void PageDirectoryFactory::loadFromDisk(const PageDirectoryPtr & dir, WALStoreReaderPtr && reader) +template +void PageDirectoryFactory::loadFromDisk(const PageDirectoryPtr & dir, WALStoreReaderPtr && reader) { while (reader->remained()) { @@ -233,9 +249,12 @@ void PageDirectoryFactory::loadFromDisk(const PageDirectoryPtr & dir, WALStoreRe } // apply the edit read - auto edit = ser::deserializeFrom(record.value()); + auto edit = Trait::Serializer::deserializeFrom(record.value()); loadEdit(dir, edit); } } + +template class PageDirectoryFactory; +template class PageDirectoryFactory; } // namespace PS::V3 } // namespace DB diff --git a/dbms/src/Storages/Page/V3/PageDirectoryFactory.h b/dbms/src/Storages/Page/V3/PageDirectoryFactory.h index 2472ed11c71..69320fb90ad 100644 --- a/dbms/src/Storages/Page/V3/PageDirectoryFactory.h +++ b/dbms/src/Storages/Page/V3/PageDirectoryFactory.h @@ -14,9 +14,10 @@ #pragma once -#include #include #include +#include +#include #include #include @@ -27,8 +28,6 @@ using PSDiskDelegatorPtr = std::shared_ptr; namespace PS::V3 { -class PageDirectory; -using PageDirectoryPtr = std::unique_ptr; class WALStoreReader; using WALStoreReaderPtr = std::shared_ptr; @@ -36,26 +35,31 @@ using WALStoreReaderPtr = std::shared_ptr; * A helper class for creating `PageDirectory` instance and restore data from disk. * During restoring data, we need to restore `BlobStore::BlobStats` at the same time. */ +template class PageDirectoryFactory { +public: + using PageEntriesEdit = PageEntriesEdit; + using PageDirectoryPtr = std::unique_ptr; + public: PageVersion max_applied_ver; - PageDirectoryFactory & setBlobStore(BlobStore & blob_store) + PageDirectoryFactory & setBlobStore(typename Trait::BlobStore & blob_store) { blob_stats = &blob_store.blob_stats; return *this; } - PageDirectoryPtr create(String storage_name, FileProviderPtr & file_provider, PSDiskDelegatorPtr & delegator, WALConfig config); + PageDirectoryPtr create(const String & storage_name, FileProviderPtr & file_provider, PSDiskDelegatorPtr & delegator, const WALConfig & config); - PageDirectoryPtr createFromReader(String storage_name, WALStoreReaderPtr reader, WALStorePtr wal); + PageDirectoryPtr createFromReader(const String & storage_name, WALStoreReaderPtr reader, WALStorePtr wal); // just for test - PageDirectoryPtr createFromEdit(String storage_name, FileProviderPtr & file_provider, PSDiskDelegatorPtr & delegator, PageEntriesEdit & edit); + PageDirectoryPtr createFromEdit(const String & storage_name, FileProviderPtr & file_provider, PSDiskDelegatorPtr & delegator, PageEntriesEdit & edit); // just for test - PageDirectoryFactory & setBlobStats(BlobStats & blob_stats_) + PageDirectoryFactory & setBlobStats(BlobStats & blob_stats_) { blob_stats = &blob_stats_; return *this; @@ -66,7 +70,7 @@ class PageDirectoryFactory void loadEdit(const PageDirectoryPtr & dir, const PageEntriesEdit & edit); static void applyRecord( const PageDirectoryPtr & dir, - const PageEntriesEdit::EditRecord & r); + const typename PageEntriesEdit::EditRecord & r); BlobStats * blob_stats = nullptr; @@ -75,6 +79,29 @@ class PageDirectoryFactory bool dump_entries = false; }; +namespace u128 +{ +struct FactoryTrait +{ + using PageId = PageIdV3Internal; + using PageDirectory = PageDirectoryType; + using BlobStore = BlobStoreType; + using PageIdTrait = PageIdTrait; + using Serializer = Serializer; +}; +using PageDirectoryFactory = DB::PS::V3::PageDirectoryFactory; +} // namespace u128 +namespace universal +{ +struct FactoryTrait +{ + using PageId = UniversalPageId; + using PageDirectory = PageDirectoryType; + using BlobStore = BlobStoreType; + using PageIdTrait = PageIdTrait; + using Serializer = Serializer; +}; +using PageDirectoryFactory = DB::PS::V3::PageDirectoryFactory; +} // namespace universal } // namespace PS::V3 - } // namespace DB diff --git a/dbms/src/Storages/Page/V3/PageEntriesEdit.h b/dbms/src/Storages/Page/V3/PageEntriesEdit.h index 1e8f2d41493..d85c6bb7baa 100644 --- a/dbms/src/Storages/Page/V3/PageEntriesEdit.h +++ b/dbms/src/Storages/Page/V3/PageEntriesEdit.h @@ -16,8 +16,9 @@ #include #include -#include +#include #include +#include #include #include #include @@ -91,7 +92,7 @@ struct fmt::formatter namespace DB::PS::V3 { -using VersionedEntry = std::pair; +using VersionedEntry = std::pair; using VersionedEntries = std::vector; enum class EditRecordType @@ -138,8 +139,12 @@ inline const char * typeToString(EditRecordType t) } /// Page entries change to apply to PageDirectory +template class PageEntriesEdit { +public: + using PageId = PageIdType; + public: PageEntriesEdit() = default; @@ -148,7 +153,7 @@ class PageEntriesEdit records.reserve(capacity); } - void put(PageIdV3Internal page_id, const PageEntryV3 & entry) + void put(const PageId & page_id, const PageEntryV3 & entry) { EditRecord record{}; record.type = EditRecordType::PUT; @@ -157,7 +162,7 @@ class PageEntriesEdit records.emplace_back(record); } - void putExternal(PageIdV3Internal page_id) + void putExternal(const PageId & page_id) { EditRecord record{}; record.type = EditRecordType::PUT_EXTERNAL; @@ -165,7 +170,7 @@ class PageEntriesEdit records.emplace_back(record); } - void upsertPage(PageIdV3Internal page_id, const PageVersion & ver, const PageEntryV3 & entry) + void upsertPage(const PageId & page_id, const PageVersion & ver, const PageEntryV3 & entry) { EditRecord record{}; record.type = EditRecordType::UPSERT; @@ -175,7 +180,7 @@ class PageEntriesEdit records.emplace_back(record); } - void del(PageIdV3Internal page_id) + void del(const PageId & page_id) { EditRecord record{}; record.type = EditRecordType::DEL; @@ -183,7 +188,7 @@ class PageEntriesEdit records.emplace_back(record); } - void ref(PageIdV3Internal ref_id, PageIdV3Internal page_id) + void ref(const PageId & ref_id, const PageId & page_id) { EditRecord record{}; record.type = EditRecordType::REF; @@ -192,7 +197,7 @@ class PageEntriesEdit records.emplace_back(record); } - void varRef(PageIdV3Internal ref_id, const PageVersion & ver, PageIdV3Internal ori_page_id) + void varRef(const PageId & ref_id, const PageVersion & ver, const PageId & ori_page_id) { EditRecord record{}; record.type = EditRecordType::VAR_REF; @@ -202,7 +207,7 @@ class PageEntriesEdit records.emplace_back(record); } - void varExternal(PageIdV3Internal page_id, const PageVersion & create_ver, Int64 being_ref_count) + void varExternal(const PageId & page_id, const PageVersion & create_ver, Int64 being_ref_count) { EditRecord record{}; record.type = EditRecordType::VAR_EXTERNAL; @@ -212,7 +217,7 @@ class PageEntriesEdit records.emplace_back(record); } - void varEntry(PageIdV3Internal page_id, const PageVersion & ver, const PageEntryV3 & entry, Int64 being_ref_count) + void varEntry(const PageId & page_id, const PageVersion & ver, const PageEntryV3 & entry, Int64 being_ref_count) { EditRecord record{}; record.type = EditRecordType::VAR_ENTRY; @@ -223,7 +228,7 @@ class PageEntriesEdit records.emplace_back(record); } - void varDel(PageIdV3Internal page_id, const PageVersion & delete_ver) + void varDel(const PageId & page_id, const PageVersion & delete_ver) { EditRecord record{}; record.type = EditRecordType::VAR_DELETE; @@ -240,20 +245,12 @@ class PageEntriesEdit struct EditRecord { - EditRecordType type; - PageIdV3Internal page_id; - PageIdV3Internal ori_page_id; + EditRecordType type{EditRecordType::DEL}; + PageId page_id{}; + PageId ori_page_id{}; PageVersion version; PageEntryV3 entry; - Int64 being_ref_count; - - EditRecord() - : type(EditRecordType::DEL) - , page_id(0) - , ori_page_id(0) - , version(0, 0) - , being_ref_count(1) - {} + Int64 being_ref_count{1}; }; using EditRecords = std::vector; @@ -299,4 +296,12 @@ class PageEntriesEdit } }; +namespace u128 +{ +using PageEntriesEdit = PageEntriesEdit; +} +namespace universal +{ +using PageEntriesEdit = PageEntriesEdit; +} } // namespace DB::PS::V3 diff --git a/dbms/src/Storages/Page/V3/PageEntry.h b/dbms/src/Storages/Page/V3/PageEntry.h index 3b441bd094a..d32fd16e376 100644 --- a/dbms/src/Storages/Page/V3/PageEntry.h +++ b/dbms/src/Storages/Page/V3/PageEntry.h @@ -15,7 +15,7 @@ #pragma once #include -#include +#include #include namespace DB diff --git a/dbms/src/Storages/Page/V3/PageStorageImpl.cpp b/dbms/src/Storages/Page/V3/PageStorageImpl.cpp index e132b847357..c671a30d145 100644 --- a/dbms/src/Storages/Page/V3/PageStorageImpl.cpp +++ b/dbms/src/Storages/Page/V3/PageStorageImpl.cpp @@ -18,8 +18,9 @@ #include #include #include -#include #include +#include +#include #include #include #include @@ -67,13 +68,13 @@ void PageStorageImpl::restore() // TODO: Speedup restoring blob_store.registerPaths(); - PageDirectoryFactory factory; + u128::PageDirectoryFactory factory; page_directory = factory .setBlobStore(blob_store) .create(storage_name, file_provider, delegator, WALConfig::from(config)); } -PageId PageStorageImpl::getMaxId() +PageIdU64 PageStorageImpl::getMaxId() { return page_directory->getMaxId(); } @@ -83,7 +84,7 @@ void PageStorageImpl::drop() throw Exception("Not implemented", ErrorCodes::NOT_IMPLEMENTED); } -PageId PageStorageImpl::getNormalPageIdImpl(NamespaceId ns_id, PageId page_id, SnapshotPtr snapshot, bool throw_on_not_exist) +PageIdU64 PageStorageImpl::getNormalPageIdImpl(NamespaceId ns_id, PageIdU64 page_id, SnapshotPtr snapshot, bool throw_on_not_exist) { if (!snapshot) { @@ -116,7 +117,7 @@ size_t PageStorageImpl::getNumberOfPages() } // For debugging purpose -std::set PageStorageImpl::getAliveExternalPageIds(NamespaceId ns_id) +std::set PageStorageImpl::getAliveExternalPageIds(NamespaceId ns_id) { // Keep backward compatibility of this functions with v2 if (auto ids = page_directory->getAliveExternalIds(ns_id); ids) @@ -137,7 +138,7 @@ void PageStorageImpl::writeImpl(DB::WriteBatch && write_batch, const WriteLimite page_directory->apply(std::move(edit), write_limiter); } -DB::PageEntry PageStorageImpl::getEntryImpl(NamespaceId ns_id, PageId page_id, SnapshotPtr snapshot) +DB::PageEntry PageStorageImpl::getEntryImpl(NamespaceId ns_id, PageIdU64 page_id, SnapshotPtr snapshot) { if (!snapshot) { @@ -167,7 +168,7 @@ DB::PageEntry PageStorageImpl::getEntryImpl(NamespaceId ns_id, PageId page_id, S } } -DB::Page PageStorageImpl::readImpl(NamespaceId ns_id, PageId page_id, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) +DB::Page PageStorageImpl::readImpl(NamespaceId ns_id, PageIdU64 page_id, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) { if (!snapshot) { @@ -178,7 +179,7 @@ DB::Page PageStorageImpl::readImpl(NamespaceId ns_id, PageId page_id, const Read return blob_store.read(page_entry, read_limiter); } -PageMap PageStorageImpl::readImpl(NamespaceId ns_id, const PageIds & page_ids, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) +PageMapU64 PageStorageImpl::readImpl(NamespaceId ns_id, const PageIdU64s & page_ids, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) { if (!snapshot) { @@ -199,18 +200,16 @@ PageMap PageStorageImpl::readImpl(NamespaceId ns_id, const PageIds & page_ids, c else { auto [page_entries, page_ids_not_found] = page_directory->getByIDsOrNull(page_id_v3s, snapshot); - PageMap page_map = blob_store.read(page_entries, read_limiter); + PageMapU64 page_map = blob_store.read(page_entries, read_limiter); for (const auto & page_id_not_found : page_ids_not_found) { - Page page_not_found; - page_not_found.page_id = INVALID_PAGE_ID; - page_map[page_id_not_found] = page_not_found; + page_map.emplace(page_id_not_found.low, Page::invalidPage()); } return page_map; } } -PageMap PageStorageImpl::readImpl(NamespaceId ns_id, const std::vector & page_fields, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) +PageMapU64 PageStorageImpl::readImpl(NamespaceId ns_id, const std::vector & page_fields, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) { if (!snapshot) { @@ -219,15 +218,15 @@ PageMap PageStorageImpl::readImpl(NamespaceId ns_id, const std::vector::FieldReadInfos read_infos; for (const auto & [page_id, field_indices] : page_fields) { const auto & [id, entry] = throw_on_not_exist ? page_directory->getByID(buildV3Id(ns_id, page_id), snapshot) : page_directory->getByIDOrNull(buildV3Id(ns_id, page_id), snapshot); if (entry.isValid()) { - auto info = BlobStore::FieldReadInfo(buildV3Id(ns_id, page_id), entry, field_indices); + auto info = BlobStore::FieldReadInfo(buildV3Id(ns_id, page_id), entry, field_indices); read_infos.emplace_back(info); } else @@ -237,12 +236,10 @@ PageMap PageStorageImpl::readImpl(NamespaceId ns_id, const std::vector"; - case GCStageType::OnlyInMem: - return " without full gc"; - case GCStageType::FullGCNothingMoved: - return " without moving any entry"; - case GCStageType::FullGC: - return ""; - } - }(); - const auto get_external_msg = [this]() -> String { - if (clean_external_page_ms == 0) - return String(""); - static constexpr double SCALE_NS_TO_MS = 1'000'000.0; - return fmt::format(" [external_callbacks={}] [external_gc={}ms] [scanner={:.2f}ms] [get_alive={:.2f}ms] [remover={:.2f}ms]", - num_external_callbacks, - clean_external_page_ms, - external_page_scan_ns / SCALE_NS_TO_MS, - external_page_get_alive_ns / SCALE_NS_TO_MS, - external_page_remove_ns / SCALE_NS_TO_MS); - }; - return fmt::format("GC finished{}." - " [total time={}ms]" - " [compact wal={}ms] [compact directory={}ms] [compact spacemap={}ms]" - " [gc status={}ms] [gc entries={}ms] [gc data={}ms]" - " [gc apply={}ms]" - "{}", // a placeholder for external page gc at last - stage_suffix, - total_cost_ms, - compact_wal_ms, - compact_directory_ms, - compact_spacemap_ms, - full_gc_prepare_ms, - full_gc_get_entries_ms, - full_gc_blobstore_copy_ms, - full_gc_apply_ms, - get_external_msg()); -} - -void PageStorageImpl::GCTimeStatistics::finishCleanExternalPage(UInt64 clean_cost_ms) -{ - clean_external_page_ms = clean_cost_ms; - GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_clean_external).Observe(clean_external_page_ms / 1000.0); -} - bool PageStorageImpl::gcImpl(bool /*not_skip*/, const WriteLimiterPtr & write_limiter, const ReadLimiterPtr & read_limiter) { - // If another thread is running gc, just return; - bool v = false; - if (!gc_is_running.compare_exchange_strong(v, true)) - return false; - - const GCTimeStatistics statistics = doGC(write_limiter, read_limiter); - assert(statistics.stage != GCStageType::Unknown); // `doGC` must set the stage - LOG_DEBUG(log, statistics.toLogging()); - - return statistics.executeNextImmediately(); -} - -// Remove external pages for all tables -// TODO: `clean_external_page` for all tables may slow down the whole gc process when there are lots of table. -void PageStorageImpl::cleanExternalPage(Stopwatch & gc_watch, GCTimeStatistics & statistics) -{ - // Fine grained lock on `callbacks_mutex`. - // So that adding/removing a storage will not be blocked for the whole - // processing time of `cleanExternalPage`. - std::shared_ptr ns_callbacks; - { - std::scoped_lock lock{callbacks_mutex}; - // check and get the begin iter - statistics.num_external_callbacks = callbacks_container.size(); - auto iter = callbacks_container.begin(); - if (iter == callbacks_container.end()) // empty - { - statistics.finishCleanExternalPage(gc_watch.elapsedMillisecondsFromLastTime()); - return; - } - - assert(iter != callbacks_container.end()); // early exit in the previous code - // keep the shared_ptr so that erasing ns_id from PageStorage won't invalid the `ns_callbacks` - ns_callbacks = iter->second; - } - - Stopwatch external_watch; - - SYNC_FOR("before_PageStorageImpl::cleanExternalPage_execute_callbacks"); - - while (true) - { - // 1. Note that we must call `scanner` before `getAliveExternalIds`. - // Or some committed external ids is not included in `alive_ids` - // but exist in `pending_external_pages`. They will be removed by - // accident with `remover` under this situation. - // 2. Assume calling the callbacks after erasing ns_is is safe. - - // the external pages on disks. - auto pending_external_pages = ns_callbacks->scanner(); - statistics.external_page_scan_ns += external_watch.elapsedFromLastTime(); - auto alive_external_ids = page_directory->getAliveExternalIds(ns_callbacks->ns_id); - statistics.external_page_get_alive_ns += external_watch.elapsedFromLastTime(); - if (alive_external_ids) - { - // remove the external pages that is not alive now. - ns_callbacks->remover(pending_external_pages, *alive_external_ids); - } // else the ns_id is invalid, just skip - statistics.external_page_remove_ns += external_watch.elapsedFromLastTime(); - - // move to next namespace callbacks - { - std::scoped_lock lock{callbacks_mutex}; - // next ns_id that is greater than `ns_id` - auto iter = callbacks_container.upper_bound(ns_callbacks->ns_id); - if (iter == callbacks_container.end()) - break; - ns_callbacks = iter->second; - } - } - - statistics.finishCleanExternalPage(gc_watch.elapsedMillisecondsFromLastTime()); -} - -PageStorageImpl::GCTimeStatistics PageStorageImpl::doGC(const WriteLimiterPtr & write_limiter, const ReadLimiterPtr & read_limiter) -{ - Stopwatch gc_watch; - SCOPE_EXIT({ - GET_METRIC(tiflash_storage_page_gc_count, type_v3).Increment(); - GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_v3).Observe(gc_watch.elapsedSeconds()); - bool is_running = true; - gc_is_running.compare_exchange_strong(is_running, false); - }); - - GCTimeStatistics statistics; - - // TODO: rewrite the GC process and split it into smaller interface - bool force_wal_compact = false; - fiu_do_on(FailPoints::force_ps_wal_compact, { force_wal_compact = true; }); - - // 1. Do the MVCC gc, clean up expired snapshot. - // And get the expired entries. - if (page_directory->tryDumpSnapshot(read_limiter, write_limiter, force_wal_compact)) - { - GET_METRIC(tiflash_storage_page_gc_count, type_v3_mvcc_dumped).Increment(); - } - statistics.compact_wal_ms = gc_watch.elapsedMillisecondsFromLastTime(); - GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_compact_wal).Observe(statistics.compact_wal_ms / 1000.0); - - const auto & del_entries = page_directory->gcInMemEntries(); - statistics.compact_directory_ms = gc_watch.elapsedMillisecondsFromLastTime(); - GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_compact_directory).Observe(statistics.compact_directory_ms / 1000.0); - - SYNC_FOR("before_PageStorageImpl::doGC_fullGC_prepare"); - - // 2. Remove the expired entries in BlobStore. - // It won't delete the data on the disk. - // It will only update the SpaceMap which in memory. - blob_store.remove(del_entries); - statistics.compact_spacemap_ms = gc_watch.elapsedMillisecondsFromLastTime(); - GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_compact_spacemap).Observe(statistics.compact_spacemap_ms / 1000.0); - - // Note that if full GC is not executed, below metrics won't be shown on grafana but it should - // only take few ms to fininsh these in-memory operations. Check them out by the logs if - // the total time cost not match. - - // 3. Check whether there are BlobFiles that need to do `full GC`. - // This function will also try to use `ftruncate` to reduce space amplification. - const auto & blob_ids_need_gc = blob_store.getGCStats(); - statistics.full_gc_prepare_ms = gc_watch.elapsedMillisecondsFromLastTime(); - if (blob_ids_need_gc.empty()) - { - cleanExternalPage(gc_watch, statistics); - statistics.stage = GCStageType::OnlyInMem; - statistics.total_cost_ms = gc_watch.elapsedMilliseconds(); - return statistics; - } - - // Execute full gc - GET_METRIC(tiflash_storage_page_gc_count, type_v3_bs_full_gc).Increment(blob_ids_need_gc.size()); - // 4. Filter out entries in MVCC by BlobId. - // We also need to filter the version of the entry. - // So that the `gc_apply` can proceed smoothly. - auto [blob_gc_info, total_page_size] = page_directory->getEntriesByBlobIds(blob_ids_need_gc); - statistics.full_gc_get_entries_ms = gc_watch.elapsedMillisecondsFromLastTime(); - if (blob_gc_info.empty()) - { - cleanExternalPage(gc_watch, statistics); - statistics.stage = GCStageType::FullGCNothingMoved; - statistics.total_cost_ms = gc_watch.elapsedMilliseconds(); - return statistics; - } - - SYNC_FOR("before_PageStorageImpl::doGC_fullGC_commit"); - - // 5. Do the BlobStore GC - // After BlobStore GC, these entries will be migrated to a new blob. - // Then we should notify MVCC apply the change. - PageEntriesEdit gc_edit = blob_store.gc(blob_gc_info, total_page_size, write_limiter, read_limiter); - statistics.full_gc_blobstore_copy_ms = gc_watch.elapsedMillisecondsFromLastTime(); - GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_fullgc_rewrite).Observe( // - (statistics.full_gc_prepare_ms + statistics.full_gc_get_entries_ms + statistics.full_gc_blobstore_copy_ms) / 1000.0); - RUNTIME_CHECK_MSG(!gc_edit.empty(), "Something wrong after BlobStore GC"); - - // 6. MVCC gc apply - // MVCC will apply the migrated entries. - // Also it will generate a new version for these entries. - // Note that if the process crash between step 5 and step 6, the stats in BlobStore will - // be reset to correct state during restore. If any exception thrown, then some BlobFiles - // will be remained as "read-only" files while entries in them are useless in actual. - // Those BlobFiles should be cleaned during next restore. - page_directory->gcApply(std::move(gc_edit), write_limiter); - statistics.full_gc_apply_ms = gc_watch.elapsedMillisecondsFromLastTime(); - GET_METRIC(tiflash_storage_page_gc_duration_seconds, type_fullgc_commit).Observe(statistics.full_gc_apply_ms / 1000.0); - - SYNC_FOR("after_PageStorageImpl::doGC_fullGC_commit"); - - cleanExternalPage(gc_watch, statistics); - statistics.stage = GCStageType::FullGC; - statistics.total_cost_ms = gc_watch.elapsedMilliseconds(); - return statistics; + return manager.gc(blob_store, *page_directory, write_limiter, read_limiter, log); } void PageStorageImpl::registerExternalPagesCallbacks(const ExternalPageCallbacks & callbacks) { - std::scoped_lock lock{callbacks_mutex}; - assert(callbacks.scanner != nullptr); - assert(callbacks.remover != nullptr); - assert(callbacks.ns_id != MAX_NAMESPACE_ID); - // NamespaceId(TableID) should not be reuse - RUNTIME_CHECK_MSG( - callbacks_container.count(callbacks.ns_id) == 0, - "Try to create callbacks for duplicated namespace id {}", - callbacks.ns_id); - // `emplace` won't invalid other iterator - callbacks_container.emplace(callbacks.ns_id, std::make_shared(callbacks)); + manager.registerExternalPagesCallbacks(callbacks); } void PageStorageImpl::unregisterExternalPagesCallbacks(NamespaceId ns_id) { - { - std::scoped_lock lock{callbacks_mutex}; - callbacks_container.erase(ns_id); - } + manager.unregisterExternalPagesCallbacks(ns_id); // clean all external ids ptrs page_directory->unregisterNamespace(ns_id); } -const String PageStorageImpl::manifests_file_name = "manifests"; - -bool PageStorageImpl::isManifestsFileExists(const String & path) -{ - Poco::File file(fmt::format("{}/{}", path, manifests_file_name)); - return file.exists(); -} - -void PageStorageImpl::createManifestsFileIfNeed(const String & path) -{ - Poco::File dir(path); - dir.createDirectories(); - Poco::File file(fmt::format("{}/{}", path, manifests_file_name)); - file.createFile(); -} - } // namespace PS::V3 } // namespace DB diff --git a/dbms/src/Storages/Page/V3/PageStorageImpl.h b/dbms/src/Storages/Page/V3/PageStorageImpl.h index 28cddb5a86d..d1bb85e9992 100644 --- a/dbms/src/Storages/Page/V3/PageStorageImpl.h +++ b/dbms/src/Storages/Page/V3/PageStorageImpl.h @@ -16,10 +16,11 @@ #include #include -#include #include #include #include +#include +#include #include #include @@ -44,9 +45,9 @@ class PageStorageImpl : public DB::PageStorage void drop() override; - PageId getMaxId() override; + PageIdU64 getMaxId() override; - PageId getNormalPageIdImpl(NamespaceId ns_id, PageId page_id, SnapshotPtr snapshot, bool throw_on_not_exist) override; + PageIdU64 getNormalPageIdImpl(NamespaceId ns_id, PageIdU64 page_id, SnapshotPtr snapshot, bool throw_on_not_exist) override; DB::PageStorage::SnapshotPtr getSnapshot(const String & tracing_id) override; @@ -56,17 +57,17 @@ class PageStorageImpl : public DB::PageStorage size_t getNumberOfPages() override; - std::set getAliveExternalPageIds(NamespaceId ns_id) override; + std::set getAliveExternalPageIds(NamespaceId ns_id) override; void writeImpl(DB::WriteBatch && write_batch, const WriteLimiterPtr & write_limiter) override; - DB::PageEntry getEntryImpl(NamespaceId ns_id, PageId page_id, SnapshotPtr snapshot) override; + DB::PageEntry getEntryImpl(NamespaceId ns_id, PageIdU64 page_id, SnapshotPtr snapshot) override; - DB::Page readImpl(NamespaceId ns_id, PageId page_id, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) override; + DB::Page readImpl(NamespaceId ns_id, PageIdU64 page_id, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) override; - PageMap readImpl(NamespaceId ns_id, const PageIds & page_ids, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) override; + PageMapU64 readImpl(NamespaceId ns_id, const PageIdU64s & page_ids, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) override; - PageMap readImpl(NamespaceId ns_id, const std::vector & page_fields, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) override; + PageMapU64 readImpl(NamespaceId ns_id, const std::vector & page_fields, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) override; Page readImpl(NamespaceId ns_id, const PageReadFields & page_field, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) override; @@ -78,85 +79,31 @@ class PageStorageImpl : public DB::PageStorage void unregisterExternalPagesCallbacks(NamespaceId ns_id) override; - static bool isManifestsFileExists(const String & path); - - static void createManifestsFileIfNeed(const String & path); - #ifndef NDEBUG // Just for tests, refactor them out later // clang-format off DB::PageStorage::SnapshotPtr getSnapshot() { return getSnapshot(""); } - DB::PageEntry getEntry(PageId page_id) { return getEntryImpl(TEST_NAMESPACE_ID, page_id, nullptr); } - DB::Page read(PageId page_id) { return readImpl(TEST_NAMESPACE_ID, page_id, nullptr, nullptr, true); } - PageMap read(const PageIds & page_ids) { return readImpl(TEST_NAMESPACE_ID, page_ids, nullptr, nullptr, true); } - PageMap read(const std::vector & page_fields) { return readImpl(TEST_NAMESPACE_ID, page_fields, nullptr, nullptr, true); } + DB::PageEntry getEntry(PageIdU64 page_id) { return getEntryImpl(TEST_NAMESPACE_ID, page_id, nullptr); } + DB::Page read(PageIdU64 page_id) { return readImpl(TEST_NAMESPACE_ID, page_id, nullptr, nullptr, true); } + PageMapU64 read(const PageIdU64s & page_ids) { return readImpl(TEST_NAMESPACE_ID, page_ids, nullptr, nullptr, true); } + PageMapU64 read(const std::vector & page_fields) { return readImpl(TEST_NAMESPACE_ID, page_fields, nullptr, nullptr, true); } // clang-format on #endif + template friend class PageDirectoryFactory; friend class PageStorageControlV3; #ifndef DBMS_PUBLIC_GTEST private: #endif - enum class GCStageType - { - Unknown, - OnlyInMem, - FullGCNothingMoved, - FullGC, - }; - struct GCTimeStatistics - { - GCStageType stage = GCStageType::Unknown; - bool executeNextImmediately() const { return stage == GCStageType::FullGC; }; - - UInt64 total_cost_ms = 0; - - UInt64 compact_wal_ms = 0; - UInt64 compact_directory_ms = 0; - UInt64 compact_spacemap_ms = 0; - // Full GC - UInt64 full_gc_prepare_ms = 0; - UInt64 full_gc_get_entries_ms = 0; - UInt64 full_gc_blobstore_copy_ms = 0; - UInt64 full_gc_apply_ms = 0; - - // GC external page - UInt64 num_external_callbacks = 0; - // Breakdown the duration for cleaning external pages - // ms is usually too big for these operation, store by ns (10^-9) - UInt64 external_page_scan_ns = 0; - UInt64 external_page_get_alive_ns = 0; - UInt64 external_page_remove_ns = 0; - - private: - // Total time of cleaning external pages - UInt64 clean_external_page_ms = 0; - - public: - void finishCleanExternalPage(UInt64 clean_cost_ms); - - String toLogging() const; - }; - - GCTimeStatistics doGC(const WriteLimiterPtr & write_limiter, const ReadLimiterPtr & read_limiter); - void cleanExternalPage(Stopwatch & gc_watch, GCTimeStatistics & statistics); - LoggerPtr log; - PageDirectoryPtr page_directory; - - BlobStore blob_store; - - std::atomic gc_is_running = false; + u128::PageDirectoryPtr page_directory; - const static String manifests_file_name; + u128::BlobStoreType blob_store; - std::mutex callbacks_mutex; - // Only std::map not std::unordered_map. We need insert/erase do not invalid other iterators. - using ExternalPageCallbacksContainer = std::map>; - ExternalPageCallbacksContainer callbacks_container; + u128::ExternalPageCallbacksManager manager; }; } // namespace PS::V3 diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageId.h b/dbms/src/Storages/Page/V3/Universal/UniversalPageId.h new file mode 100644 index 00000000000..40e7200f56c --- /dev/null +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageId.h @@ -0,0 +1,112 @@ +// 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 +#include +#include + +namespace DB +{ +class UniversalPageId final +{ +public: + static inline UniversalPageId toFullPageId(const String & prefix, PageIdU64 page_id) + { + WriteBufferFromOwnString buff; + writeString(prefix, buff); + UniversalPageIdFormat::encodeUInt64(page_id, buff); + return buff.releaseStr(); + } + +public: + UniversalPageId() = default; + + UniversalPageId(String id_) // NOLINT(google-explicit-constructor) + : id(std::move(id_)) + {} + UniversalPageId(const char * id_) // NOLINT(google-explicit-constructor) + : id(id_) + {} + UniversalPageId(const char * id_, size_t sz_) + : id(id_, sz_) + {} + + UniversalPageId & operator=(String && id_) noexcept + { + id.swap(id_); + return *this; + } + bool operator==(const UniversalPageId & rhs) const noexcept + { + return id == rhs.id; + } + bool operator!=(const UniversalPageId & rhs) const noexcept + { + return id != rhs.id; + } + bool operator>=(const UniversalPageId & rhs) const noexcept + { + return id >= rhs.id; + } + size_t rfind(const String & str, size_t pos) const noexcept + { + return id.rfind(str, pos); + } + + const char * data() const { return id.data(); } + size_t size() const { return id.size(); } + bool empty() const { return id.empty(); } + UniversalPageId substr(size_t pos, size_t npos) const { return id.substr(pos, npos); } + bool operator<(const UniversalPageId & rhs) const { return id < rhs.id; } + bool isPrefix(const String & str) const { return startsWith(id, str); } + + String toStr() const { return id; } + const String & asStr() const { return id; } + + friend bool operator==(const String & lhs, const UniversalPageId & rhs); + +private: + String id; +}; +using UniversalPageIds = std::vector; + +inline bool operator==(const String & lhs, const UniversalPageId & rhs) +{ + return lhs == rhs.id; +} +} // namespace DB + +template <> +struct fmt::formatter +{ + static constexpr auto parse(format_parse_context & ctx) -> decltype(ctx.begin()) + { + const auto * it = ctx.begin(); + const auto * end = ctx.end(); + /// Only support {}. + if (it != end && *it != '}') + throw format_error("invalid format"); + return it; + } + + template + auto format(const DB::UniversalPageId & value, FormatContext & ctx) const -> decltype(ctx.out()) + { + return format_to(ctx.out(), "{}", Redact::keyToHexString(value.data(), value.size())); + } +}; \ No newline at end of file diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageIdFormat.h b/dbms/src/Storages/Page/V3/Universal/UniversalPageIdFormat.h new file mode 100644 index 00000000000..87911593b71 --- /dev/null +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageIdFormat.h @@ -0,0 +1,60 @@ +// 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 + +namespace DB +{ +// General UniversalPageId Format: Prefix + PageIdU64. +// So normally the size of page id should be larger than 8 bytes(size of PageIdU64). +// If the size of page id is smaller than 8 bytes, it will be regraded as a whole.(Its Prefix is empty, while PageIdU64 is INVALID_PAGE_U64_ID) +// +// Currently, if the PageIdU64 is 0(which is INVALID_PAGE_U64_ID), it may have some special meaning in some cases, +// so please avoid it in the following case: +// 1. if there are ref operations in your workload +// +// +// The main key format types: +// Raft related key +// Format: https://github.com/tikv/tikv/blob/9c0df6d68c72d30021b36d24275fdceca9864235/components/keys/src/lib.rs#L24 +// +// KVStore related key +// Prefix = [optional prefix] + "kvs" +// +// Storage key +// Meta +// Prefix = [optional prefix] + "tm" + NamespaceId +// Log +// Prefix = [optional prefix] + "tl" + NamespaceId +// Data +// Prefix = [optional prefix] + "td" + NamespaceId + +struct UniversalPageIdFormat +{ + static inline void encodeUInt64(const UInt64 x, WriteBuffer & ss) + { + auto u = toBigEndian(x); + ss.write(reinterpret_cast(&u), sizeof(u)); + } + + static inline UInt64 decodeUInt64(const char * s) + { + auto v = *(reinterpret_cast(s)); + return toBigEndian(v); + } +}; +} // namespace DB diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.cpp b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.cpp new file mode 100644 index 00000000000..9df23eb58b0 --- /dev/null +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.cpp @@ -0,0 +1,205 @@ +// 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 + +namespace DB +{ +UniversalPageStoragePtr UniversalPageStorage::create( + String name, + PSDiskDelegatorPtr delegator, + const PageStorageConfig & config, + const FileProviderPtr & file_provider) +{ + UniversalPageStoragePtr storage = std::make_shared(name, delegator, config, file_provider); + storage->blob_store = std::make_unique( + name, + file_provider, + delegator, + PS::V3::BlobConfig::from(config)); + return storage; +} + +void UniversalPageStorage::restore() +{ + blob_store->registerPaths(); + + PS::V3::universal::PageDirectoryFactory factory; + page_directory = factory + .setBlobStore(*blob_store) + .create(storage_name, file_provider, delegator, PS::V3::WALConfig::from(config)); +} + +void UniversalPageStorage::write(UniversalWriteBatch && write_batch, const WriteLimiterPtr & write_limiter) const +{ + if (unlikely(write_batch.empty())) + return; + + Stopwatch watch; + SCOPE_EXIT({ GET_METRIC(tiflash_storage_page_write_duration_seconds, type_total).Observe(watch.elapsedSeconds()); }); + auto edit = blob_store->write(write_batch, write_limiter); + page_directory->apply(std::move(edit), write_limiter); +} + +Page UniversalPageStorage::read(const UniversalPageId & page_id, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) const +{ + if (!snapshot) + { + snapshot = this->getSnapshot(""); + } + + auto page_entry = throw_on_not_exist ? page_directory->getByID(page_id, snapshot) : page_directory->getByIDOrNull(page_id, snapshot); + return blob_store->read(page_entry, read_limiter); +} + +UniversalPageMap UniversalPageStorage::read(const UniversalPageIds & page_ids, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) const +{ + if (!snapshot) + { + snapshot = this->getSnapshot(""); + } + + if (throw_on_not_exist) + { + auto page_entries = page_directory->getByIDs(page_ids, snapshot); + return blob_store->read(page_entries, read_limiter); + } + else + { + auto [page_entries, page_ids_not_found] = page_directory->getByIDsOrNull(page_ids, snapshot); + UniversalPageMap page_map = blob_store->read(page_entries, read_limiter); + for (const auto & page_id_not_found : page_ids_not_found) + { + page_map.emplace(page_id_not_found, Page::invalidPage()); + } + return page_map; + } +} + +UniversalPageMap UniversalPageStorage::read(const std::vector & page_fields, const ReadLimiterPtr & read_limiter, SnapshotPtr snapshot, bool throw_on_not_exist) const +{ + if (!snapshot) + { + snapshot = this->getSnapshot(""); + } + + // get the entries from directory, keep track + // for not found page_ids + UniversalPageIds page_ids_not_found; + PS::V3::universal::BlobStoreType::FieldReadInfos read_infos; + for (const auto & [page_id, field_indices] : page_fields) + { + const auto & [id, entry] = throw_on_not_exist ? page_directory->getByID(page_id, snapshot) : page_directory->getByIDOrNull(page_id, snapshot); + + if (entry.isValid()) + { + auto info = PS::V3::universal::BlobStoreType::FieldReadInfo(page_id, entry, field_indices); + read_infos.emplace_back(info); + } + else + { + page_ids_not_found.emplace_back(id); + } + } + + // read page data from blob_store + UniversalPageMap page_map = blob_store->read(read_infos, read_limiter); + for (const auto & page_id_not_found : page_ids_not_found) + { + page_map.emplace(page_id_not_found, Page::invalidPage()); + } + return page_map; +} + +void UniversalPageStorage::traverse(const String & prefix, const std::function & acceptor, SnapshotPtr snapshot) const +{ + if (!snapshot) + { + snapshot = this->getSnapshot(""); + } + + // TODO: This could hold the read lock of `page_directory` for a long time + const auto page_ids = page_directory->getAllPageIdsWithPrefix(prefix, snapshot); + for (const auto & page_id : page_ids) + { + const auto page_id_and_entry = page_directory->getByID(page_id, snapshot); + acceptor(page_id_and_entry.first, blob_store->read(page_id_and_entry)); + } +} + +UniversalPageId UniversalPageStorage::getNormalPageId(const UniversalPageId & page_id, SnapshotPtr snapshot, bool throw_on_not_exist) const +{ + if (!snapshot) + { + snapshot = this->getSnapshot(""); + } + + return page_directory->getNormalPageId(page_id, snapshot, throw_on_not_exist); +} + +DB::PageEntry UniversalPageStorage::getEntry(const UniversalPageId & page_id, SnapshotPtr snapshot) +{ + if (!snapshot) + { + snapshot = this->getSnapshot(""); + } + + try + { + const auto & [id, entry] = page_directory->getByIDOrNull(page_id, snapshot); + (void)id; + PageEntry entry_ret; + entry_ret.file_id = entry.file_id; + entry_ret.offset = entry.offset; + entry_ret.tag = entry.tag; + entry_ret.size = entry.size; + entry_ret.field_offsets = entry.field_offsets; + entry_ret.checksum = entry.checksum; + + return entry_ret; + } + catch (DB::Exception & e) + { + LOG_WARNING(log, "{}", e.message()); + return {.file_id = INVALID_BLOBFILE_ID}; // return invalid PageEntry + } +} + +PageIdU64 UniversalPageStorage::getMaxId() const +{ + return page_directory->getMaxId(); +} + +bool UniversalPageStorage::gc(bool /*not_skip*/, const WriteLimiterPtr & write_limiter, const ReadLimiterPtr & read_limiter) +{ + return manager.gc(*blob_store, *page_directory, write_limiter, read_limiter, log); +} + +void UniversalPageStorage::registerUniversalExternalPagesCallbacks(const UniversalExternalPageCallbacks & callbacks) +{ + manager.registerExternalPagesCallbacks(callbacks); +} +void UniversalPageStorage::unregisterUniversalExternalPagesCallbacks(const String & prefix) +{ + manager.unregisterExternalPagesCallbacks(prefix); + // clean all external ids ptrs + page_directory->unregisterNamespace(prefix); +} +} // namespace DB diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.h b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.h new file mode 100644 index 00000000000..336d4747a74 --- /dev/null +++ b/dbms/src/Storages/Page/V3/Universal/UniversalPageStorage.h @@ -0,0 +1,146 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DB +{ +class FileProvider; +using FileProviderPtr = std::shared_ptr; +class PathCapacityMetrics; +using PathCapacityMetricsPtr = std::shared_ptr; +class PSDiskDelegator; +using PSDiskDelegatorPtr = std::shared_ptr; +class Context; +class WriteLimiter; +using WriteLimiterPtr = std::shared_ptr; +class ReadLimiter; +using ReadLimiterPtr = std::shared_ptr; + +class UniversalPageStorage; +using UniversalPageStoragePtr = std::shared_ptr; + +using UniversalPageMap = std::map; + +class UniversalPageStorage final +{ +public: + using SnapshotPtr = PageStorageSnapshotPtr; + +public: + static UniversalPageStoragePtr + create( + String name, + PSDiskDelegatorPtr delegator, + const PageStorageConfig & config, + const FileProviderPtr & file_provider); + + UniversalPageStorage( + String name, + PSDiskDelegatorPtr delegator_, + const PageStorageConfig & config_, + const FileProviderPtr & file_provider_) + : storage_name(std::move(name)) + , delegator(std::move(delegator_)) + , config(config_) + , file_provider(file_provider_) + , log(Logger::get("UniversalPageStorage", name)) + { + } + + ~UniversalPageStorage() = default; + + void restore(); + + SnapshotPtr getSnapshot(const String & tracing_id) const + { + return page_directory->createSnapshot(tracing_id); + } + + // Get some statistics of all living snapshots and the oldest living snapshot. + SnapshotsStatistics getSnapshotsStat() const + { + return page_directory->getSnapshotsStat(); + } + + FileUsageStatistics getFileUsageStatistics() const + { + auto u = blob_store->getFileUsageStatistics(); + u.merge(page_directory->getFileUsageStatistics()); + return u; + } + + void write(UniversalWriteBatch && write_batch, const WriteLimiterPtr & write_limiter = nullptr) const; + + Page read(const UniversalPageId & page_id, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) const; + + UniversalPageMap read(const UniversalPageIds & page_ids, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) const; + + using FieldIndices = std::vector; + using PageReadFields = std::pair; + + UniversalPageMap read(const std::vector & page_fields, const ReadLimiterPtr & read_limiter = nullptr, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) const; + + void traverse(const String & prefix, const std::function & acceptor, SnapshotPtr snapshot) const; + + UniversalPageId getNormalPageId(const UniversalPageId & page_id, SnapshotPtr snapshot = {}, bool throw_on_not_exist = true) const; + + DB::PageEntry getEntry(const UniversalPageId & page_id, SnapshotPtr snapshot); + + PageIdU64 getMaxId() const; + + // We may skip the GC to reduce useless reading by default. + bool gc(bool not_skip = false, const WriteLimiterPtr & write_limiter = nullptr, const ReadLimiterPtr & read_limiter = nullptr); + + bool isEmpty() const + { + return page_directory->numPages() == 0; + } + + // Register and unregister external pages GC callbacks + // Note that user must ensure that it is safe to call `scanner` and `remover` even after unregister. + void registerUniversalExternalPagesCallbacks(const UniversalExternalPageCallbacks & callbacks); + void unregisterUniversalExternalPagesCallbacks(const String & prefix); + + String storage_name; // Identify between different Storage + PSDiskDelegatorPtr delegator; // Get paths for storing data + PageStorageConfig config; + FileProviderPtr file_provider; + + PS::V3::universal::PageDirectoryPtr page_directory; + + using BlobStorePtr = std::unique_ptr; + BlobStorePtr blob_store; + + PS::V3::universal::ExternalPageCallbacksManager manager; + + LoggerPtr log; +}; + +} // namespace DB diff --git a/dbms/src/Storages/Page/V3/Universal/UniversalWriteBatch.h b/dbms/src/Storages/Page/V3/Universal/UniversalWriteBatch.h new file mode 100644 index 00000000000..bfb09307e40 --- /dev/null +++ b/dbms/src/Storages/Page/V3/Universal/UniversalWriteBatch.h @@ -0,0 +1,193 @@ +// 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 +{ +namespace ErrorCodes +{ +extern const int LOGICAL_ERROR; +} // namespace ErrorCodes + +class UniversalWriteBatch : private boost::noncopyable +{ +private: + struct Write + { + WriteBatchWriteType type; + UniversalPageId page_id; + UInt64 tag; + // Page's data and size + ReadBufferPtr read_buffer; + PageSize size; + // RefPage's origin page + UniversalPageId ori_page_id; + // Fields' offset inside Page's data + PageFieldOffsetChecksums offsets; + }; + using Writes = std::vector; + +public: + UniversalWriteBatch() = default; + + UniversalWriteBatch(UniversalWriteBatch && rhs) + : writes(std::move(rhs.writes)) + , total_data_size(rhs.total_data_size) + {} + + void putPage(const UniversalPageId & page_id, UInt64 tag, const ReadBufferPtr & read_buffer, PageSize size, const PageFieldSizes & data_sizes = {}) + { + // Convert from data_sizes to the offset of each field + PageFieldOffsetChecksums offsets; + PageFieldOffset off = 0; + for (auto data_sz : data_sizes) + { + offsets.emplace_back(off, 0); + off += data_sz; + } + if (unlikely(!data_sizes.empty() && off != size)) + { + throw Exception(fmt::format( + "Try to put Page with fields, but page size and fields total size not match " + "[page_id={}] [num_fields={}] [page_size={}] [all_fields_size={}]", + page_id, + data_sizes.size(), + size, + off), + ErrorCodes::LOGICAL_ERROR); + } + + Write w{WriteBatchWriteType::PUT, page_id, tag, read_buffer, size, "", std::move(offsets)}; + total_data_size += size; + writes.emplace_back(std::move(w)); + } + + void putPage(const UniversalPageId & page_id, UInt64 tag, std::string_view data) + { + auto buffer_ptr = std::make_shared(data); + putPage(page_id, tag, buffer_ptr, data.size()); + } + + void putExternal(const UniversalPageId & page_id, UInt64 tag) + { + // External page's data is not managed by PageStorage, which means data is empty. + Write w{WriteBatchWriteType::PUT_EXTERNAL, page_id, tag, nullptr, 0, "", {}}; + writes.emplace_back(std::move(w)); + } + + // Add RefPage{ref_id} -> Page{page_id} + void putRefPage(const UniversalPageId & ref_id, const UniversalPageId & page_id) + { + Write w{WriteBatchWriteType::REF, ref_id, 0, nullptr, 0, page_id, {}}; + writes.emplace_back(std::move(w)); + } + + void delPage(const UniversalPageId & page_id) + { + Write w{WriteBatchWriteType::DEL, page_id, 0, nullptr, 0, "", {}}; + writes.emplace_back(std::move(w)); + } + + bool empty() const + { + return writes.empty(); + } + + const Writes & getWrites() const + { + return writes; + } + Writes & getWrites() + { + return writes; + } + + size_t putWriteCount() const + { + size_t count = 0; + for (const auto & w : writes) + count += (w.type == WriteBatchWriteType::PUT); + return count; + } + + void swap(UniversalWriteBatch & o) + { + writes.swap(o.writes); + std::swap(o.total_data_size, total_data_size); + } + + void merge(UniversalWriteBatch & rhs) + { + writes.reserve(writes.size() + rhs.writes.size()); + for (const auto & r : rhs.writes) + { + writes.emplace_back(r); + } + total_data_size += rhs.total_data_size; + } + + void clear() + { + Writes tmp; + writes.swap(tmp); + total_data_size = 0; + } + + size_t getTotalDataSize() const + { + return total_data_size; + } + + static const UniversalPageId & getFullPageId(const UniversalPageId & id) { return id; } + + String toString() const + { + FmtBuffer fmt_buffer; + fmt_buffer.joinStr( + writes.begin(), + writes.end(), + [](const auto & w, FmtBuffer & fb) { + switch (w.type) + { + case WriteBatchWriteType::PUT: + fb.fmtAppend("{}", w.page_id); + break; + case WriteBatchWriteType::REF: + fb.fmtAppend("{} > {}", w.page_id, w.ori_page_id); + break; + case WriteBatchWriteType::DEL: + fb.fmtAppend("X{}", w.page_id); + break; + case WriteBatchWriteType::PUT_EXTERNAL: + fb.fmtAppend("E{}", w.page_id); + break; + default: + fb.fmtAppend("Unknown {}", w.page_id); + break; + }; + }, + ","); + return fmt_buffer.toString(); + } + +private: + Writes writes; + size_t total_data_size = 0; +}; +} // namespace DB diff --git a/dbms/src/Storages/Page/V3/Universal/tests/gtest_universal_page_storage.cpp b/dbms/src/Storages/Page/V3/Universal/tests/gtest_universal_page_storage.cpp new file mode 100644 index 00000000000..b78591beab5 --- /dev/null +++ b/dbms/src/Storages/Page/V3/Universal/tests/gtest_universal_page_storage.cpp @@ -0,0 +1,247 @@ +// 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 + +namespace DB +{ +namespace PS::universal::tests +{ +class UniPageStorageTest : public DB::base::TiFlashStorageTestBasic +{ +public: + void SetUp() override + { + TiFlashStorageTestBasic::SetUp(); + auto path = getTemporaryPath(); + createIfNotExist(path); + file_provider = DB::tests::TiFlashTestEnv::getGlobalContext().getFileProvider(); + delegator = std::make_shared(path); + page_storage = UniversalPageStorage::create("test.t", delegator, config, file_provider); + page_storage->restore(); + + for (size_t i = 0; i < buf_sz; ++i) + { + c_buff[i] = i % 0xff; + } + + log = Logger::get("PageStorageTest"); + } + + std::shared_ptr reopenWithConfig(const PageStorageConfig & config_) + { + auto path = getTemporaryPath(); + delegator = std::make_shared(path); + auto storage = UniversalPageStorage::create("test.t", delegator, config_, file_provider); + storage->restore(); + return storage; + } + +protected: + FileProviderPtr file_provider; + PSDiskDelegatorPtr delegator; + PageStorageConfig config; + std::shared_ptr page_storage; + + LoggerPtr log; + + static constexpr size_t buf_sz = 1024; + char c_buff[buf_sz] = {}; +}; + +TEST_F(UniPageStorageTest, WriteRead) +try +{ + const String prefix = "aaa"; + const UInt64 tag = 0; + for (size_t i = 0; i < buf_sz; ++i) + { + c_buff[i] = i % 0xff; + } + + { + UniversalWriteBatch wb; + wb.putPage(UniversalPageId::toFullPageId(prefix, 0), tag, std::make_shared(c_buff, buf_sz), buf_sz); + wb.putPage(UniversalPageId::toFullPageId(prefix, 21), tag, std::make_shared(c_buff, buf_sz), buf_sz); + wb.putPage(UniversalPageId::toFullPageId(prefix, 200), tag, std::make_shared(c_buff, buf_sz), buf_sz); + page_storage->write(std::move(wb)); + } + + DB::Page page0 = page_storage->read(UniversalPageId::toFullPageId(prefix, 0)); + ASSERT_TRUE(page0.isValid()); + ASSERT_EQ(page0.data.size(), buf_sz); + ASSERT_EQ(page0.page_id, 0UL); + for (size_t i = 0; i < buf_sz; ++i) + { + EXPECT_EQ(*(page0.data.begin() + i), static_cast(i % 0xff)); + } + DB::Page page1 = page_storage->read(UniversalPageId::toFullPageId(prefix, 21)); + ASSERT_TRUE(page1.isValid()); + ASSERT_EQ(page1.data.size(), buf_sz); + ASSERT_EQ(page1.page_id, 21UL); + for (size_t i = 0; i < buf_sz; ++i) + { + EXPECT_EQ(*(page1.data.begin() + i), static_cast(i % 0xff)); + } + DB::Page page2 = page_storage->read(UniversalPageId::toFullPageId(prefix, 500), nullptr, {}, false); + ASSERT_TRUE(!page2.isValid()); +} +CATCH + +TEST_F(UniPageStorageTest, Traverse) +{ + const String prefix1 = "aaa"; + const String prefix2 = "bbbb"; + const String prefix3 = "zzzzzzzzz"; + const UInt64 tag = 0; + const size_t write_count = 100; + { + UniversalWriteBatch wb; + for (size_t i = 0; i < write_count; i++) + { + c_buff[0] = 10; + c_buff[1] = i; + wb.putPage(UniversalPageId::toFullPageId(prefix1, i), tag, std::make_shared(c_buff, buf_sz), buf_sz); + } + page_storage->write(std::move(wb)); + } + + { + UniversalWriteBatch wb; + for (size_t i = 0; i < write_count; i++) + { + c_buff[0] = 10; + c_buff[1] = i; + wb.putPage(UniversalPageId::toFullPageId(prefix2, i), tag, std::make_shared(c_buff, buf_sz), buf_sz); + } + page_storage->write(std::move(wb)); + } + + { + size_t read_count = 0; + auto checker = [&](const UniversalPageId & page_id, const DB::Page & page) { + ASSERT_TRUE(page_id.isPrefix(prefix1)); + ASSERT_TRUE(page.isValid()); + read_count += 1; + }; + page_storage->traverse(prefix1, checker, {}); + ASSERT_EQ(read_count, write_count); + } + + { + size_t read_count = 0; + auto checker = [&](const UniversalPageId & page_id, const DB::Page & page) { + ASSERT_TRUE(page_id.isPrefix(prefix2)); + ASSERT_TRUE(page.isValid()); + read_count += 1; + }; + page_storage->traverse(prefix2, checker, {}); + ASSERT_EQ(read_count, write_count); + } + + { + size_t read_count = 0; + auto checker = [&](const UniversalPageId & page_id, const DB::Page & page) { + ASSERT_TRUE(page_id.isPrefix(prefix3)); + ASSERT_TRUE(page.isValid()); + read_count += 1; + }; + page_storage->traverse(prefix3, checker, {}); + ASSERT_EQ(read_count, 0); + } +} + +TEST_F(UniPageStorageTest, TraverseWithSnap) +{ + const String prefix1 = "aaa"; + const UInt64 tag = 0; + const size_t write_count = 100; + { + UniversalWriteBatch wb; + for (size_t i = 0; i < write_count; i++) + { + c_buff[0] = 10; + c_buff[1] = i; + wb.putPage(UniversalPageId::toFullPageId(prefix1, i), tag, std::make_shared(c_buff, buf_sz), buf_sz); + } + page_storage->write(std::move(wb)); + } + + auto snap = page_storage->getSnapshot("UniPageStorageTest"); + // write more after create snap + { + UniversalWriteBatch wb; + for (size_t i = write_count; i < 2 * write_count; i++) + { + c_buff[0] = 10; + c_buff[1] = i; + wb.putPage(UniversalPageId::toFullPageId(prefix1, i), tag, std::make_shared(c_buff, buf_sz), buf_sz); + } + page_storage->write(std::move(wb)); + } + + { + size_t read_count = 0; + auto checker = [&](const UniversalPageId & page_id, const DB::Page & page) { + ASSERT_TRUE(page_id.isPrefix(prefix1)); + ASSERT_TRUE(page.isValid()); + read_count += 1; + }; + page_storage->traverse(prefix1, checker, snap); + ASSERT_EQ(read_count, write_count); + } + + // delete some pages + { + UniversalWriteBatch wb; + for (size_t i = 0; i < write_count; i++) + { + c_buff[0] = 10; + c_buff[1] = i; + wb.delPage(UniversalPageId::toFullPageId(prefix1, i)); + } + page_storage->write(std::move(wb)); + } + + { + size_t read_count = 0; + auto checker = [&](const UniversalPageId & page_id, const DB::Page & page) { + ASSERT_TRUE(page_id.isPrefix(prefix1)); + ASSERT_TRUE(page.isValid()); + read_count += 1; + }; + page_storage->traverse(prefix1, checker, snap); + ASSERT_EQ(read_count, write_count); + } +} + +TEST(UniPageStorageIdTest, UniversalPageId) +{ + { + auto u_id = UniversalPageId::toFullPageId("aaa", 100); + ASSERT_EQ(DB::PS::V3::universal::PageIdTrait::getU64ID(u_id), 100); + ASSERT_EQ(DB::PS::V3::universal::PageIdTrait::getPrefix(u_id), "aaa"); + } + + { + auto u_id = "z"; + ASSERT_EQ(DB::PS::V3::universal::PageIdTrait::getU64ID(u_id), 0); + ASSERT_EQ(DB::PS::V3::universal::PageIdTrait::getPrefix(u_id), ""); + } +} +} // namespace PS::universal::tests +} // namespace DB diff --git a/dbms/src/Storages/Page/V3/WAL/WALConfig.h b/dbms/src/Storages/Page/V3/WAL/WALConfig.h index b4cd3256707..8dac502127a 100644 --- a/dbms/src/Storages/Page/V3/WAL/WALConfig.h +++ b/dbms/src/Storages/Page/V3/WAL/WALConfig.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include namespace DB::PS::V3 @@ -42,7 +42,7 @@ struct WALConfig wal_recover_mode = recover_mode; } - WALRecoveryMode getRecoverMode() + WALRecoveryMode getRecoverMode() const { return static_cast(wal_recover_mode.get()); } diff --git a/dbms/src/Storages/Page/V3/WAL/serialize.cpp b/dbms/src/Storages/Page/V3/WAL/serialize.cpp index abd08ae4e1e..016648c8036 100644 --- a/dbms/src/Storages/Page/V3/WAL/serialize.cpp +++ b/dbms/src/Storages/Page/V3/WAL/serialize.cpp @@ -15,15 +15,17 @@ #include #include #include -#include +#include #include #include +#include #include #include #include +#include -namespace DB::PS::V3::ser +namespace DB::PS::V3 { inline void serializeVersionTo(const PageVersion & version, WriteBuffer & buf) { @@ -80,7 +82,20 @@ inline void deserializeEntryFrom(ReadBuffer & buf, PageEntryV3 & entry) } } -void serializePutTo(const PageEntriesEdit::EditRecord & record, WriteBuffer & buf) +inline void deserializeUniversalPageIDFrom(ReadBuffer & buf, UniversalPageId & page_id) +{ + String s_id; + readStringBinary(s_id, buf); + page_id = std::move(s_id); +} + +inline void deserializeUInt128PageIDFrom(ReadBuffer & buf, PageIdV3Internal & page_id) +{ + readIntBinary(page_id, buf); +} + +template +void serializePutTo(const EditRecord & record, WriteBuffer & buf) { assert(record.type == EditRecordType::PUT || record.type == EditRecordType::UPSERT || record.type == EditRecordType::VAR_ENTRY); @@ -88,23 +103,38 @@ void serializePutTo(const PageEntriesEdit::EditRecord & record, WriteBuffer & bu UInt32 flags = 0; writeIntBinary(flags, buf); - writeIntBinary(record.page_id, buf); + if constexpr (std::is_same_v) + { + writeIntBinary(record.page_id, buf); + } + else if constexpr (std::is_same_v) + { + writeStringBinary(record.page_id.asStr(), buf); + } serializeVersionTo(record.version, buf); writeIntBinary(record.being_ref_count, buf); serializeEntryTo(record.entry, buf); } -void deserializePutFrom([[maybe_unused]] const EditRecordType record_type, ReadBuffer & buf, PageEntriesEdit & edit) +template +void deserializePutFrom([[maybe_unused]] const EditRecordType record_type, ReadBuffer & buf, EditType & edit) { assert(record_type == EditRecordType::PUT || record_type == EditRecordType::UPSERT || record_type == EditRecordType::VAR_ENTRY); UInt32 flags = 0; readIntBinary(flags, buf); - PageEntriesEdit::EditRecord rec; + typename EditType::EditRecord rec; rec.type = record_type; - readIntBinary(rec.page_id, buf); + if constexpr (std::is_same_v) + { + deserializeUInt128PageIDFrom(buf, rec.page_id); + } + else if constexpr (std::is_same_v) + { + deserializeUniversalPageIDFrom(buf, rec.page_id); + } deserializeVersionFrom(buf, rec.version); readIntBinary(rec.being_ref_count, buf); @@ -112,81 +142,126 @@ void deserializePutFrom([[maybe_unused]] const EditRecordType record_type, ReadB edit.appendRecord(rec); } -void serializeRefTo(const PageEntriesEdit::EditRecord & record, WriteBuffer & buf) +template +void serializeRefTo(const EditRecord & record, WriteBuffer & buf) { assert(record.type == EditRecordType::REF || record.type == EditRecordType::VAR_REF); writeIntBinary(record.type, buf); - writeIntBinary(record.page_id, buf); - writeIntBinary(record.ori_page_id, buf); + if constexpr (std::is_same_v) + { + writeIntBinary(record.page_id, buf); + writeIntBinary(record.ori_page_id, buf); + } + else if constexpr (std::is_same_v) + { + writeStringBinary(record.page_id.asStr(), buf); + writeStringBinary(record.ori_page_id.asStr(), buf); + } serializeVersionTo(record.version, buf); assert(record.entry.file_id == INVALID_BLOBFILE_ID); } -void deserializeRefFrom([[maybe_unused]] const EditRecordType record_type, ReadBuffer & buf, PageEntriesEdit & edit) +template +void deserializeRefFrom([[maybe_unused]] const EditRecordType record_type, ReadBuffer & buf, EditType & edit) { assert(record_type == EditRecordType::REF || record_type == EditRecordType::VAR_REF); - PageEntriesEdit::EditRecord rec; + typename EditType::EditRecord rec; rec.type = record_type; - readIntBinary(rec.page_id, buf); - readIntBinary(rec.ori_page_id, buf); + if constexpr (std::is_same_v) + { + deserializeUInt128PageIDFrom(buf, rec.page_id); + deserializeUInt128PageIDFrom(buf, rec.ori_page_id); + } + else if constexpr (std::is_same_v) + { + deserializeUniversalPageIDFrom(buf, rec.page_id); + deserializeUniversalPageIDFrom(buf, rec.ori_page_id); + } deserializeVersionFrom(buf, rec.version); edit.appendRecord(rec); } - -void serializePutExternalTo(const PageEntriesEdit::EditRecord & record, WriteBuffer & buf) +template +void serializePutExternalTo(const EditRecord & record, WriteBuffer & buf) { assert(record.type == EditRecordType::PUT_EXTERNAL || record.type == EditRecordType::VAR_EXTERNAL); writeIntBinary(record.type, buf); - writeIntBinary(record.page_id, buf); + if constexpr (std::is_same_v) + { + writeIntBinary(record.page_id, buf); + } + else if constexpr (std::is_same_v) + { + writeStringBinary(record.page_id.asStr(), buf); + } serializeVersionTo(record.version, buf); writeIntBinary(record.being_ref_count, buf); } -void deserializePutExternalFrom([[maybe_unused]] const EditRecordType record_type, ReadBuffer & buf, PageEntriesEdit & edit) +template +void deserializePutExternalFrom([[maybe_unused]] const EditRecordType record_type, ReadBuffer & buf, EditType & edit) { assert(record_type == EditRecordType::PUT_EXTERNAL || record_type == EditRecordType::VAR_EXTERNAL); - PageEntriesEdit::EditRecord rec; + typename EditType::EditRecord rec; rec.type = record_type; - readIntBinary(rec.page_id, buf); + if constexpr (std::is_same_v) + { + deserializeUInt128PageIDFrom(buf, rec.page_id); + } + else if constexpr (std::is_same_v) + { + deserializeUniversalPageIDFrom(buf, rec.page_id); + } deserializeVersionFrom(buf, rec.version); readIntBinary(rec.being_ref_count, buf); edit.appendRecord(rec); } -void serializeDelTo(const PageEntriesEdit::EditRecord & record, WriteBuffer & buf) +template +void serializeDelTo(const EditRecord & record, WriteBuffer & buf) { assert(record.type == EditRecordType::DEL || record.type == EditRecordType::VAR_DELETE); writeIntBinary(record.type, buf); - writeIntBinary(record.page_id, buf); + if constexpr (std::is_same_v) + { + writeIntBinary(record.page_id, buf); + } + else if constexpr (std::is_same_v) + { + writeStringBinary(record.page_id.asStr(), buf); + } serializeVersionTo(record.version, buf); } -void deserializeDelFrom([[maybe_unused]] const EditRecordType record_type, ReadBuffer & buf, PageEntriesEdit & edit) +template +void deserializeDelFrom([[maybe_unused]] const EditRecordType record_type, ReadBuffer & buf, EditType & edit) { assert(record_type == EditRecordType::DEL || record_type == EditRecordType::VAR_DELETE); - PageIdV3Internal page_id; - readIntBinary(page_id, buf); - PageVersion version; - deserializeVersionFrom(buf, version); - - PageEntriesEdit::EditRecord rec; + typename EditType::EditRecord rec; rec.type = record_type; - rec.page_id = page_id; - rec.version = version; + if constexpr (std::is_same_v) + { + deserializeUInt128PageIDFrom(buf, rec.page_id); + } + else if constexpr (std::is_same_v) + { + deserializeUniversalPageIDFrom(buf, rec.page_id); + } + deserializeVersionFrom(buf, rec.version); edit.appendRecord(rec); } -void deserializeFrom(ReadBuffer & buf, PageEntriesEdit & edit) +template +void deserializeFrom(ReadBuffer & buf, EditType & edit) { EditRecordType record_type; while (!buf.eof()) @@ -225,7 +300,8 @@ void deserializeFrom(ReadBuffer & buf, PageEntriesEdit & edit) } } -String serializeTo(const PageEntriesEdit & edit) +template +String Serializer::serializeTo(const PageEntriesEdit & edit) { WriteBufferFromOwnString buf; UInt32 version = 1; @@ -254,9 +330,10 @@ String serializeTo(const PageEntriesEdit & edit) } } return buf.releaseStr(); -} +}; -PageEntriesEdit deserializeFrom(std::string_view record) +template +PageEntriesEdit Serializer::deserializeFrom(std::string_view record) { PageEntriesEdit edit; ReadBufferFromMemory buf(record.data(), record.size()); @@ -265,8 +342,10 @@ PageEntriesEdit deserializeFrom(std::string_view record) if (version != 1) throw Exception(fmt::format("Unknown version for PageEntriesEdit deser [version={}]", version), ErrorCodes::LOGICAL_ERROR); - deserializeFrom(buf, edit); + DB::PS::V3::deserializeFrom(buf, edit); return edit; -} +}; -} // namespace DB::PS::V3::ser +template struct Serializer; +template struct Serializer; +} // namespace DB::PS::V3 diff --git a/dbms/src/Storages/Page/V3/WAL/serialize.h b/dbms/src/Storages/Page/V3/WAL/serialize.h index 4f37970a841..7d25aca1147 100644 --- a/dbms/src/Storages/Page/V3/WAL/serialize.h +++ b/dbms/src/Storages/Page/V3/WAL/serialize.h @@ -18,9 +18,21 @@ #include -namespace DB::PS::V3::ser +namespace DB::PS::V3 { -String serializeTo(const PageEntriesEdit & edit); -PageEntriesEdit deserializeFrom(std::string_view record); +template +struct Serializer +{ + static String serializeTo(const PageEntriesEdit & edit); + static PageEntriesEdit deserializeFrom(std::string_view record); +}; -} // namespace DB::PS::V3::ser +namespace u128 +{ +using Serializer = Serializer; +} // namespace u128 +namespace universal +{ +using Serializer = Serializer; +} // namespace universal +} // namespace DB::PS::V3 diff --git a/dbms/src/Storages/Page/V3/WALStore.cpp b/dbms/src/Storages/Page/V3/WALStore.cpp index 574ea374e55..77e7cf00619 100644 --- a/dbms/src/Storages/Page/V3/WALStore.cpp +++ b/dbms/src/Storages/Page/V3/WALStore.cpp @@ -19,10 +19,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V3/tests/entries_helper.h b/dbms/src/Storages/Page/V3/tests/entries_helper.h index a651bfc5e04..d980aa481c6 100644 --- a/dbms/src/Storages/Page/V3/tests/entries_helper.h +++ b/dbms/src/Storages/Page/V3/tests/entries_helper.h @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -81,7 +81,7 @@ inline ::testing::AssertionResult getEntryCompare( const char * page_id_expr, const char * snap_expr, const PageEntryV3 & expected_entry, - const PageDirectoryPtr & dir, + const u128::PageDirectoryPtr & dir, const PageIdV3Internal page_id, const PageDirectorySnapshotPtr & snap) { @@ -140,7 +140,7 @@ inline ::testing::AssertionResult getEntriesCompare( const char * page_ids_expr, const char * snap_expr, const PageIDAndEntriesV3 & expected_entries, - const PageDirectoryPtr & dir, + const u128::PageDirectoryPtr & dir, const PageIdV3Internals page_ids, const PageDirectorySnapshotPtr & snap) { @@ -214,7 +214,7 @@ inline ::testing::AssertionResult getEntryNotExist( const char * dir_expr, const char * page_id_expr, const char * snap_expr, - const PageDirectoryPtr & dir, + const u128::PageDirectoryPtr & dir, const PageIdV3Internal page_id, const PageDirectorySnapshotPtr & snap) { @@ -254,7 +254,7 @@ inline ::testing::AssertionResult getEntriesNotExist( const char * dir_expr, const char * page_ids_expr, const char * snap_expr, - const PageDirectoryPtr & dir, + const u128::PageDirectoryPtr & dir, const PageIdV3Internals page_ids, const PageDirectorySnapshotPtr & snap) { diff --git a/dbms/src/Storages/Page/V3/tests/gtest_blob_stat.cpp b/dbms/src/Storages/Page/V3/tests/gtest_blob_stat.cpp index ced58f07186..0be516ac20c 100644 --- a/dbms/src/Storages/Page/V3/tests/gtest_blob_stat.cpp +++ b/dbms/src/Storages/Page/V3/tests/gtest_blob_stat.cpp @@ -14,8 +14,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp b/dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp index 52bbcfc393d..02dcc4ecbec 100644 --- a/dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp +++ b/dbms/src/Storages/Page/V3/tests/gtest_blob_store.cpp @@ -16,8 +16,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -30,7 +30,8 @@ namespace DB::PS::V3::tests { - +using u128::PageEntriesEdit; +using BlobStore = BlobStore; constexpr size_t path_num = 3; class BlobStoreTest : public DB::base::TiFlashStorageTestBasic @@ -146,7 +147,7 @@ try // Generate blob [1,2,3] auto write_blob_datas = [](BlobStore & blob_store) { WriteBatch write_batch; - PageId page_id = 55; + PageIdU64 page_id = 55; size_t buff_size = 1024; char c_buff[buff_size]; memset(c_buff, 0x1, buff_size); @@ -305,7 +306,7 @@ TEST_F(BlobStoreTest, testWriteRead) { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId page_id = 50; + PageIdU64 page_id = 50; size_t buff_nums = 21; size_t buff_size = 123; @@ -389,7 +390,7 @@ TEST_F(BlobStoreTest, testWriteReadWithIOLimiter) { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId page_id = 50; + PageIdU64 page_id = 50; size_t wb_nums = 5; size_t buff_size = 10ul * 1024; const size_t rate_target = buff_size - 1; @@ -500,9 +501,9 @@ try { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId page_id1 = 50; - PageId page_id2 = 51; - PageId page_id3 = 53; + PageIdU64 page_id1 = 50; + PageIdU64 page_id2 = 51; + PageIdU64 page_id3 = 53; size_t buff_size = 120; WriteBatch wb; @@ -567,7 +568,7 @@ TEST_F(BlobStoreTest, testFeildOffsetWriteRead) { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId page_id = 50; + PageIdU64 page_id = 50; size_t buff_size = 20; size_t buff_nums = 5; PageFieldSizes field_sizes = {1, 2, 3, 4, 5, 2, 1, 1, 1}; @@ -639,7 +640,7 @@ try const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); auto blob_store = BlobStore(getCurrentTestName(), file_provider, delegator, config); - PageId page_id = 50; + PageIdU64 page_id = 50; const size_t buff_size = 1024; WriteBatch wb; { @@ -814,7 +815,7 @@ TEST_F(BlobStoreTest, testBlobStoreGcStats) const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); size_t buff_size = 1024; size_t buff_nums = 10; - PageId page_id = 50; + PageIdU64 page_id = 50; auto blob_store = BlobStore(getCurrentTestName(), file_provider, delegator, config); std::list remove_entries_idx1 = {1, 3, 4, 7, 9}; std::list remove_entries_idx2 = {6, 8}; @@ -910,7 +911,7 @@ TEST_F(BlobStoreTest, testBlobStoreGcStats2) const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); size_t buff_size = 1024; size_t buff_nums = 10; - PageId page_id = 50; + PageIdU64 page_id = 50; auto blob_store = BlobStore(getCurrentTestName(), file_provider, delegator, config); std::list remove_entries_idx = {0, 1, 2, 3, 4, 5, 6, 7}; @@ -967,7 +968,7 @@ TEST_F(BlobStoreTest, testBlobStoreGcStats2) TEST_F(BlobStoreTest, GC) { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId page_id = 50; + PageIdU64 page_id = 50; size_t buff_nums = 21; size_t buff_size = 123; @@ -991,12 +992,12 @@ TEST_F(BlobStoreTest, GC) PageEntriesEdit edit = blob_store.write(wb, nullptr); ASSERT_EQ(edit.size(), buff_nums); - PageIdAndVersionedEntries versioned_pageid_entries; + PageDirectory::GcEntries versioned_pageid_entries; for (const auto & record : edit.getRecords()) { versioned_pageid_entries.emplace_back(buildV3Id(TEST_NAMESPACE_ID, page_id), 1, record.entry); } - std::map gc_context; + PageDirectory::GcEntriesMap gc_context; gc_context[1] = versioned_pageid_entries; // Before we do BlobStore we need change BlobFile0 to Read-Only @@ -1032,8 +1033,8 @@ TEST_F(BlobStoreTest, GCMigirateBigData) try { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId fixed_page_id = 50; - PageId page_id = fixed_page_id; + PageIdU64 fixed_page_id = 50; + PageIdU64 page_id = fixed_page_id; size_t buff_nums = 20; size_t buff_size = 20; @@ -1044,7 +1045,7 @@ try WriteBatch wb; - std::map gc_context; + PageDirectory::GcEntriesMap gc_context; for (size_t i = 0; i < buff_nums; ++i) { @@ -1061,7 +1062,7 @@ try ASSERT_EQ(records.size(), 1); if (gc_context.find(records[0].entry.file_id) == gc_context.end()) { - PageIdAndVersionedEntries versioned_pageid_entries; + PageDirectory::GcEntries versioned_pageid_entries; versioned_pageid_entries.emplace_back(page_id, 1, records[0].entry); gc_context[records[0].entry.file_id] = std::move(versioned_pageid_entries); } @@ -1083,8 +1084,8 @@ TEST_F(BlobStoreTest, ReadByFieldReadInfos) try { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId fixed_page_id = 50; - PageId page_id = fixed_page_id; + PageIdU64 fixed_page_id = 50; + PageIdU64 page_id = fixed_page_id; size_t buff_nums = 20; size_t buff_size = 20; @@ -1119,8 +1120,8 @@ try auto page_map = blob_store.read(read_infos); for (size_t i = 0; i < buff_nums; ++i) { - PageId reading_id = fixed_page_id + i; - Page page = page_map[reading_id]; + PageIdU64 reading_id = fixed_page_id + i; + Page page = page_map.at(reading_id); ASSERT_EQ(page.fieldSize(), 5); } } @@ -1130,8 +1131,8 @@ TEST_F(BlobStoreTest, TestBigBlob) try { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId fixed_page_id = 50; - PageId page_id = fixed_page_id; + PageIdU64 fixed_page_id = 50; + PageIdU64 page_id = fixed_page_id; BlobConfig config_with_small_file_limit_size; config_with_small_file_limit_size.file_limit_size = 400; @@ -1296,8 +1297,8 @@ TEST_F(BlobStoreTest, TestBigBlobRemove) try { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId fixed_page_id = 50; - PageId page_id = fixed_page_id; + PageIdU64 fixed_page_id = 50; + PageIdU64 page_id = fixed_page_id; BlobConfig config_with_small_file_limit_size; config_with_small_file_limit_size.file_limit_size = 400; @@ -1328,8 +1329,8 @@ TEST_F(BlobStoreTest, TestBigBlobRegisterPath) try { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId fixed_page_id = 50; - PageId page_id = fixed_page_id; + PageIdU64 fixed_page_id = 50; + PageIdU64 page_id = fixed_page_id; BlobConfig config_with_small_file_limit_size; config_with_small_file_limit_size.file_limit_size = 400; @@ -1368,7 +1369,7 @@ TEST_F(BlobStoreTest, TestRestartWithSmallerFileLimitSize) try { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId page_id = 50; + PageIdU64 page_id = 50; BlobConfig config_with_small_file_limit_size; config_with_small_file_limit_size.file_limit_size = 800; @@ -1438,9 +1439,9 @@ TEST_F(BlobStoreTest, TestBigBlobGC) try { const auto file_provider = DB::tests::TiFlashTestEnv::getContext().getFileProvider(); - PageId page_id1 = 50; - PageId page_id2 = 51; - PageId page_id3 = 52; + PageIdU64 page_id1 = 50; + PageIdU64 page_id2 = 51; + PageIdU64 page_id3 = 52; BlobConfig config_with_small_file_limit_size; config_with_small_file_limit_size.file_limit_size = 800; @@ -1491,8 +1492,8 @@ try const auto & blob_need_gc2 = blob_store.getGCStats(); ASSERT_EQ(blob_need_gc2.size(), 1); - std::map gc_context; - PageIdAndVersionedEntries versioned_pageid_entries; + PageDirectory::GcEntriesMap gc_context; + PageDirectory::GcEntries versioned_pageid_entries; versioned_pageid_entries.emplace_back(page_id2, 1, entry_from_write2); gc_context[1] = versioned_pageid_entries; PageEntriesEdit gc_edit = blob_store.gc(gc_context, 500); diff --git a/dbms/src/Storages/Page/V3/tests/gtest_page_directory.cpp b/dbms/src/Storages/Page/V3/tests/gtest_page_directory.cpp index 7f9c59b7902..94ca37a5cbf 100644 --- a/dbms/src/Storages/Page/V3/tests/gtest_page_directory.cpp +++ b/dbms/src/Storages/Page/V3/tests/gtest_page_directory.cpp @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -47,10 +47,12 @@ namespace DB { namespace PS::V3::tests { +using u128::PageEntriesEdit; + TEST(ExternalIdsByNamespaceTest, Simple) { NamespaceId ns_id = 100; - ExternalIdsByNamespace external_ids_by_ns; + ExternalIdsByNamespace external_ids_by_ns; { ASSERT_FALSE(external_ids_by_ns.existNamespace(ns_id)); @@ -112,28 +114,28 @@ class PageDirectoryTest : public DB::base::TiFlashStorageTestBasic dir = restoreFromDisk(); } - static PageDirectoryPtr restoreFromDisk() + static u128::PageDirectoryPtr restoreFromDisk() { auto path = getTemporaryPath(); auto ctx = DB::tests::TiFlashTestEnv::getContext(); FileProviderPtr provider = ctx.getFileProvider(); PSDiskDelegatorPtr delegator = std::make_shared(path); - PageDirectoryFactory factory; + PageDirectoryFactory factory; return factory.create("PageDirectoryTest", provider, delegator, WALConfig()); } protected: - static PageId getNormalPageIdU64(const PageDirectoryPtr & d, PageId page_id, const PageDirectorySnapshotPtr & snap) + static PageIdU64 getNormalPageIdU64(const u128::PageDirectoryPtr & d, PageIdU64 page_id, const PageDirectorySnapshotPtr & snap) { return d->getNormalPageId(buildV3Id(TEST_NAMESPACE_ID, page_id), snap, true).low; } - static PageEntryV3 getEntry(const PageDirectoryPtr & d, PageId page_id, const PageDirectorySnapshotPtr & snap) + static PageEntryV3 getEntry(const u128::PageDirectoryPtr & d, PageIdU64 page_id, const PageDirectorySnapshotPtr & snap) { return d->getByID(buildV3Id(TEST_NAMESPACE_ID, page_id), snap).second; } protected: - PageDirectoryPtr dir; + u128::PageDirectoryPtr dir; LoggerPtr log; }; @@ -187,7 +189,7 @@ TEST_F(PageDirectoryTest, ApplyPutWithIdenticalPages) try { // Put identical page in different `edit` - PageId page_id = 50; + PageIdU64 page_id = 50; auto snap0 = dir->createSnapshot(); EXPECT_ENTRY_NOT_EXIST(dir, page_id, snap0); @@ -714,7 +716,7 @@ CATCH TEST_F(PageDirectoryTest, NewRefAfterDelRandom) try { - PageId id = 50; + PageIdU64 id = 50; PageEntryV3 entry1{.file_id = 1, .size = 1024, .padded_size = 0, .tag = 0, .offset = 0x123, .checksum = 0x4567}; { PageEntriesEdit edit; @@ -722,7 +724,7 @@ try dir->apply(std::move(edit)); } - std::unordered_set visible_page_ids{ + std::unordered_set visible_page_ids{ id, }; @@ -740,7 +742,7 @@ try // Generate new ref operations to the visible pages const size_t num_ref_page = distrib(gen) + 1; - std::unordered_map new_ref_page_ids; + std::unordered_map new_ref_page_ids; std::uniform_int_distribution<> rand_visible_ids(0, visible_page_ids.size() - 1); for (size_t j = 0; j < num_ref_page; ++j) { @@ -754,12 +756,12 @@ try // Delete 1 page at least, delete until 1 page left at most std::uniform_int_distribution<> rand_delete_ids(0, visible_page_ids.size() + num_ref_page - 1); const size_t num_del_page = std::min(std::max(rand_delete_ids(gen), 1), visible_page_ids.size() + num_ref_page - 1); - std::unordered_set delete_ref_page_ids; + std::unordered_set delete_ref_page_ids; for (size_t j = 0; j < num_del_page; ++j) { // Random choose a id from all visible id and new-generated ref pages. auto r = rand_delete_ids(gen); - PageId id_to_del = 0; + PageIdU64 id_to_del = 0; if (static_cast(r) < visible_page_ids.size()) { auto rand_it = std::next(std::begin(visible_page_ids), r); @@ -811,9 +813,9 @@ try if (gc_or_not) dir->gcInMemEntries(/*return_removed_entries=*/false); auto snap = dir->createSnapshot(); - for (const auto & id : visible_page_ids) + for (const auto & cur_id : visible_page_ids) { - ASSERT_ENTRY_EQ(entry1, dir, id, snap); + ASSERT_ENTRY_EQ(entry1, dir, cur_id, snap); } } } @@ -822,14 +824,14 @@ CATCH TEST_F(PageDirectoryTest, NewRefToExtAfterDelRandom) try { - PageId id = 50; + PageIdU64 id = 50; { PageEntriesEdit edit; edit.putExternal(buildV3Id(TEST_NAMESPACE_ID, id)); dir->apply(std::move(edit)); } - std::unordered_set visible_page_ids{ + std::unordered_set visible_page_ids{ id, }; @@ -846,7 +848,7 @@ try LOG_DEBUG(log, "round={}, del_in_same_wb={}, gc_or_not={}, visible_ids_num={}", test_round, del_in_same_wb, gc_or_not, visible_page_ids.size()); const size_t num_ref_page = distrib(gen) + 1; - std::unordered_map new_ref_page_ids; + std::unordered_map new_ref_page_ids; std::uniform_int_distribution<> rand_visible_ids(0, visible_page_ids.size() - 1); for (size_t j = 0; j < num_ref_page; ++j) { @@ -859,7 +861,7 @@ try // Delete 1 page at least, delete until 1 page left at most std::uniform_int_distribution<> rand_delete_ids(0, visible_page_ids.size() + num_ref_page - 1); const size_t num_del_page = std::min(std::max(rand_delete_ids(gen), 1), visible_page_ids.size() + num_ref_page - 1); - std::unordered_set delete_ref_page_ids; + std::unordered_set delete_ref_page_ids; for (size_t j = 0; j < num_del_page; ++j) { auto r = rand_delete_ids(gen); @@ -913,9 +915,9 @@ try { dir->gcInMemEntries(/*return_removed_entries=*/false); const auto all_ids = dir->getAllPageIds(); - for (const auto & id : visible_page_ids) + for (const auto & cur_id : visible_page_ids) { - EXPECT_GT(all_ids.count(buildV3Id(TEST_NAMESPACE_ID, id)), 0) << fmt::format("cur_id:{}, all_id:{}, visible_ids:{}", id, all_ids, visible_page_ids); + EXPECT_GT(all_ids.count(buildV3Id(TEST_NAMESPACE_ID, cur_id)), 0) << fmt::format("cur_id:{}, all_id:{}, visible_ids:{}", cur_id, all_ids, visible_page_ids); } } auto snap = dir->createSnapshot(); @@ -1017,10 +1019,10 @@ class PageDirectoryGCTest : public PageDirectoryTest TEST_F(PageDirectoryGCTest, ManyEditsAndDumpSnapshot) { - PageId page_id0 = 50; - PageId page_id1 = 51; - PageId page_id2 = 52; - PageId page_id3 = 53; + PageIdU64 page_id0 = 50; + PageIdU64 page_id1 = 51; + PageIdU64 page_id2 = 52; + PageIdU64 page_id3 = 53; PageEntryV3 last_entry_for_0; constexpr size_t num_edits_test = 50000; @@ -1072,7 +1074,7 @@ TEST_F(PageDirectoryGCTest, ManyEditsAndDumpSnapshot) TEST_F(PageDirectoryGCTest, GCPushForward) try { - PageId page_id = 50; + PageIdU64 page_id = 50; /** * before GC => { @@ -1126,8 +1128,8 @@ try * } * snapshot remain: [v3, v5] */ - PageId page_id = 50; - PageId another_page_id = 512; + PageIdU64 page_id = 50; + PageIdU64 another_page_id = 512; INSERT_ENTRY(another_page_id, 1); INSERT_ENTRY(page_id, 2); @@ -1194,8 +1196,8 @@ try * } * snapshot remain: [v1, v3, v5, v10] */ - PageId page_id = 50; - PageId another_page_id = 512; + PageIdU64 page_id = 50; + PageIdU64 another_page_id = 512; // Push entries INSERT_ENTRY_ACQ_SNAP(another_page_id, 1); @@ -1279,8 +1281,8 @@ try * } * snapshot remain: [v5, v8, v9] */ - PageId page_id = 50; - PageId another_page_id = 512; + PageIdU64 page_id = 50; + PageIdU64 another_page_id = 512; // Push entries INSERT_ENTRY(another_page_id, 1); @@ -1375,8 +1377,8 @@ CATCH TEST_F(PageDirectoryGCTest, FullGCApply) try { - PageId page_id = 50; - PageId another_page_id = 512; + PageIdU64 page_id = 50; + PageIdU64 another_page_id = 512; INSERT_ENTRY_TO(page_id, 1, 1); INSERT_ENTRY_TO(page_id, 2, 2); INSERT_ENTRY_TO(another_page_id, 3, 2); @@ -1400,17 +1402,17 @@ try for (const auto & [file_id, entries] : candidate_entries_1.first) { (void)file_id; - for (const auto & [page_id, ver, entry] : entries) + for (const auto & [gc_page_id, ver, entry] : entries) { - gc_migrate_entries.upsertPage(page_id, ver, entry); + gc_migrate_entries.upsertPage(gc_page_id, ver, entry); } } for (const auto & [file_id, entries] : candidate_entries_2_3.first) { (void)file_id; - for (const auto & [page_id, ver, entry] : entries) + for (const auto & [gc_page_id, ver, entry] : entries) { - gc_migrate_entries.upsertPage(page_id, ver, entry); + gc_migrate_entries.upsertPage(gc_page_id, ver, entry); } } @@ -1426,8 +1428,8 @@ CATCH TEST_F(PageDirectoryGCTest, MVCCAndFullGCInConcurrent) try { - PageId page_id = 50; - PageId another_page_id = 512; + PageIdU64 page_id = 50; + PageIdU64 another_page_id = 512; INSERT_ENTRY_TO(page_id, 1, 1); INSERT_ENTRY_TO(page_id, 2, 2); INSERT_ENTRY_TO(page_id, 3, 2); @@ -1456,17 +1458,17 @@ try for (const auto & [file_id, entries] : candidate_entries_1.first) { (void)file_id; - for (const auto & [page_id, ver, entry] : entries) + for (const auto & [gc_page_id, ver, entry] : entries) { - gc_migrate_entries.upsertPage(page_id, ver, entry); + gc_migrate_entries.upsertPage(gc_page_id, ver, entry); } } for (const auto & [file_id, entries] : candidate_entries_2_3.first) { (void)file_id; - for (const auto & [page_id, ver, entry] : entries) + for (const auto & [gc_page_id, ver, entry] : entries) { - gc_migrate_entries.upsertPage(page_id, ver, entry); + gc_migrate_entries.upsertPage(gc_page_id, ver, entry); } } @@ -1811,12 +1813,12 @@ try auto s0 = dir->createSnapshot(); auto edit = dir->dumpSnapshotToEdit(s0); auto restore_from_edit = [](const PageEntriesEdit & edit) { - auto deseri_edit = DB::PS::V3::ser::deserializeFrom(DB::PS::V3::ser::serializeTo(edit)); + auto deseri_edit = u128::Serializer::deserializeFrom(u128::Serializer::serializeTo(edit)); auto ctx = DB::tests::TiFlashTestEnv::getContext(); auto provider = ctx.getFileProvider(); auto path = getTemporaryPath(); PSDiskDelegatorPtr delegator = std::make_shared(path); - PageDirectoryFactory factory; + PageDirectoryFactory factory; auto d = factory.createFromEdit(getCurrentTestName(), provider, delegator, deseri_edit); return d; }; @@ -1834,12 +1836,12 @@ TEST_F(PageDirectoryGCTest, DumpAndRestore) try { auto restore_from_edit = [](const PageEntriesEdit & edit) { - auto deseri_edit = DB::PS::V3::ser::deserializeFrom(DB::PS::V3::ser::serializeTo(edit)); + auto deseri_edit = u128::Serializer::deserializeFrom(u128::Serializer::serializeTo(edit)); auto ctx = DB::tests::TiFlashTestEnv::getContext(); auto provider = ctx.getFileProvider(); auto path = getTemporaryPath(); PSDiskDelegatorPtr delegator = std::make_shared(path); - PageDirectoryFactory factory; + PageDirectoryFactory factory; auto d = factory.createFromEdit(getCurrentTestName(), provider, delegator, deseri_edit); return d; }; @@ -2064,7 +2066,7 @@ try auto provider = ctx.getFileProvider(); auto path = getTemporaryPath(); PSDiskDelegatorPtr delegator = std::make_shared(path); - PageDirectoryFactory factory; + PageDirectoryFactory factory; auto d = factory.setBlobStats(stats).createFromEdit(getCurrentTestName(), provider, delegator, edit); return d; }; @@ -2108,7 +2110,7 @@ try auto provider = ctx.getFileProvider(); auto path = getTemporaryPath(); PSDiskDelegatorPtr delegator = std::make_shared(path); - PageDirectoryFactory factory; + PageDirectoryFactory factory; auto d = factory.createFromEdit(getCurrentTestName(), provider, delegator, edit); return d; }; diff --git a/dbms/src/Storages/Page/V3/tests/gtest_page_storage.cpp b/dbms/src/Storages/Page/V3/tests/gtest_page_storage.cpp index 96b82bf4c2a..6beff83a0c2 100644 --- a/dbms/src/Storages/Page/V3/tests/gtest_page_storage.cpp +++ b/dbms/src/Storages/Page/V3/tests/gtest_page_storage.cpp @@ -20,9 +20,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -95,14 +95,14 @@ try // In this case, WalStore throput is very low. // Because we only have 5 record to write. size_t wb_nums = 5; - PageId page_id = 50; + PageIdU64 page_id = 50; size_t buff_size = 100ul * 1024; const size_t rate_target = buff_size - 1; char c_buff[wb_nums * buff_size]; WriteBatch wbs[wb_nums]; - PageEntriesEdit edits[wb_nums]; + u128::PageEntriesEdit edits[wb_nums]; for (size_t i = 0; i < wb_nums; ++i) { @@ -154,7 +154,7 @@ try rate_target, LimiterType::UNKNOW); - PageIds page_ids; + std::vector page_ids; for (size_t i = 0; i < wb_nums; ++i) { page_ids.emplace_back(page_id + i); @@ -394,12 +394,12 @@ try } { - PageIds page_ids = {1, 2, 5}; + std::vector page_ids = {1, 2, 5}; // readImpl(TEST_NAMESPACE_ID, page_ids, nullptr, nullptr, true); auto page_maps = page_storage->readImpl(TEST_NAMESPACE_ID, page_ids, nullptr, nullptr, false); - ASSERT_EQ(page_maps[1].page_id, 1); - ASSERT_FALSE(page_maps[2].isValid()); - ASSERT_FALSE(page_maps[5].isValid()); + ASSERT_EQ(page_maps.at(1).page_id, 1); + ASSERT_FALSE(page_maps.at(2).isValid()); + ASSERT_FALSE(page_maps.at(5).isValid()); const auto & page1 = page_storage->readImpl(TEST_NAMESPACE_ID, 1, nullptr, nullptr, false); ASSERT_EQ(page1.page_id, 1); @@ -415,16 +415,16 @@ try }; page_maps = page_storage->readImpl(TEST_NAMESPACE_ID, fields, nullptr, nullptr, false); - ASSERT_EQ(page_maps[4].page_id, 4); - ASSERT_EQ(page_maps[4].fieldSize(), 3); - ASSERT_EQ(page_maps[4].data.size(), 20 + 20 + 30); + ASSERT_EQ(page_maps.at(4).page_id, 4); + ASSERT_EQ(page_maps.at(4).fieldSize(), 3); + ASSERT_EQ(page_maps.at(4).data.size(), 20 + 20 + 30); // the invalid page ids in input param are returned with INVALID_ID ASSERT_GT(page_maps.count(6), 0); - ASSERT_EQ(page_maps[6].isValid(), false); + ASSERT_EQ(page_maps.at(6).isValid(), false); ASSERT_GT(page_maps.count(2), 0); - ASSERT_EQ(page_maps[2].isValid(), false); + ASSERT_EQ(page_maps.at(2).isValid(), false); ASSERT_GT(page_maps.count(5), 0); - ASSERT_EQ(page_maps[5].isValid(), false); + ASSERT_EQ(page_maps.at(5).isValid(), false); } { // Read with id can also fetch the fieldOffsets @@ -437,11 +437,11 @@ try } { // Read with ids can also fetch the fieldOffsets - PageIds page_ids{4}; + std::vector page_ids{4}; auto pages = page_storage->readImpl(TEST_NAMESPACE_ID, page_ids, nullptr, nullptr, false); ASSERT_EQ(pages.size(), 1); ASSERT_GT(pages.count(4), 0); - auto page_4 = pages[4]; + auto page_4 = pages.at(4); ASSERT_EQ(page_4.fieldSize(), 4); ASSERT_EQ(page_4.getFieldData(0).size(), 20); ASSERT_EQ(page_4.getFieldData(1).size(), 20); @@ -523,7 +523,7 @@ CATCH TEST_F(PageStorageTest, MultipleWriteRead) { size_t page_id_max = 100; - for (DB::PageId page_id = 0; page_id <= page_id_max; ++page_id) + for (DB::PageIdU64 page_id = 0; page_id <= page_id_max; ++page_id) { std::mt19937 size_gen; size_gen.seed(time(nullptr)); @@ -547,7 +547,7 @@ TEST_F(PageStorageTest, MultipleWriteRead) page_storage->write(std::move(wb)); } - for (DB::PageId page_id = 0; page_id <= page_id_max; ++page_id) + for (DB::PageIdU64 page_id = 0; page_id <= page_id_max; ++page_id) { page_storage->read(page_id); } @@ -607,7 +607,7 @@ try char c_buff[buf_sz]; const size_t num_repeat = 10; - PageId pid = 1; + PageIdU64 pid = 1; const char page0_byte = 0x3f; { // put page0 @@ -712,18 +712,18 @@ TEST_F(PageStorageTest, IngestFile) callbacks.scanner = []() -> ExternalPageCallbacks::PathAndIdsVec { return {}; }; - callbacks.remover = [×_remover_called](const ExternalPageCallbacks::PathAndIdsVec &, const std::set & living_page_ids) -> void { + callbacks.remover = [×_remover_called](const ExternalPageCallbacks::PathAndIdsVec &, const std::set & living_page_ids) -> void { times_remover_called += 1; EXPECT_EQ(living_page_ids.size(), 1); EXPECT_GT(living_page_ids.count(100), 0); }; - callbacks.ns_id = TEST_NAMESPACE_ID; + callbacks.prefix = TEST_NAMESPACE_ID; page_storage->registerExternalPagesCallbacks(callbacks); page_storage->gc(); ASSERT_EQ(times_remover_called, 1); page_storage->gc(); ASSERT_EQ(times_remover_called, 2); - page_storage->unregisterExternalPagesCallbacks(callbacks.ns_id); + page_storage->unregisterExternalPagesCallbacks(callbacks.prefix); page_storage->gc(); ASSERT_EQ(times_remover_called, 2); } @@ -1192,7 +1192,7 @@ try callbacks.scanner = []() -> ExternalPageCallbacks::PathAndIdsVec { return {}; }; - callbacks.remover = [×_remover_called, &test_stage](const ExternalPageCallbacks::PathAndIdsVec &, const std::set & living_page_ids) -> void { + callbacks.remover = [×_remover_called, &test_stage](const ExternalPageCallbacks::PathAndIdsVec &, const std::set & living_page_ids) -> void { times_remover_called += 1; switch (test_stage) { @@ -1213,7 +1213,7 @@ try } } }; - callbacks.ns_id = TEST_NAMESPACE_ID; + callbacks.prefix = TEST_NAMESPACE_ID; page_storage->registerExternalPagesCallbacks(callbacks); { SCOPED_TRACE("fist gc"); @@ -1280,7 +1280,7 @@ try auto ptr = std::make_shared(100); // mock the `StorageDeltaMerge` ExternalPageCallbacks callbacks; - callbacks.ns_id = ns_id1; + callbacks.prefix = ns_id1; callbacks.scanner = [ptr_weak_ref = std::weak_ptr(ptr)]() -> ExternalPageCallbacks::PathAndIdsVec { auto ptr = ptr_weak_ref.lock(); if (!ptr) @@ -1289,7 +1289,7 @@ try (*ptr) += 1; // mock access the storage inside callback return {}; }; - callbacks.remover = [ptr_weak_ref = std::weak_ptr(ptr)](const ExternalPageCallbacks::PathAndIdsVec &, const std::set &) -> void { + callbacks.remover = [ptr_weak_ref = std::weak_ptr(ptr)](const ExternalPageCallbacks::PathAndIdsVec &, const std::set &) -> void { auto ptr = ptr_weak_ref.lock(); if (!ptr) return; @@ -1308,7 +1308,7 @@ try // mock table created while gc is running { ExternalPageCallbacks new_callbacks; - new_callbacks.ns_id = ns_id2; + new_callbacks.prefix = ns_id2; new_callbacks.scanner = [ptr_weak_ref = std::weak_ptr(ptr)]() -> ExternalPageCallbacks::PathAndIdsVec { auto ptr = ptr_weak_ref.lock(); if (!ptr) @@ -1317,7 +1317,7 @@ try (*ptr) += 1; // mock access the storage inside callback return {}; }; - new_callbacks.remover = [ptr_weak_ref = std::weak_ptr(ptr)](const ExternalPageCallbacks::PathAndIdsVec &, const std::set &) -> void { + new_callbacks.remover = [ptr_weak_ref = std::weak_ptr(ptr)](const ExternalPageCallbacks::PathAndIdsVec &, const std::set &) -> void { auto ptr = ptr_weak_ref.lock(); if (!ptr) return; @@ -1339,7 +1339,7 @@ try { auto ptr = std::make_shared(100); // mock the `StorageDeltaMerge` ExternalPageCallbacks callbacks; - callbacks.ns_id = TEST_NAMESPACE_ID; + callbacks.prefix = TEST_NAMESPACE_ID; callbacks.scanner = [ptr_weak_ref = std::weak_ptr(ptr)]() -> ExternalPageCallbacks::PathAndIdsVec { auto ptr = ptr_weak_ref.lock(); if (!ptr) @@ -1348,7 +1348,7 @@ try (*ptr) += 1; // mock access the storage inside callback return {}; }; - callbacks.remover = [ptr_weak_ref = std::weak_ptr(ptr)](const ExternalPageCallbacks::PathAndIdsVec &, const std::set &) -> void { + callbacks.remover = [ptr_weak_ref = std::weak_ptr(ptr)](const ExternalPageCallbacks::PathAndIdsVec &, const std::set &) -> void { auto ptr = ptr_weak_ref.lock(); if (!ptr) return; @@ -1611,7 +1611,7 @@ try c_buff[i] = i % 0xff; } - PageId page_id = 120; + PageIdU64 page_id = 120; UInt64 tag = 12345; { WriteBatch batch; @@ -1663,7 +1663,7 @@ try c_buff[i] = i % 0xff; } - PageId page_id0 = 120; + PageIdU64 page_id0 = 120; { WriteBatch batch; batch.putPage(page_id0, 0, std::make_shared(c_buff, buf_sz), buf_sz, {}); @@ -1683,7 +1683,7 @@ try while (getLogFileNum() <= 1) { WriteBatch batch; - PageId page_id1 = 130; + PageIdU64 page_id1 = 130; batch.putPage(page_id1, 0, std::make_shared(c_buff, buf_sz), buf_sz, {}); page_storage->write(std::move(batch)); } @@ -1729,13 +1729,13 @@ try c_buff[i] = i % 0xff; } - PageId page_id0 = 120; + PageIdU64 page_id0 = 120; { WriteBatch batch; batch.putPage(page_id0, 0, std::make_shared(c_buff, buf_sz), buf_sz, {}); page_storage->write(std::move(batch)); } - PageId page_id1 = 121; + PageIdU64 page_id1 = 121; { WriteBatch batch; batch.putRefPage(page_id1, page_id0); @@ -1759,7 +1759,7 @@ try while (getLogFileNum() <= 1) { WriteBatch batch; - PageId page_id2 = 130; + PageIdU64 page_id2 = 130; batch.putPage(page_id2, 0, std::make_shared(c_buff, buf_sz), buf_sz, {}); page_storage->write(std::move(batch)); } diff --git a/dbms/src/Storages/Page/V3/tests/gtest_page_storage_gc.cpp b/dbms/src/Storages/Page/V3/tests/gtest_page_storage_gc.cpp index a04856c4254..89dec7fb987 100644 --- a/dbms/src/Storages/Page/V3/tests/gtest_page_storage_gc.cpp +++ b/dbms/src/Storages/Page/V3/tests/gtest_page_storage_gc.cpp @@ -77,8 +77,8 @@ try new_config.blob_heavy_gc_valid_rate = 1.0; page_storage->reloadSettings(new_config); - PageId page_id1 = 101; - PageId ref_page_id = 102; + PageIdU64 page_id1 = 101; + PageIdU64 ref_page_id = 102; { WriteBatch batch; batch.putPage(page_id1, default_tag, getDefaultBuffer(), buf_sz); @@ -186,7 +186,7 @@ try new_config.blob_heavy_gc_valid_rate = 1.0; page_storage->reloadSettings(new_config); - PageId page_id1 = 101; + PageIdU64 page_id1 = 101; { WriteBatch batch; batch.putPage(page_id1, default_tag, getDefaultBuffer(), buf_sz); @@ -228,7 +228,7 @@ try auto s = reader->next(); if (s.has_value()) { - auto e = ser::deserializeFrom(s.value()); + auto e = u128::Serializer::deserializeFrom(s.value()); num_entries_on_wal += e.size(); EXPECT_TRUE(e.empty()); } @@ -245,10 +245,10 @@ try new_config.blob_heavy_gc_valid_rate = 1.0; page_storage->reloadSettings(new_config); - PageId page_id1 = 101; - PageId ref_page_id2 = 102; - PageId ref_page_id3 = 103; - PageId ref_page_id4 = 104; + PageIdU64 page_id1 = 101; + PageIdU64 ref_page_id2 = 102; + PageIdU64 ref_page_id3 = 103; + PageIdU64 ref_page_id4 = 104; { WriteBatch batch; batch.putPage(page_id1, default_tag, getDefaultBuffer(), buf_sz); @@ -304,7 +304,7 @@ try auto s = reader->next(); if (s.has_value()) { - auto e = ser::deserializeFrom(s.value()); + auto e = u128::Serializer::deserializeFrom(s.value()); num_entries_on_wal += e.size(); EXPECT_TRUE(e.empty()); } @@ -377,10 +377,10 @@ try new_config.blob_heavy_gc_valid_rate = 1.0; page_storage->reloadSettings(new_config); - PageId page_id1 = 101; - PageId ref_page_id2 = 102; - PageId ref_page_id3 = 103; - PageId ref_page_id4 = 104; + PageIdU64 page_id1 = 101; + PageIdU64 ref_page_id2 = 102; + PageIdU64 ref_page_id3 = 103; + PageIdU64 ref_page_id4 = 104; { WriteBatch batch; batch.putPage(page_id1, default_tag, getDefaultBuffer(), buf_sz); @@ -445,7 +445,7 @@ try auto s = reader->next(); if (s.has_value()) { - auto e = ser::deserializeFrom(s.value()); + auto e = u128::Serializer::deserializeFrom(s.value()); num_entries_on_wal += e.size(); for (const auto & r : e.getRecords()) { @@ -456,7 +456,7 @@ try else if (r.page_id.low == ref_page_id4) exist_id4_normal_entry = true; } - LOG_INFO(log, PageEntriesEdit::toDebugString(r)); + LOG_INFO(log, PageEntriesEdit::toDebugString(r)); } } } diff --git a/dbms/src/Storages/Page/V3/tests/gtest_page_storage_mix_mode.cpp b/dbms/src/Storages/Page/V3/tests/gtest_page_storage_mix_mode.cpp index d734bb759b9..2e638986938 100644 --- a/dbms/src/Storages/Page/V3/tests/gtest_page_storage_mix_mode.cpp +++ b/dbms/src/Storages/Page/V3/tests/gtest_page_storage_mix_mode.cpp @@ -125,7 +125,7 @@ inline ::testing::AssertionResult getPageCompare( char * buff_cmp, const size_t buf_size, const Page & page_cmp, - const PageId & page_id) + const PageIdU64 & page_id) { if (page_cmp.data.size() != buf_size) { @@ -256,42 +256,42 @@ try } { - PageIds page_ids = {1, 2, 3, 4}; + std::vector page_ids = {1, 2, 3, 4}; auto page_maps = page_reader_mix->read(page_ids); ASSERT_EQ(page_maps.size(), 4); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[1], 1); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[2], 2); - ASSERT_PAGE_EQ(c_buff2, buf_sz2, page_maps[3], 3); - ASSERT_PAGE_EQ(c_buff2, buf_sz2, page_maps[4], 4); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(1), 1); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(2), 2); + ASSERT_PAGE_EQ(c_buff2, buf_sz2, page_maps.at(3), 3); + ASSERT_PAGE_EQ(c_buff2, buf_sz2, page_maps.at(4), 4); // Read page ids which only exited in V2 page_ids = {1, 2, 7}; page_maps = page_reader_mix->read(page_ids); ASSERT_EQ(page_maps.size(), 3); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[1], 1); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[2], 2); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[7], 7); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(1), 1); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(2), 2); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(7), 7); } { std::vector read_fields; - read_fields.emplace_back(std::pair(2, {1, 3, 6})); - read_fields.emplace_back(std::pair(4, {1, 3, 4, 8, 10})); - read_fields.emplace_back(std::pair(7, {0, 1, 2})); - PageMap page_maps = page_reader_mix->read(read_fields); + read_fields.emplace_back(std::pair(2, {1, 3, 6})); + read_fields.emplace_back(std::pair(4, {1, 3, 4, 8, 10})); + read_fields.emplace_back(std::pair(7, {0, 1, 2})); + PageMapU64 page_maps = page_reader_mix->read(read_fields); ASSERT_EQ(page_maps.size(), 3); - ASSERT_EQ(page_maps[2].page_id, 2); - ASSERT_EQ(page_maps[2].field_offsets.size(), 3); - ASSERT_EQ(page_maps[4].page_id, 4); - ASSERT_EQ(page_maps[4].field_offsets.size(), 5); - ASSERT_EQ(page_maps[7].page_id, 7); - ASSERT_EQ(page_maps[7].field_offsets.size(), 3); + ASSERT_EQ(page_maps.at(2).page_id, 2); + ASSERT_EQ(page_maps.at(2).field_offsets.size(), 3); + ASSERT_EQ(page_maps.at(4).page_id, 4); + ASSERT_EQ(page_maps.at(4).field_offsets.size(), 5); + ASSERT_EQ(page_maps.at(7).page_id, 7); + ASSERT_EQ(page_maps.at(7).field_offsets.size(), 3); } { // Read page ids which only exited in V2 std::vector read_fields; - read_fields.emplace_back(std::pair(2, {1, 3, 6})); + read_fields.emplace_back(std::pair(2, {1, 3, 6})); ASSERT_NO_THROW(page_reader_mix->read(read_fields)); } @@ -462,15 +462,15 @@ try ASSERT_EQ(page_reader_mix->getNormalPageId(10), 8); std::vector read_fields; - read_fields.emplace_back(std::pair(10, {0, 1, 2, 6})); + read_fields.emplace_back(std::pair(10, {0, 1, 2, 6})); - PageMap page_maps = page_reader_mix->read(read_fields); + PageMapU64 page_maps = page_reader_mix->read(read_fields); ASSERT_EQ(page_maps.size(), 1); - ASSERT_EQ(page_maps[10].page_id, 10); - ASSERT_EQ(page_maps[10].field_offsets.size(), 4); - ASSERT_EQ(page_maps[10].data.size(), 710); + ASSERT_EQ(page_maps.at(10).page_id, 10); + ASSERT_EQ(page_maps.at(10).field_offsets.size(), 4); + ASSERT_EQ(page_maps.at(10).data.size(), 710); - auto field_offset = page_maps[10].field_offsets; + auto field_offset = page_maps.at(10).field_offsets; auto it = field_offset.begin(); ASSERT_EQ(it->offset, 0); ++it; @@ -1119,8 +1119,8 @@ try auto page_maps = newMixedPageReader(snapshot_mix).read({1, 2}); ASSERT_EQ(page_maps.size(), 2); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[1], 1); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[2], 2); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(1), 1); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(2), 2); } } CATCH @@ -1186,8 +1186,8 @@ try auto page_maps = newMixedPageReader(snapshot_mix).read({1, 2}); ASSERT_EQ(page_maps.size(), 2); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[1], 1); - ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps[2], 2); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(1), 1); + ASSERT_PAGE_EQ(c_buff, buf_sz, page_maps.at(2), 2); } } CATCH diff --git a/dbms/src/Storages/Page/V3/tests/gtest_versioned_entries.cpp b/dbms/src/Storages/Page/V3/tests/gtest_versioned_entries.cpp index 4424c29608b..b5a21bc7dc8 100644 --- a/dbms/src/Storages/Page/V3/tests/gtest_versioned_entries.cpp +++ b/dbms/src/Storages/Page/V3/tests/gtest_versioned_entries.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -67,8 +67,8 @@ class VersionedEntriesTest : public ::testing::Test } protected: - const PageId page_id = 100; - VersionedPageEntries entries; + const PageIdU64 page_id = 100; + u128::VersionedPageEntries entries; }; TEST_F(VersionedEntriesTest, InsertGet) @@ -528,8 +528,8 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) INSERT_BLOBID_ENTRY(3, 8); INSERT_BLOBID_ENTRY(1, 11); - PageId page_id = 100; - auto check_for_blob_id_1 = [&](const PageIdAndVersionedEntries & entries) { + PageIdU64 page_id = 100; + auto check_for_blob_id_1 = [&](const PageDirectory::GcEntries & entries) { auto it = entries.begin(); ASSERT_EQ(std::get<0>(*it).low, page_id); ASSERT_EQ(std::get<1>(*it).sequence, 11); @@ -537,7 +537,7 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) }; { - std::map blob_entries; + PageDirectory::GcEntriesMap blob_entries; std::map> rewrite; PageSize total_size = entries.getEntriesByBlobIds({/*empty*/}, buildV3Id(TEST_NAMESPACE_ID, page_id), blob_entries, rewrite); @@ -546,7 +546,7 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) } { - std::map blob_entries; + PageDirectory::GcEntriesMap blob_entries; std::map> rewrite; const BlobFileId blob_id = 1; PageSize total_size = entries.getEntriesByBlobIds({blob_id}, buildV3Id(TEST_NAMESPACE_ID, page_id), blob_entries, rewrite); @@ -558,7 +558,7 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) } { - std::map blob_entries; + PageDirectory::GcEntriesMap blob_entries; std::map> rewrite; const BlobFileId blob_id = 2; PageSize total_size = entries.getEntriesByBlobIds({blob_id}, buildV3Id(TEST_NAMESPACE_ID, page_id), blob_entries, rewrite); @@ -568,7 +568,7 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) } { - std::map blob_entries; + PageDirectory::GcEntriesMap blob_entries; std::map> rewrite; const BlobFileId blob_id = 3; PageSize total_size = entries.getEntriesByBlobIds({blob_id}, buildV3Id(TEST_NAMESPACE_ID, page_id), blob_entries, rewrite); @@ -579,7 +579,7 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) // {1, 2} { - std::map blob_entries; + PageDirectory::GcEntriesMap blob_entries; std::map> rewrite; PageSize total_size = entries.getEntriesByBlobIds({1, 2}, buildV3Id(TEST_NAMESPACE_ID, page_id), blob_entries, rewrite); @@ -591,7 +591,7 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) // {2, 3} { - std::map blob_entries; + PageDirectory::GcEntriesMap blob_entries; std::map> rewrite; PageSize total_size = entries.getEntriesByBlobIds({3, 2}, buildV3Id(TEST_NAMESPACE_ID, page_id), blob_entries, rewrite); @@ -601,7 +601,7 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) // {1, 2, 3} { - std::map blob_entries; + PageDirectory::GcEntriesMap blob_entries; std::map> rewrite; PageSize total_size = entries.getEntriesByBlobIds({1, 3, 2}, buildV3Id(TEST_NAMESPACE_ID, page_id), blob_entries, rewrite); @@ -613,7 +613,7 @@ TEST_F(VersionedEntriesTest, getEntriesByBlobId) // {1, 2, 3, 100}; blob_id 100 is not exist in actual { - std::map blob_entries; + PageDirectory::GcEntriesMap blob_entries; std::map> rewrite; PageSize total_size = entries.getEntriesByBlobIds({1, 3, 2, 4}, buildV3Id(TEST_NAMESPACE_ID, page_id), blob_entries, rewrite); diff --git a/dbms/src/Storages/Page/V3/tests/gtest_wal_store.cpp b/dbms/src/Storages/Page/V3/tests/gtest_wal_store.cpp index 7550bb2ca8f..810ddd6e577 100644 --- a/dbms/src/Storages/Page/V3/tests/gtest_wal_store.cpp +++ b/dbms/src/Storages/Page/V3/tests/gtest_wal_store.cpp @@ -15,9 +15,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -36,6 +36,8 @@ namespace DB::PS::V3::tests { +using u128::PageEntriesEdit; + TEST(WALSeriTest, AllPuts) { PageEntryV3 entry_p1{.file_id = 1, .size = 1, .padded_size = 0, .tag = 0, .offset = 0x123, .checksum = 0x4567}; @@ -48,7 +50,7 @@ TEST(WALSeriTest, AllPuts) for (auto & rec : edit.getMutRecords()) rec.version = ver20; - auto deseri_edit = DB::PS::V3::ser::deserializeFrom(DB::PS::V3::ser::serializeTo(edit)); + auto deseri_edit = u128::Serializer::deserializeFrom(u128::Serializer::serializeTo(edit)); ASSERT_EQ(deseri_edit.size(), 2); auto iter = deseri_edit.getRecords().begin(); EXPECT_EQ(iter->type, EditRecordType::PUT); @@ -74,7 +76,7 @@ try for (auto & rec : edit.getMutRecords()) rec.version = ver21; - auto deseri_edit = DB::PS::V3::ser::deserializeFrom(DB::PS::V3::ser::serializeTo(edit)); + auto deseri_edit = u128::Serializer::deserializeFrom(u128::Serializer::serializeTo(edit)); ASSERT_EQ(deseri_edit.size(), 6); auto iter = deseri_edit.getRecords().begin(); EXPECT_EQ(iter->type, EditRecordType::PUT); @@ -118,7 +120,7 @@ TEST(WALSeriTest, Upserts) edit.upsertPage(buildV3Id(TEST_NAMESPACE_ID, 3), ver21_1, entry_p3_2); edit.upsertPage(buildV3Id(TEST_NAMESPACE_ID, 5), ver21_1, entry_p5_2); - auto deseri_edit = DB::PS::V3::ser::deserializeFrom(DB::PS::V3::ser::serializeTo(edit)); + auto deseri_edit = u128::Serializer::deserializeFrom(u128::Serializer::serializeTo(edit)); ASSERT_EQ(deseri_edit.size(), 3); auto iter = deseri_edit.getRecords().begin(); EXPECT_EQ(iter->type, EditRecordType::UPSERT); @@ -148,7 +150,7 @@ TEST(WALSeriTest, RefExternalAndEntry) edit.varDel(buildV3Id(TEST_NAMESPACE_ID, 1), ver2_0); edit.varRef(buildV3Id(TEST_NAMESPACE_ID, 2), ver3_0, buildV3Id(TEST_NAMESPACE_ID, 1)); - auto deseri_edit = DB::PS::V3::ser::deserializeFrom(DB::PS::V3::ser::serializeTo(edit)); + auto deseri_edit = u128::Serializer::deserializeFrom(u128::Serializer::serializeTo(edit)); ASSERT_EQ(deseri_edit.size(), 3); auto iter = deseri_edit.getRecords().begin(); EXPECT_EQ(iter->type, EditRecordType::VAR_EXTERNAL); @@ -173,7 +175,7 @@ TEST(WALSeriTest, RefExternalAndEntry) edit.varDel(buildV3Id(TEST_NAMESPACE_ID, 1), ver2_0); edit.varRef(buildV3Id(TEST_NAMESPACE_ID, 2), ver3_0, buildV3Id(TEST_NAMESPACE_ID, 1)); - auto deseri_edit = DB::PS::V3::ser::deserializeFrom(DB::PS::V3::ser::serializeTo(edit)); + auto deseri_edit = DB::PS::V3::u128::Serializer::deserializeFrom(DB::PS::V3::u128::Serializer::serializeTo(edit)); ASSERT_EQ(deseri_edit.size(), 3); auto iter = deseri_edit.getRecords().begin(); EXPECT_EQ(iter->type, EditRecordType::VAR_ENTRY); @@ -312,7 +314,7 @@ class WALStoreTest { r.version = version; } - wal->apply(ser::serializeTo(edit)); + wal->apply(u128::Serializer::serializeTo(edit)); } static void rollToNewLogWriter(const WALStorePtr & wal) @@ -454,7 +456,7 @@ try if (!record) break; // Details of each edit is verified in `WALSeriTest` - auto edit = ser::deserializeFrom(record.value()); + auto edit = u128::Serializer::deserializeFrom(record.value()); EXPECT_EQ(size_each_edit[num_applied_edit], edit.size()); num_applied_edit += 1; } @@ -487,7 +489,7 @@ try if (!record) break; // Details of each edit is verified in `WALSeriTest` - auto edit = ser::deserializeFrom(record.value()); + auto edit = u128::Serializer::deserializeFrom(record.value()); EXPECT_EQ(size_each_edit[num_applied_edit], edit.size()); num_applied_edit += 1; } @@ -507,7 +509,7 @@ try edit.upsertPage(buildV3Id(TEST_NAMESPACE_ID, 3), ver21_1, entry_p3_2); edit.upsertPage(buildV3Id(TEST_NAMESPACE_ID, 5), ver21_1, entry_p5_2); size_each_edit.emplace_back(edit.size()); - wal->apply(ser::serializeTo(edit)); + wal->apply(u128::Serializer::serializeTo(edit)); } wal.reset(); @@ -522,7 +524,7 @@ try if (!record) break; // Details of each edit is verified in `WALSeriTest` - auto edit = ser::deserializeFrom(record.value()); + auto edit = u128::Serializer::deserializeFrom(record.value()); EXPECT_EQ(size_each_edit[num_applied_edit], edit.size()); num_applied_edit += 1; } @@ -580,7 +582,7 @@ try edit.upsertPage(buildV3Id(TEST_NAMESPACE_ID, 3), ver21_1, entry_p3_2); edit.upsertPage(buildV3Id(TEST_NAMESPACE_ID, 5), ver21_1, entry_p5_2); size_each_edit.emplace_back(edit.size()); - wal->apply(ser::serializeTo(edit)); + wal->apply(u128::Serializer::serializeTo(edit)); } wal.reset(); @@ -594,7 +596,7 @@ try if (!record) break; // Details of each edit is verified in `WALSeriTest` - auto edit = ser::deserializeFrom(record.value()); + auto edit = u128::Serializer::deserializeFrom(record.value()); EXPECT_EQ(size_each_edit[num_applied_edit], edit.size()) << fmt::format("edit size not match at idx={}", num_applied_edit); num_applied_edit += 1; } @@ -614,7 +616,7 @@ try break; } // Details of each edit is verified in `WALSeriTest` - auto edit = ser::deserializeFrom(record.value()); + auto edit = u128::Serializer::deserializeFrom(record.value()); EXPECT_EQ(size_each_edit[num_applied_edit], edit.size()) << fmt::format("edit size not match at idx={}", num_applied_edit); num_applied_edit += 1; } @@ -640,7 +642,7 @@ try // Stage 2. insert many edits constexpr size_t num_edits_test = 100000; - PageId page_id = 0; + PageIdU64 page_id = 0; std::vector size_each_edit; size_each_edit.reserve(num_edits_test); PageVersion ver(/*seq*/ 32); @@ -675,7 +677,7 @@ try // else it just run to the end of file. break; } - auto edit = ser::deserializeFrom(record.value()); + auto edit = u128::Serializer::deserializeFrom(record.value()); num_pages_read += edit.size(); EXPECT_EQ(size_each_edit[num_edits_read], edit.size()) << fmt::format("at idx={}", num_edits_read); num_edits_read += 1; @@ -699,7 +701,7 @@ try snap_edit.varEntry(buildV3Id(TEST_NAMESPACE_ID, d_10000(rd)), PageVersion(345, 22), entry, 1); } std::tie(wal, reader) = WALStore::create(getCurrentTestName(), enc_provider, delegator, config); - bool done = wal->saveSnapshot(std::move(file_snap), ser::serializeTo(snap_edit), snap_edit.size()); + bool done = wal->saveSnapshot(std::move(file_snap), u128::Serializer::serializeTo(snap_edit), snap_edit.size()); ASSERT_TRUE(done); wal.reset(); reader.reset(); @@ -717,7 +719,7 @@ try // else it just run to the end of file. break; } - auto edit = ser::deserializeFrom(record.value()); + auto edit = u128::Serializer::deserializeFrom(record.value()); num_pages_read += edit.size(); num_edits_read += 1; } @@ -767,7 +769,7 @@ TEST_P(WALStoreTest, GetFileSnapshot) // write new edit, new log file generated PageEntriesEdit edit; edit.del(buildV3Id(TEST_NAMESPACE_ID, 100)); - wal->apply(ser::serializeTo(edit)); + wal->apply(u128::Serializer::serializeTo(edit)); } { @@ -781,7 +783,7 @@ TEST_P(WALStoreTest, GetFileSnapshot) // empty PageEntriesEdit snap_edit; - bool done = wal->saveSnapshot(std::move(files), ser::serializeTo(snap_edit), snap_edit.size()); + bool done = wal->saveSnapshot(std::move(files), u128::Serializer::serializeTo(snap_edit), snap_edit.size()); ASSERT_TRUE(done); ASSERT_EQ(getNumLogFiles(), 1); } diff --git a/dbms/src/Storages/Page/WriteBatch.h b/dbms/src/Storages/Page/WriteBatch.h index 1359fb77e7d..cb6be591be3 100644 --- a/dbms/src/Storages/Page/WriteBatch.h +++ b/dbms/src/Storages/Page/WriteBatch.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include @@ -52,13 +52,13 @@ class WriteBatch : private boost::noncopyable struct Write { WriteBatchWriteType type; - PageId page_id; + PageIdU64 page_id; UInt64 tag; // Page's data and size ReadBufferPtr read_buffer; PageSize size; // RefPage's origin page - PageId ori_page_id; + PageIdU64 ori_page_id; // Fields' offset inside Page's data PageFieldOffsetChecksums offsets; @@ -88,7 +88,7 @@ class WriteBatch : private boost::noncopyable , namespace_id(rhs.namespace_id) {} - void putPage(PageId page_id, UInt64 tag, const ReadBufferPtr & read_buffer, PageSize size, const PageFieldSizes & data_sizes = {}) + void putPage(PageIdU64 page_id, UInt64 tag, const ReadBufferPtr & read_buffer, PageSize size, const PageFieldSizes & data_sizes = {}) { // Convert from data_sizes to the offset of each field PageFieldOffsetChecksums offsets; @@ -115,7 +115,7 @@ class WriteBatch : private boost::noncopyable writes.emplace_back(std::move(w)); } - void putExternal(PageId page_id, UInt64 tag) + void putExternal(PageIdU64 page_id, UInt64 tag) { // External page's data is not managed by PageStorage, which means data is empty. Write w{WriteBatchWriteType::PUT_EXTERNAL, page_id, tag, nullptr, 0, 0, {}, 0, 0, {}}; @@ -124,7 +124,7 @@ class WriteBatch : private boost::noncopyable // Upsert a page{page_id} and writer page's data to a new PageFile{file_id}. // Now it's used in DataCompactor to move page's data to new file. - void upsertPage(PageId page_id, + void upsertPage(PageIdU64 page_id, UInt64 tag, const PageFileIdAndLevel & file_id, const ReadBufferPtr & read_buffer, @@ -139,7 +139,7 @@ class WriteBatch : private boost::noncopyable // Upserting a page{page_id} to PageFile{file_id}. This type of upsert is a simple mark and // only used for checkpoint. That page will be overwritten by WriteBatch with larger sequence, // so we don't need to write page's data. - void upsertPage(PageId page_id, + void upsertPage(PageIdU64 page_id, UInt64 tag, const PageFileIdAndLevel & file_id, UInt64 page_offset, @@ -152,13 +152,13 @@ class WriteBatch : private boost::noncopyable } // Add RefPage{ref_id} -> Page{page_id} - void putRefPage(PageId ref_id, PageId page_id) + void putRefPage(PageIdU64 ref_id, PageIdU64 page_id) { Write w{WriteBatchWriteType::REF, ref_id, 0, nullptr, 0, page_id, {}, 0, 0, {}}; writes.emplace_back(std::move(w)); } - void delPage(PageId page_id) + void delPage(PageIdU64 page_id) { Write w{WriteBatchWriteType::DEL, page_id, 0, nullptr, 0, 0, {}, 0, 0, {}}; writes.emplace_back(std::move(w)); @@ -235,7 +235,7 @@ class WriteBatch : private boost::noncopyable return namespace_id; } - PageIdV3Internal getFullPageId(PageId id) const + PageIdV3Internal getFullPageId(PageIdU64 id) const { return buildV3Id(namespace_id, id); } @@ -265,7 +265,7 @@ class WriteBatch : private boost::noncopyable fb.fmtAppend("E{}.{}", namespace_id, w.page_id); break; default: - fb.fmtAppend("Unknow {}.{}", namespace_id, w.page_id); + fb.fmtAppend("Unknown {}.{}", namespace_id, w.page_id); break; }; }, diff --git a/dbms/src/Storages/Page/tools/PageCtl/PageStorageCtlV2.cpp b/dbms/src/Storages/Page/tools/PageCtl/PageStorageCtlV2.cpp index 1b4d22a8397..76875802f7d 100644 --- a/dbms/src/Storages/Page/tools/PageCtl/PageStorageCtlV2.cpp +++ b/dbms/src/Storages/Page/tools/PageCtl/PageStorageCtlV2.cpp @@ -46,7 +46,7 @@ Usage: )HELP"); } -void printPageEntry(const DB::PageId pid, const DB::PageEntry & entry) +void printPageEntry(const DB::PageIdU64 pid, const DB::PageEntry & entry) { printf("\tpid:%9lld\t\t" "%9llu\t%9u\t%9u\t%9llu\t%9llu\t%016llx\n", @@ -234,7 +234,7 @@ void dump_all_entries(PageFileSet & page_files, int32_t mode) for (const auto & page_file : page_files) { PageEntriesEdit edit; - DB::PageIdAndEntries id_and_caches; + DB::PageIdU64AndEntries id_and_caches; auto reader = PageFile::MetaMergingReader::createFrom(const_cast(page_file)); @@ -320,7 +320,7 @@ void list_all_capacity(const PageFileSet & page_files, PageStorage & storage, co const size_t total_size = page_file.getDataFileSize(); size_t valid_size = 0; - DB::PageIdSet valid_pages; + DB::PageIdU64Set valid_pages; if (auto iter = file_valid_pages.find(page_file.fileIdLevel()); iter != file_valid_pages.end()) { valid_size = iter->second.first; diff --git a/dbms/src/Storages/Page/tools/PageCtl/PageStorageCtlV3.cpp b/dbms/src/Storages/Page/tools/PageCtl/PageStorageCtlV3.cpp index 92d3f91bfab..f57508f0087 100644 --- a/dbms/src/Storages/Page/tools/PageCtl/PageStorageCtlV3.cpp +++ b/dbms/src/Storages/Page/tools/PageCtl/PageStorageCtlV3.cpp @@ -79,7 +79,7 @@ ControlOptions ControlOptions::parse(int argc, char ** argv) ("config_file_path", value(), "Path to TiFlash config (tiflash.toml)."); - static_assert(sizeof(DB::PageId) == sizeof(UInt64)); + static_assert(sizeof(DB::PageIdU64) == sizeof(UInt64)); static_assert(sizeof(DB::BlobFileId) == sizeof(UInt64)); po::variables_map options; @@ -195,7 +195,7 @@ class PageStorageControlV3 if (options.mode == ControlOptions::DisplayType::DISPLAY_WAL_ENTRIES) { // Only restore the PageDirectory - PageDirectoryFactory factory; + PageDirectoryFactory factory; factory.dump_entries = true; factory.create(String(NAME), provider, delegator, WALConfig::from(config)); return 0; @@ -204,7 +204,7 @@ class PageStorageControlV3 // Other display mode need to restore ps instance PageStorageImpl ps(String(NAME), delegator, config, provider); ps.restore(); - PageDirectory::MVCCMapType & mvcc_table_directory = ps.page_directory->mvcc_table_directory; + PageDirectory::MVCCMapType & mvcc_table_directory = ps.page_directory->mvcc_table_directory; switch (options.mode) { @@ -242,7 +242,7 @@ class PageStorageControlV3 return 0; } - static String getBlobsInfo(BlobStore & blob_store, UInt32 blob_id) + static String getBlobsInfo(BlobStore & blob_store, UInt32 blob_id) { auto stat_info = [](const BlobStats::BlobStatPtr & stat, const String & path) { FmtBuffer stat_str; @@ -292,9 +292,9 @@ class PageStorageControlV3 return stats_info.toString(); } - static String getDirectoryInfo(PageDirectory::MVCCMapType & mvcc_table_directory, UInt64 ns_id, UInt64 page_id) + static String getDirectoryInfo(PageDirectory::MVCCMapType & mvcc_table_directory, UInt64 ns_id, UInt64 page_id) { - auto page_info = [](UInt128 page_internal_id_, const VersionedPageEntriesPtr & versioned_entries) { + auto page_info = [](UInt128 page_internal_id_, const u128::VersionedPageEntriesPtr & versioned_entries) { FmtBuffer page_str; page_str.fmtAppend(" page id {}\n", page_internal_id_); page_str.fmtAppend(" {}\n", versioned_entries->toDebugString()); @@ -357,7 +357,7 @@ class PageStorageControlV3 return directory_info.toString(); } - static String getSummaryInfo(PageDirectory::MVCCMapType & mvcc_table_directory, BlobStore & blob_store) + static String getSummaryInfo(PageDirectory::MVCCMapType & mvcc_table_directory, BlobStore & blob_store) { UInt64 longest_version_chaim = 0; UInt64 shortest_version_chaim = UINT64_MAX; @@ -404,7 +404,7 @@ class PageStorageControlV3 return dir_summary_info.toString(); } - static String checkSinglePage(PageDirectory::MVCCMapType & mvcc_table_directory, BlobStore & blob_store, UInt64 ns_id, UInt64 page_id) + static String checkSinglePage(PageDirectory::MVCCMapType & mvcc_table_directory, BlobStore & blob_store, UInt64 ns_id, UInt64 page_id) { const auto & page_internal_id = buildV3Id(ns_id, page_id); const auto & it = mvcc_table_directory.find(page_internal_id); @@ -436,8 +436,8 @@ class PageStorageControlV3 DB::PageStorage::FieldIndices indices(entry.field_offsets.size()); std::iota(std::begin(indices), std::end(indices), 0); - BlobStore::FieldReadInfos infos; - BlobStore::FieldReadInfo info(page_internal_id, entry, indices); + BlobStore::FieldReadInfos infos; + BlobStore::FieldReadInfo info(page_internal_id, entry, indices); infos.emplace_back(info); blob_store.read(infos); } @@ -460,7 +460,7 @@ class PageStorageControlV3 return error_msg.toString(); } - static String checkAllDataCrc(PageDirectory::MVCCMapType & mvcc_table_directory, BlobStore & blob_store, bool enable_fo_check) + static String checkAllDataCrc(PageDirectory::MVCCMapType & mvcc_table_directory, BlobStore & blob_store, bool enable_fo_check) { size_t total_pages = mvcc_table_directory.size(); size_t cut_index = 0; @@ -498,8 +498,8 @@ class PageStorageControlV3 DB::PageStorage::FieldIndices indices(entry.field_offsets.size()); std::iota(std::begin(indices), std::end(indices), 0); - BlobStore::FieldReadInfos infos; - BlobStore::FieldReadInfo info(internal_id, entry, indices); + BlobStore::FieldReadInfos infos; + BlobStore::FieldReadInfo info(internal_id, entry, indices); infos.emplace_back(info); blob_store.read(infos); } diff --git a/dbms/src/Storages/Page/workload/Normal.h b/dbms/src/Storages/Page/workload/Normal.h index c25352c30bc..ae4c9448268 100644 --- a/dbms/src/Storages/Page/workload/Normal.h +++ b/dbms/src/Storages/Page/workload/Normal.h @@ -53,7 +53,7 @@ class NormalWorkload // init all pages in PageStorage if (options.init_pages) { - static constexpr PageId MAX_PAGE_ID_DEFAULT = 1000; + static constexpr PageIdU64 MAX_PAGE_ID_DEFAULT = 1000; initPages(MAX_PAGE_ID_DEFAULT); LOG_INFO(StressEnv::logger, "All pages have been init."); } diff --git a/dbms/src/Storages/Page/workload/PSRunnable.cpp b/dbms/src/Storages/Page/workload/PSRunnable.cpp index 94312d7944c..1e9304b0d18 100644 --- a/dbms/src/Storages/Page/workload/PSRunnable.cpp +++ b/dbms/src/Storages/Page/workload/PSRunnable.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -133,7 +133,7 @@ RandomPageId PSWriter::genRandomPageId() { // std::normal_distribution<> distribution{static_cast(max_page_id) / 2, 150}; std::uniform_int_distribution<> dist(0ULL, max_page_id - 1); - return RandomPageId(static_cast(std::round(dist(gen)))); + return RandomPageId(static_cast(std::round(dist(gen)))); } DB::ReadBufferPtr PSCommonWriter::getRandomData() @@ -216,20 +216,20 @@ void PSCommonWriter::setFieldSize(const DB::PageFieldSizes & data_sizes_) /// Reader /// -DB::PageIds PSReader::genRandomPageIds() +DB::PageIdU64s PSReader::genRandomPageIds() { - DB::PageIds page_ids; + DB::PageIdU64s page_ids; for (size_t i = 0; i < num_pages_read; ++i) { std::uniform_int_distribution<> dist(0, max_page_id); - page_ids.emplace_back(static_cast(dist(gen))); + page_ids.emplace_back(static_cast(dist(gen))); } return page_ids; } bool PSReader::runImpl() { - DB::PageIds page_ids = genRandomPageIds(); + DB::PageIdU64s page_ids = genRandomPageIds(); if (page_ids.empty()) return true; @@ -273,8 +273,8 @@ void PSWindowWriter::setNormalDistributionSigma(size_t sigma_) RandomPageId PSWindowWriter::genRandomPageId() { std::lock_guard page_id_lock(global_stat->mtx_page_id); - DB::PageIdSet ids_to_del; - DB::PageId page_id = [this, &ids_to_del]() { + DB::PageIdU64Set ids_to_del; + DB::PageIdU64 page_id = [this, &ids_to_del]() { if (global_stat->right_id_boundary < 4 * sigma) { return global_stat->right_id_boundary++; @@ -288,14 +288,14 @@ RandomPageId PSWindowWriter::genRandomPageId() { // Move this "random" near the right boundary - σ, (mock a hot write in an id range) // we will update the data in this page_id - DB::PageId page_id = std::abs(global_stat->right_id_boundary - sigma + random); + DB::PageIdU64 page_id = std::abs(global_stat->right_id_boundary - sigma + random); return std::max(page_id, global_stat->left_id_boundary.load()); } // Else it is about 16% probability that we create a new page. // Also we consider the pages with id less than (right boundary - 4σ) have no chance (less than 0.01% // by the definition of normal distribution) for being read later, remove the pages. - DB::PageId left_boundary = 0; + DB::PageIdU64 left_boundary = 0; if (global_stat->right_id_boundary > 3 * sigma) // ensure the new left boundary is not negative left_boundary = global_stat->right_id_boundary - 3 * sigma; global_stat->left_id_boundary = left_boundary; @@ -326,7 +326,7 @@ void PSWindowReader::setNormalDistributionSigma(size_t sigma_) sigma = sigma_; } -DB::PageIds PSWindowReader::genRandomPageIds() +DB::PageIdU64s PSWindowReader::genRandomPageIds() { const auto page_id_boundary_copy = global_stat->right_id_boundary.load(); // Nothing to read @@ -347,7 +347,7 @@ DB::PageIds PSWindowReader::genRandomPageIds() rand_id = std::max(rand_id, global_stat->left_id_boundary.load()); rand_id = std::min(rand_id, read_right_boundary); - DB::PageIds page_ids; + DB::PageIdU64s page_ids; std::lock_guard lock(global_stat->mtx_page_id); { for (size_t id = rand_id; id < num_pages_read + rand_id; ++id) diff --git a/dbms/src/Storages/Page/workload/PSRunnable.h b/dbms/src/Storages/Page/workload/PSRunnable.h index 72e2b81e46c..1821c702a73 100644 --- a/dbms/src/Storages/Page/workload/PSRunnable.h +++ b/dbms/src/Storages/Page/workload/PSRunnable.h @@ -14,12 +14,12 @@ #pragma once #include -#include +#include #include namespace DB::PS::tests { -static constexpr PageId MAX_PAGE_ID_DEFAULT = 1000; +static constexpr PageIdU64 MAX_PAGE_ID_DEFAULT = 1000; class PSRunnable : public Poco::Runnable { public: @@ -39,15 +39,15 @@ class PSRunnable : public Poco::Runnable struct RandomPageId { // The new page id to add to pagestorage - DB::PageId page_id; + DB::PageIdU64 page_id; // The page ids to removed from pagestorage - DB::PageIdSet page_id_to_remove; + DB::PageIdU64Set page_id_to_remove; - explicit RandomPageId(DB::PageId new_page_id) + explicit RandomPageId(DB::PageIdU64 new_page_id) : page_id(new_page_id) {} - RandomPageId(DB::PageId new_page_id, DB::PageIdSet page_id_to_remove_) + RandomPageId(DB::PageIdU64 new_page_id, DB::PageIdU64Set page_id_to_remove_) : page_id(new_page_id) , page_id_to_remove(page_id_to_remove_) { @@ -62,10 +62,10 @@ struct GlobalStat // The page ids between [left_id_boundary, right_id_boundary) // and exists in `commit_ids` && not exists in `pending_remove_ids` // is readable - std::atomic right_id_boundary = 0; - std::atomic left_id_boundary = 0; - std::set commit_ids; - std::set pending_remove_ids; + std::atomic right_id_boundary = 0; + std::atomic left_id_boundary = 0; + std::set commit_ids; + std::set pending_remove_ids; void commit(const RandomPageId & c); }; @@ -106,7 +106,7 @@ class PSWriter : public PSRunnable PSPtr ps; DB::UInt32 index = 0; std::mt19937 gen; - DB::PageId max_page_id = MAX_PAGE_ID_DEFAULT; + DB::PageIdU64 max_page_id = MAX_PAGE_ID_DEFAULT; std::unique_ptr memory; size_t buffer_size_min = 1 * 1024 * 1024; @@ -224,7 +224,7 @@ class PSReader : public PSRunnable void setReadPageNums(size_t page_read_once); protected: - virtual DB::PageIds genRandomPageIds(); + virtual DB::PageIdU64s genRandomPageIds(); protected: PSPtr ps; @@ -232,7 +232,7 @@ class PSReader : public PSRunnable size_t heavy_read_delay_ms = 0; size_t num_pages_read = 5; DB::UInt32 index = 0; - DB::PageId max_page_id = MAX_PAGE_ID_DEFAULT; + DB::PageIdU64 max_page_id = MAX_PAGE_ID_DEFAULT; const std::unique_ptr & global_stat; }; @@ -258,7 +258,7 @@ class PSWindowReader : public PSReader void setNormalDistributionSigma(size_t sigma); protected: - DB::PageIds genRandomPageIds() override; + DB::PageIdU64s genRandomPageIds() override; protected: size_t sigma = 11; diff --git a/dbms/src/Storages/Page/workload/PSStressEnv.h b/dbms/src/Storages/Page/workload/PSStressEnv.h index 3cb583a05af..c32715a582c 100644 --- a/dbms/src/Storages/Page/workload/PSStressEnv.h +++ b/dbms/src/Storages/Page/workload/PSStressEnv.h @@ -14,7 +14,7 @@ #pragma once -#include +#include #include #include diff --git a/dbms/src/Storages/Page/workload/PSWorkload.cpp b/dbms/src/Storages/Page/workload/PSWorkload.cpp index df8ffb45c3f..c7c2fa4d3db 100644 --- a/dbms/src/Storages/Page/workload/PSWorkload.cpp +++ b/dbms/src/Storages/Page/workload/PSWorkload.cpp @@ -143,10 +143,10 @@ void StressWorkload::initPageStorage(DB::PageStorageConfig & config, String path runtime_stat = std::make_unique(); } -void StressWorkload::initPages(const DB::PageId & max_page_id) +void StressWorkload::initPages(const DB::PageIdU64 & max_page_id) { auto writer = std::make_shared(ps, 0, runtime_stat); - for (DB::PageId page_id = 0; page_id <= max_page_id; ++page_id) + for (DB::PageIdU64 page_id = 0; page_id <= max_page_id; ++page_id) { RandomPageId r(page_id); writer->write(r); diff --git a/dbms/src/Storages/Page/workload/PSWorkload.h b/dbms/src/Storages/Page/workload/PSWorkload.h index 746cb6c2262..b2a5eb07b39 100644 --- a/dbms/src/Storages/Page/workload/PSWorkload.h +++ b/dbms/src/Storages/Page/workload/PSWorkload.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -84,7 +84,7 @@ class StressWorkload void startBackgroundTimer(); - void initPages(const DB::PageId & max_page_id); + void initPages(const DB::PageIdU64 & max_page_id); template void startWriter(size_t nums_writers, std::function)> writer_configure = nullptr) diff --git a/dbms/src/Storages/PathPool.cpp b/dbms/src/Storages/PathPool.cpp index 3e5232db3c6..d5121c16e91 100644 --- a/dbms/src/Storages/PathPool.cpp +++ b/dbms/src/Storages/PathPool.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Storages/PathPool.h b/dbms/src/Storages/PathPool.h index 3a7cb7191f9..599d0ad4715 100644 --- a/dbms/src/Storages/PathPool.h +++ b/dbms/src/Storages/PathPool.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Storages/Transaction/RegionPersister.cpp b/dbms/src/Storages/Transaction/RegionPersister.cpp index 0aa55cf74da..cf19962312e 100644 --- a/dbms/src/Storages/Transaction/RegionPersister.cpp +++ b/dbms/src/Storages/Transaction/RegionPersister.cpp @@ -282,7 +282,7 @@ RegionMap RegionPersister::restore(PathPool & path_pool, const TiFlashRaftProxyH auto page_storage_v2 = std::make_shared( "RegionPersister", delegator, - PageStorage::getEasyGCConfig(), + DB::PageStorageConfig::getEasyGCConfig(), provider, global_context.getPSBackgroundPool()); // V3 should not used getPSDiskDelegatorRaft diff --git a/dbms/src/Storages/tests/gtest_path_pool.cpp b/dbms/src/Storages/tests/gtest_path_pool.cpp index e2be4e7f524..58df20b1e81 100644 --- a/dbms/src/Storages/tests/gtest_path_pool.cpp +++ b/dbms/src/Storages/tests/gtest_path_pool.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include