diff --git a/dbms/src/Storages/KVStore/Decode/SafeTsManager.h b/dbms/src/Storages/KVStore/Decode/SafeTsManager.h index 2fb77aa6a22..1b01068ad5a 100644 --- a/dbms/src/Storages/KVStore/Decode/SafeTsManager.h +++ b/dbms/src/Storages/KVStore/Decode/SafeTsManager.h @@ -61,6 +61,24 @@ struct SafeTsManager static const SafeTS SafeTsDiffThreshold = 2 * 60 * 1000; bool isSafeTSLag(RegionID region_id, SafeTS * leader_safe_ts, SafeTS * self_safe_ts); + struct SafeTsPair + { + const SafeTS leader_safe_ts; + const SafeTS self_safe_ts; + }; + SafeTsPair get(RegionID region_id) const + { + std::shared_lock read_lock(rw_lock); + if (auto iter = safe_ts_map.find(region_id); iter != safe_ts_map.end()) + { + return SafeTsPair{ + .leader_safe_ts = (*iter->second).leader_safe_ts.load(), + .self_safe_ts = (*iter->second).self_safe_ts.load(), + }; + } + return SafeTsPair{0, 0}; + } + UInt64 getSelfSafeTS(RegionID region_id) const; void remove(RegionID region_id) diff --git a/dbms/src/Storages/KVStore/Region.cpp b/dbms/src/Storages/KVStore/Region.cpp index 5f1fe795060..c5d16f759a8 100644 --- a/dbms/src/Storages/KVStore/Region.cpp +++ b/dbms/src/Storages/KVStore/Region.cpp @@ -335,16 +335,6 @@ Region::~Region() GET_METRIC(tiflash_raft_classes_count, type_region).Decrement(); } -TableID Region::getMappedTableID() const -{ - return mapped_table_id; -} - -KeyspaceID Region::getKeyspaceID() const -{ - return keyspace_id; -} - void Region::setPeerState(raft_serverpb::PeerState state) { meta.setPeerState(state); diff --git a/dbms/src/Storages/KVStore/Region.h b/dbms/src/Storages/KVStore/Region.h index 9760d1ad0ef..d79c19624e3 100644 --- a/dbms/src/Storages/KVStore/Region.h +++ b/dbms/src/Storages/KVStore/Region.h @@ -229,8 +229,9 @@ class Region : public std::enable_shared_from_this RegionVersion version() const; RegionVersion confVer() const; - TableID getMappedTableID() const; - KeyspaceID getKeyspaceID() const; + TableID getMappedTableID() const { return mapped_table_id; } + KeyspaceID getKeyspaceID() const { return keyspace_id; } + KeyspaceTableID getKeyspaceTableID() const { return KeyspaceTableID{keyspace_id, mapped_table_id}; } /// get approx rows, bytes info about mem cache. std::pair getApproxMemCacheInfo() const; diff --git a/dbms/src/Storages/System/StorageSystemRegionInfos.cpp b/dbms/src/Storages/System/StorageSystemRegionInfos.cpp new file mode 100644 index 00000000000..4ae90794c04 --- /dev/null +++ b/dbms/src/Storages/System/StorageSystemRegionInfos.cpp @@ -0,0 +1,104 @@ +// Copyright 2025 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DB +{ + +StorageSystemRegionInfos::StorageSystemRegionInfos(const std::string & name_) + : name(name_) +{ + setColumns(ColumnsDescription({ + {"region_id", std::make_shared()}, + {"keyspace_id", std::make_shared(std::make_shared())}, + {"table_id", std::make_shared()}, + {"leader_safe_ts", std::make_shared()}, + {"self_safe_ts", std::make_shared()}, + })); +} + +struct RegionInfoSummary +{ + RegionID region_id; + KeyspaceTableID ks_table_id; + SafeTS self_safe_ts; + SafeTS leader_safe_ts; +}; + +BlockInputStreams StorageSystemRegionInfos::read( + const Names & column_names, + const SelectQueryInfo &, + const Context & context, + QueryProcessingStage::Enum & processed_stage, + const size_t /*max_block_size*/, + const unsigned /*num_streams*/) +{ + check(column_names); + processed_stage = QueryProcessingStage::FetchColumns; + + auto & tmt = context.getTMTContext(); + auto kvstore = tmt.getKVStore(); + std::map regions; + kvstore->traverseRegions([®ions](RegionID region_id, const RegionPtr & region) { + regions.emplace( + region_id, + RegionInfoSummary{ + .region_id = region_id, + .ks_table_id = region->getKeyspaceTableID(), + }); + }); + + auto & region_tbl = tmt.getRegionTable(); + auto & safe_ts_mgr = region_tbl.safeTsMgr(); + for (auto & [region_id, region_summary] : regions) + { + auto safe_ts_pair = safe_ts_mgr.get(region_id); + region_summary.leader_safe_ts = safe_ts_pair.leader_safe_ts; + region_summary.self_safe_ts = safe_ts_pair.self_safe_ts; + } + + MutableColumns res_columns = getSampleBlock().cloneEmptyColumns(); + for (const auto & [region_id, region_summary] : regions) + { + size_t j = 0; + res_columns[j++]->insert(region_id); + res_columns[j++]->insert(static_cast(region_summary.ks_table_id.first)); + res_columns[j++]->insert(region_summary.ks_table_id.second); + res_columns[j++]->insert(region_summary.leader_safe_ts); + res_columns[j++]->insert(region_summary.self_safe_ts); + } + + return BlockInputStreams( + 1, + std::make_shared(getSampleBlock().cloneWithColumns(std::move(res_columns)))); +} + + +} // namespace DB diff --git a/dbms/src/Storages/System/StorageSystemRegionInfos.h b/dbms/src/Storages/System/StorageSystemRegionInfos.h new file mode 100644 index 00000000000..9187faee87c --- /dev/null +++ b/dbms/src/Storages/System/StorageSystemRegionInfos.h @@ -0,0 +1,50 @@ +// Copyright 2025 PingCAP, Inc. +// +// 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 +{ +class Context; + + +class StorageSystemRegionInfos + : public ext::SharedPtrHelper + , public IStorage +{ +public: + std::string getName() const override { return "SystemRegionInfos"; } + std::string getTableName() const override { return name; } + + BlockInputStreams read( + const Names & column_names, + const SelectQueryInfo & query_info, + const Context & context, + QueryProcessingStage::Enum & processed_stage, + size_t max_block_size, + unsigned num_streams) override; + +private: + const std::string name; + +protected: + explicit StorageSystemRegionInfos(const std::string & name_); +}; + +} // namespace DB diff --git a/dbms/src/Storages/System/attachSystemTables.cpp b/dbms/src/Storages/System/attachSystemTables.cpp index 0fe6bb890b0..60173fb3150 100644 --- a/dbms/src/Storages/System/attachSystemTables.cpp +++ b/dbms/src/Storages/System/attachSystemTables.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ void attachSystemTablesLocal(IDatabase & system_database) system_database.attachTable("dt_tables", StorageSystemDTTables::create("dt_tables")); system_database.attachTable("dt_segments", StorageSystemDTSegments::create("dt_segments")); system_database.attachTable("dt_local_indexes", StorageSystemDTLocalIndexes::create("dt_local_indexes")); + system_database.attachTable("tiflash_regions", StorageSystemRegionInfos::create("tiflash_regions")); system_database.attachTable("tables", StorageSystemTables::create("tables")); system_database.attachTable("columns", StorageSystemColumns::create("columns")); system_database.attachTable("functions", StorageSystemFunctions::create("functions"));