Skip to content

Commit

Permalink
PageStorage: Log down the gc time for external pages (#5739)
Browse files Browse the repository at this point in the history
ref #5697
  • Loading branch information
JaySon-Huang authored Aug 31, 2022
1 parent 21a37ab commit 6262e0a
Show file tree
Hide file tree
Showing 11 changed files with 384 additions and 122 deletions.
1 change: 1 addition & 0 deletions dbms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ add_headers_and_sources(dbms src/Storages/Page/V3)
add_headers_and_sources(dbms src/Storages/Page/V3/LogFile)
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/)
add_headers_and_sources(dbms src/TiDB)
add_headers_and_sources(dbms src/Client)
Expand Down
11 changes: 2 additions & 9 deletions dbms/src/Storages/DeltaMerge/StoragePool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,10 +544,6 @@ void StoragePool::dataRegisterExternalPagesCallbacks(const ExternalPageCallbacks
break;
}
case PageStorageRunMode::ONLY_V3:
{
data_storage_v3->registerExternalPagesCallbacks(callbacks);
break;
}
case PageStorageRunMode::MIX_MODE:
{
// We have transformed all pages from V2 to V3 in `restore`, so
Expand All @@ -570,13 +566,10 @@ void StoragePool::dataUnregisterExternalPagesCallbacks(NamespaceId ns_id)
break;
}
case PageStorageRunMode::ONLY_V3:
{
data_storage_v3->unregisterExternalPagesCallbacks(ns_id);
break;
}
case PageStorageRunMode::MIX_MODE:
{
// no need unregister callback in V2.
// We have transformed all pages from V2 to V3 in `restore`, so
// only need to unregister callbacks for V3.
data_storage_v3->unregisterExternalPagesCallbacks(ns_id);
break;
}
Expand Down
23 changes: 1 addition & 22 deletions dbms/src/Storages/Page/V3/PageDirectory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1170,8 +1170,7 @@ void PageDirectory::apply(PageEntriesEdit && edit, const WriteLimiterPtr & write
{
// put the new created holder into `external_ids`
*holder = r.page_id;
std::lock_guard guard(external_ids_mutex);
external_ids.emplace_back(std::weak_ptr<PageIdV3Internal>(holder));
external_ids_by_ns.addExternalId(holder);
}
break;
}
Expand Down Expand Up @@ -1235,26 +1234,6 @@ void PageDirectory::gcApply(PageEntriesEdit && migrated_edit, const WriteLimiter
LOG_FMT_INFO(log, "GC apply done. [edit size={}]", migrated_edit.size());
}

std::set<PageId> PageDirectory::getAliveExternalIds(NamespaceId ns_id) const
{
std::set<PageId> valid_external_ids;
{
std::lock_guard guard(external_ids_mutex);
for (auto iter = external_ids.begin(); iter != external_ids.end(); /*empty*/)
{
if (auto holder = iter->lock(); holder == nullptr)
iter = external_ids.erase(iter);
else
{
if (holder->high == ns_id)
valid_external_ids.emplace(holder->low);
++iter;
}
}
}
return valid_external_ids;
}

