Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FindObsoleteFiles() to directly check whether candidate files are live #10040

Closed
wants to merge 4 commits into from

Conversation

siying
Copy link
Contributor

@siying siying commented May 23, 2022

Summary: Right now, in FindObsoleteFiles() we build a list of all live SST files from all existing Versions. This is all done in DB mutex, and is O(mn) where m is number of versions and n is number of files. In some extereme cases, it can take very long. The list is used to see whether a candidate file still shows up in a version. With this commit, every candidate file is directly check against all the versions for file existance. This operation would be O(mk) where k is number of candidate files. Since is usually small (except perhaps full compaction in universal compaction), this is usually much faster than the previous solution.

Test Plan: TBD

@facebook-github-bot
Copy link
Contributor

@siying has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Copy link
Contributor

@riversand963 riversand963 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @siying for the PR.
Overall idea LGTM except for the test failures.

@@ -242,6 +242,14 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
log_file, immutable_db_options_.db_log_dir);
}
}
} else {
// Instead of filling ob_context->sst_live and job_context->blob_live,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: job_context

@facebook-github-bot
Copy link
Contributor

@siying has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@siying has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@siying siying changed the title [RFC] FindObsoleteFiles() to directly check whether candidate files are live FindObsoleteFiles() to directly check whether candidate files are live May 24, 2022
@siying siying force-pushed the speedup_find_obsolete_files branch from 310bd8f to 52091e3 Compare May 24, 2022 18:35
@facebook-github-bot
Copy link
Contributor

@siying has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@siying has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@siying
Copy link
Contributor Author

siying commented May 24, 2022

@riversand963 I fixed a bug by changing the approach of dealing with obsolete files by adding a flag indicating whether the file needs to be deleted. Can you take another look?

db/version_set.h Outdated
// be kept. This is because another FileMetaData still references the
// file, usually because the file is trivial moved so two FileMetadata
// is managing the file.
bool should_delete_file = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: preferably initialize all members in the same manner.

@@ -395,8 +403,10 @@ void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
state.manifest_delete_files.size());
// We may ignore the dbname when generating the file names.
for (auto& file : state.sst_delete_files) {
candidate_files.emplace_back(
MakeTableFileName(file.metadata->fd.GetNumber()), file.path);
if (file.should_delete_file) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the name here confusing: if a file is already in state_delete_files, why will should_delete_file be false? Only when I checked the definition of should_delete_file did I find out. I wonder whether we can have a better name than should_delete_file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File operations should not be on the critical path because it should happen infrequently if the db is configured properly, thus the overhead of std::shared_ptr should not be a concern here. I wonder why we didn't use smart pointers in the first place so that we did not have to worry about ref-counting in RocksDB codebase.

Clarification: this is a question/comment, not something we need to address in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of an approach #8494 is taking, but I am a little bit worried about the side effect. The side effect would be that for now, with trivial move and max_open_files=-1, we will open the file twice with two table readers, and passing in different level information, and taking I/O latency histogram in the correct level. With the change of consolidating FileMetaData, some of the information will be wrong after trivial move. (this gets tricky as with max_open_files!=-1, they are sometimes wrong anyway). So it is a larger problem to solve, and it's too complicated to deal with together. If someone has time, perhaps we can have a design discussion to get this straight, perhaps with @yiwu-arbug too.

@facebook-github-bot
Copy link
Contributor

@siying has updated the pull request. You must reimport the pull request before landing.

@siying siying force-pushed the speedup_find_obsolete_files branch from c721e62 to 8d145c0 Compare May 24, 2022 23:03
@facebook-github-bot
Copy link
Contributor

@siying has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@siying has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

…re live

Summary: Right now, in FindObsoleteFiles() we build a list of all live SST files from all existing Versions. This is all done in DB mutex, and is O(m*n) where m is number of versions and n is number of files. In some extereme cases, it can take very long. The list is used to see whether a candidate file still shows up in a version. With this commit, every candidate file is directly check against all the versions for file existance. This operation would be O(m*k) where k is number of candidate files. Since is usually small (except perhaps full compaction in universal compaction), this is usually much faster than the previous solution.

Test Plan: TBD
@siying siying force-pushed the speedup_find_obsolete_files branch from 8d145c0 to c06641a Compare May 25, 2022 17:16
@facebook-github-bot
Copy link
Contributor

@siying has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@siying has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

tabokie pushed a commit to tabokie/rocksdb that referenced this pull request Jun 6, 2022
facebook#10040)

Summary:
Right now, in FindObsoleteFiles() we build a list of all live SST files from all existing Versions. This is all done in DB mutex, and is O(m*n) where m is number of versions and n is number of files. In some extereme cases, it can take very long. The list is used to see whether a candidate file still shows up in a version. With this commit, every candidate file is directly check against all the versions for file existance. This operation would be O(m*k) where k is number of candidate files. Since is usually small (except perhaps full compaction in universal compaction), this is usually much faster than the previous solution.

Pull Request resolved: facebook#10040

Test Plan: TBD

Reviewed By: riversand963

Differential Revision: D36613391

fbshipit-source-id: 3f13b090f755d9b3ae417faec62cd6e798bac1eb
Signed-off-by: tabokie <xy.tao@outlook.com>
tabokie pushed a commit to tabokie/rocksdb that referenced this pull request Jun 9, 2022
facebook#10040)

Summary:
Right now, in FindObsoleteFiles() we build a list of all live SST files from all existing Versions. This is all done in DB mutex, and is O(m*n) where m is number of versions and n is number of files. In some extereme cases, it can take very long. The list is used to see whether a candidate file still shows up in a version. With this commit, every candidate file is directly check against all the versions for file existance. This operation would be O(m*k) where k is number of candidate files. Since is usually small (except perhaps full compaction in universal compaction), this is usually much faster than the previous solution.

Pull Request resolved: facebook#10040

Test Plan: TBD

Reviewed By: riversand963

Differential Revision: D36613391

fbshipit-source-id: 3f13b090f755d9b3ae417faec62cd6e798bac1eb
Signed-off-by: tabokie <xy.tao@outlook.com>
path = std::move(rhs.path);
metadata = rhs.metadata;
rhs.metadata = nullptr;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have only_delete_metadata = rhs.only_delete_metadata here too? For that, a potential merging conflict with #9924.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. It didn't cause any alarm because JobContext::sst_delete_files isn't moved or resized after its only_delete_metadata is set.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping author @siying

tabokie pushed a commit to tabokie/rocksdb that referenced this pull request Jun 15, 2022
facebook#10040)

Summary:
Right now, in FindObsoleteFiles() we build a list of all live SST files from all existing Versions. This is all done in DB mutex, and is O(m*n) where m is number of versions and n is number of files. In some extereme cases, it can take very long. The list is used to see whether a candidate file still shows up in a version. With this commit, every candidate file is directly check against all the versions for file existance. This operation would be O(m*k) where k is number of candidate files. Since is usually small (except perhaps full compaction in universal compaction), this is usually much faster than the previous solution.

Pull Request resolved: facebook#10040

Test Plan: TBD

Reviewed By: riversand963

Differential Revision: D36613391

fbshipit-source-id: 3f13b090f755d9b3ae417faec62cd6e798bac1eb
Signed-off-by: tabokie <xy.tao@outlook.com>
tabokie pushed a commit to tikv/rocksdb that referenced this pull request Jun 15, 2022
facebook#10040)

Summary:
Right now, in FindObsoleteFiles() we build a list of all live SST files from all existing Versions. This is all done in DB mutex, and is O(m*n) where m is number of versions and n is number of files. In some extereme cases, it can take very long. The list is used to see whether a candidate file still shows up in a version. With this commit, every candidate file is directly check against all the versions for file existance. This operation would be O(m*k) where k is number of candidate files. Since is usually small (except perhaps full compaction in universal compaction), this is usually much faster than the previous solution.

Pull Request resolved: facebook#10040

Test Plan: TBD

Reviewed By: riversand963

Differential Revision: D36613391

fbshipit-source-id: 3f13b090f755d9b3ae417faec62cd6e798bac1eb
Signed-off-by: tabokie <xy.tao@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants