-
Notifications
You must be signed in to change notification settings - Fork 412
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
*: fix data race occurred in SharedQueryBlockInputStream. #5309
Conversation
[REVIEW NOTIFICATION] This pull request has been approved by:
To complete the pull request process, please ask the reviewers in the list to review by filling The full list of commands accepted by this bot can be found here. Reviewer can indicate their review by submitting an approval review. |
/run-all-tests |
/run-sanitizer-test tsan |
Coverage for changed files
Coverage summary
full coverage report (for internal network access only) |
Currently fix is not graceful, I will find a way to make the code clear. |
/rebuild |
f3b4a43
to
4ef9b2b
Compare
/run-all-tests |
/run-sanitizer-test tsan |
3 similar comments
/run-sanitizer-test tsan |
/run-sanitizer-test tsan |
/run-sanitizer-test tsan |
/run-all-tests |
Coverage for changed files
Coverage summary
full coverage report (for internal network access only) |
/run-integration-test |
/rebuild |
@@ -400,8 +400,6 @@ void DAGQueryBlockInterpreter::executeAggregation( | |||
pipeline.streams_with_non_joined_data.clear(); | |||
pipeline.firstStream() = std::move(stream); | |||
|
|||
// should record for agg before restore concurrency. See #3804. | |||
recordProfileStreams(pipeline, query_block.aggregation_name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be kept here.
Because even in this pr, ProfileInfo.ExecuteTime
of sharedQuery is still wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be we can modify the logic of recordProfileStreams
to fix the #5314.
Such as recordProfileStream(stream, executor_id, concurrency);
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can fix in #5367
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although the cost of acquiring a lock in a single thread is very small due to futex
, no overhead is always better than some. Most of IProfilingBlockInputStream
don't need this lock so I think it's better to add a bool template parameter for IProfilingBlockInputStream
to reduce the meaningless overhead.
/run-sanitizer-test tsan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems difficult to make IProfilingBlockInputStream::read
thread-safe...
limit_exceeded_need_break = true; | ||
if (!checkTimeLimit()) | ||
limit_exceeded_need_break = true; | ||
} | ||
|
||
if (!limit_exceeded_need_break) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
limit_exceeded_need_break
is still not in lock protection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have protected it, but IMO the code is hard to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm...I see that limit_exceeded_need_break
is not an atomic variable and is read without a lock. You can see https://stackoverflow.com/questions/14624776/can-a-bool-read-write-operation-be-not-atomic-on-x86 for more information.
{ | ||
auto lock = get_lock(); | ||
info.updateExecutionTime(info.total_stopwatch.elapsed() - start_time); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In progressImpl
function, info
still may be used without lock protection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
Can we change the code here
SharedQueryBlockInputStream s?And these SharedQueryBlockInputStream s share the data only from SharedQueryBlockInputStream like queue , read_prefixed , read_suffixed , thread_manager . The data from IProfilingBlockInputStream don't need to be shared.
|
Yes, I have discussed with searise before, but I think it will be too many code for this bug fix. Maybe it's a better way to solve it. |
Now I think not fixing this bug is a better choice
I will close it |
What problem does this PR solve?
Issue Number: ref #5302
Problem Summary:
In restoreConcurrency(), it assigned multiple SharedQueryBlockInputStream to pipeline.
SharedQueryBlockInputStream enable multiple threads read from one stream, so the BlockStreamProfileInfo info may be accessed by multiple threads.
What is changed and how it works?
Change the read function in dbms/src/DataStreams/IProfilingBlockInputStream.h to identify streams which need to be shared with threads.
Add fine grained locks to protect the BlockStreamProfileInfo info.
Check List
Tests
Side effects
Documentation
Release note