std::pair<std::map<BlobFileId, PageIdAndVersionedEntries>, PageSize>
PageDirectory::getEntriesByBlobIds(const std::vector<BlobFileId> & blob_ids) const
{
Expand Down
20 changes: 17 additions & 3 deletions dbms/src/Storages/Page/V3/PageDirectory.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
#include <Encryption/FileProvider.h>
#include <Poco/Ext/ThreadNumber.h>
#include <Storages/Page/Page.h>
#include <Storages/Page/PageDefines.h>
#include <Storages/Page/Snapshot.h>
#include <Storages/Page/V3/BlobStore.h>
#include <Storages/Page/V3/MapUtils.h>
#include <Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.h>
#include <Storages/Page/V3/PageEntriesEdit.h>
#include <Storages/Page/V3/PageEntry.h>
#include <Storages/Page/V3/WALStore.h>
Expand Down Expand Up @@ -348,7 +350,20 @@ class PageDirectory
// When dump snapshot, we need to keep the last valid entry. Check out `tryDumpSnapshot` for the reason.
PageEntriesV3 gcInMemEntries(bool return_removed_entries = true, bool keep_last_valid_var_entry = false);

std::set<PageId> getAliveExternalIds(NamespaceId ns_id) const;
// Get the external id that is not deleted or being ref by another id by
// `ns_id`.
std::set<PageId> getAliveExternalIds(NamespaceId ns_id) const
{
return external_ids_by_ns.getAliveIds(ns_id);
}

// 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)
{
external_ids_by_ns.unregisterNamespace(ns_id);
}

PageEntriesEdit dumpSnapshotToEdit(PageDirectorySnapshotPtr snap = nullptr);

Expand Down Expand Up @@ -391,8 +406,7 @@ class PageDirectory
mutable std::mutex snapshots_mutex;
mutable std::list<std::weak_ptr<PageDirectorySnapshot>> snapshots;

mutable std::mutex external_ids_mutex;
mutable std::list<std::weak_ptr<PageIdV3Internal>> external_ids;
mutable ExternalIdsByNamespace external_ids_by_ns;

WALStorePtr wal;
const UInt64 max_persisted_log_files;
Expand Down
78 changes: 78 additions & 0 deletions dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.cpp
Original file line number Diff line number Diff line change
@@ -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.

#include <Storages/Page/PageDefines.h>
#include <Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.h>

#include <mutex>

namespace DB::PS::V3
{
void ExternalIdsByNamespace::addExternalIdUnlock(const std::shared_ptr<PageIdV3Internal> & external_id)
{
const NamespaceId & ns_id = external_id->high;
// 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<PageIdV3Internal>(external_id));
}

void ExternalIdsByNamespace::addExternalId(const std::shared_ptr<PageIdV3Internal> & external_id)
{
std::unique_lock map_guard(mu);
addExternalIdUnlock(external_id);
}

std::set<PageId> ExternalIdsByNamespace::getAliveIds(NamespaceId ns_id) const
{
// Now we assume a lock among all NamespaceIds is good enough.
std::unique_lock map_guard(mu);

std::set<PageId> valid_external_ids;
auto ns_iter = ids_by_ns.find(ns_id);
if (ns_iter == ids_by_ns.end())
return valid_external_ids;

// Only scan the given `ns_id`
auto & external_ids = ns_iter->second;
for (auto iter = external_ids.begin(); iter != external_ids.end(); /*empty*/)
{
if (auto holder = iter->lock(); holder == nullptr)
{
// the external id has been removed from `PageDirectory`,
// cleanup the invalid weak_ptr
iter = external_ids.erase(iter);
continue;
}
else
{
valid_external_ids.emplace(holder->low);
++iter;
}
}
// No valid external pages in this `ns_id`
if (valid_external_ids.empty())
{
valid_external_ids.erase(ns_id);
}
return valid_external_ids;
}

void ExternalIdsByNamespace::unregisterNamespace(NamespaceId ns_id)
{
std::unique_lock map_guard(mu);
// free all weak_ptrs of this namespace
ids_by_ns.erase(ns_id);
}
} // namespace DB::PS::V3
56 changes: 56 additions & 0 deletions dbms/src/Storages/Page/V3/PageDirectory/ExternalIdsByNamespace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// 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 <Common/nocopyable.h>
#include <Storages/Page/PageDefines.h>

#include <unordered_map>

namespace DB::PS::V3
{

// A thread-safe class to manage external ids.
// Manage all external ids by NamespaceId.
class ExternalIdsByNamespace
{
public:
ExternalIdsByNamespace() = default;

// Add a external ids
void addExternalId(const std::shared_ptr<PageIdV3Internal> & external_id);
// non thread-safe version, only for restore
void addExternalIdUnlock(const std::shared_ptr<PageIdV3Internal> & external_id);

// Get all alive external ids of given `ns_id`
// Will also cleanup the invalid external ids.
std::set<PageId> getAliveIds(NamespaceId 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);

DISALLOW_COPY_AND_MOVE(ExternalIdsByNamespace);

private:
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<std::weak_ptr<PageIdV3Internal>>;
using NamespaceMap = std::unordered_map<NamespaceId, ExternalIds>;
mutable NamespaceMap ids_by_ns;
};
} // namespace DB::PS::V3
4 changes: 2 additions & 2 deletions dbms/src/Storages/Page/V3/PageDirectoryFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void PageDirectoryFactory::applyRecord(
if (holder)
{
*holder = r.page_id;
dir->external_ids.emplace_back(std::weak_ptr<PageIdV3Internal>(holder));
dir->external_ids_by_ns.addExternalIdUnlock(holder);
}
break;
}
Expand All @@ -162,7 +162,7 @@ void PageDirectoryFactory::applyRecord(
if (holder)
{
*holder = r.page_id;
dir->external_ids.emplace_back(std::weak_ptr<PageIdV3Internal>(holder));
dir->external_ids_by_ns.addExternalIdUnlock(holder);
}
break;
}
Expand Down
Loading

0 comments on commit 6262e0a

Please sign in to comment.