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

Do not take lock for shared context in setTempDataOnDisk #48219

Merged
merged 4 commits into from
Apr 6, 2023

Conversation

vdimir
Copy link
Member

@vdimir vdimir commented Mar 30, 2023

Changelog category (leave one):

  • Not for changelog (changelog entry is not required)

Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):

Documentation entry for user-facing changes

  • Documentation is written (mandatory for new features)

Information about CI checks: https://clickhouse.com/docs/en/development/continuous-integration/

@robot-clickhouse robot-clickhouse added the pr-not-for-changelog This PR should not be mentioned in the changelog label Mar 30, 2023
Comment on lines 757 to 768
void Context::setTempDataOnDisk(TemporaryDataOnDiskScopePtr temp_data_on_disk_)
{
auto lock = getLock();
/// It's set from `ProcessList::insert` in `executeQueryImpl` before query execution
/// so no races with `getTempDataOnDisk` which is called from query execution.
this->temp_data_on_disk = std::move(temp_data_on_disk_);
Copy link
Member

Choose a reason for hiding this comment

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

What about other functions that use temp_data_on_disk? For example

/// TODO: remove, use `getTempDataOnDisk`
VolumePtr Context::getTemporaryVolume() const
{
auto lock = getLock();
if (shared->temp_data_on_disk)

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, we have two different temp_data_on_disk one in shared part of context and one in current 🤔 I'll check why do we need two and when it was introduced. Probably shared is global and in current context is for query execution. Global one is set on server startup

if (!server_settings.tmp_policy.value.empty())
{
global_context->setTemporaryStoragePolicy(server_settings.tmp_policy, server_settings.max_temporary_data_on_disk_size);
}
else if (!server_settings.temporary_data_in_cache.value.empty())
{
global_context->setTemporaryStorageInCache(server_settings.temporary_data_in_cache, server_settings.max_temporary_data_on_disk_size);
}
else
{
std::string temporary_path = config().getString("tmp_path", path / "tmp/");
global_context->setTemporaryStoragePath(temporary_path, server_settings.max_temporary_data_on_disk_size);
}

Anyway, better naming and comments are required, so I'm going to investigate how to make it better and continue this PR

Copy link
Member Author

Choose a reason for hiding this comment

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

@tavplubix
I renamed temp_data_on_disk in shared context and added comments.
Also added locks for get/set this variable in shared context (not sure if it's mandatory since it's set once at Server::main), but in other places accessing shared parts of context we do (e.g. Context::setFlagsPath)

src/Interpreters/Context.cpp Outdated Show resolved Hide resolved
Comment on lines 866 to 871
auto lock = getLock();

if (shared->root_temp_data_on_disk)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Temporary storage is already set");

StoragePolicyPtr tmp_policy = getStoragePolicySelector(lock)->get(policy_name);
std::lock_guard storage_policies_lock(shared->storage_policies_mutex);
Copy link
Member

Choose a reason for hiding this comment

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

Does it mean that we cannot access Context while holding storage_policies_mutex?

Copy link
Member Author

Choose a reason for hiding this comment

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

Reduced scope of storage_policies_mutex not to overlap with getLock()

@tavplubix tavplubix self-assigned this Apr 5, 2023
@vdimir
Copy link
Member Author

vdimir commented Apr 6, 2023

Stateless tests (asan) [4/4] — fail: 1, passed: 1269, skipped: 10 Details

#43946

@vdimir vdimir merged commit e7a5c96 into master Apr 6, 2023
141 checks passed
@vdimir vdimir deleted the vdimir/lock_order_47072 branch April 6, 2023 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr-not-for-changelog This PR should not be mentioned in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ThreadSanitizer: lock-order-inversion
3 participants