-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Add mutation support for StorageMemory #15127
Add mutation support for StorageMemory #15127
Conversation
322d4dc
to
ec683fe
Compare
ec683fe
to
c0b5f84
Compare
…tation-for-storagememory
Hey there, @ucasfl!
Implementing |
We have discussed it and the variant with copying the list of blocks to readers looks Ok. |
If implement multiversion storage, do we still need table-level locks for storagememory? It doesn't seem to be needed anymore?@alexey-milovidov |
Yes, there will be no table-level locks inside StorageMemory. |
Hi, I have added MultiVersion storage in StorageMemory, you can take a look at it if you have time. @Akazz @alexey-milovidov |
…tation-for-storagememory
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.
There seems to exist a race condition when concurrent INSERTs each try to add new blocks to their own copy of data
.
src/Storages/StorageMemory.cpp
Outdated
auto new_data = std::make_unique<BlocksList>(*(storage.data.get())); | ||
new_data->push_back(block); | ||
storage.data.set(std::move(new_data)); |
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.
There is going to be a problem due to a race condition here. Because we do not employ any CAS technique here, data can be lost when concurrent INSERTs each add a block to its own copy of data.
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.
So, in order to solve this problem, we still need a table-level lock? @Akazz
It seems that we still need a table-level lock to resolve concurrent mutation/insert. @alexey-milovidov |
f7dab0b
to
677787f
Compare
…tation-for-storagememory
src/Storages/StorageMemory.cpp
Outdated
data.set(std::move(new_data)); | ||
} | ||
} | ||
|
||
|
||
void StorageMemory::truncate( | ||
const ASTPtr &, const StorageMetadataPtr &, const Context &, TableExclusiveLockHolder &) | ||
{ | ||
std::lock_guard lock(mutex); |
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.
Looks like mutex is not needed anymore?
@@ -102,7 +106,9 @@ class MemoryBlockOutputStream : public IBlockOutputStream | |||
metadata_snapshot->check(block, true); | |||
{ | |||
std::lock_guard lock(storage.mutex); |
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.
Here the mutex also looks unneeded.
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 we need it to resolve concurrent insert, mutation, drop...
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'm not sure... Concurrent INSERT and mutation is Ok: mutation will mutate previously inserted data and concurrently inserted data will be left unmutated.
For DROP there is table-level lock: IStorage::lockExclusively.
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.
Let's write a test for race-condition (you can find similar .sh tests).
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 already have race-condition test 01454_storagememory_data_race_challenge.sh
.
src/Storages/StorageMemory.cpp
Outdated
@@ -201,17 +208,83 @@ BlockOutputStreamPtr StorageMemory::write(const ASTPtr & /*query*/, const Storag | |||
void StorageMemory::drop() | |||
{ | |||
std::lock_guard lock(mutex); |
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.
Here mutex also looks unneeded.
src/Storages/StorageMemory.cpp
Outdated
auto new_data = std::make_unique<BlocksList>(*(data.get())); | ||
auto data_it = new_data->begin(); | ||
auto out_it = out.begin(); | ||
while (data_it != new_data->end() && out_it != out.end()) |
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.
Check that data has the same number of blocks?
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.
Clarify in comments that deletion of whole blocks cannot happen here.
src/Storages/StorageMemory.cpp
Outdated
rows += buffer.rows(); | ||
bytes += buffer.bytes(); | ||
} | ||
data.set(std::make_unique<BlocksList>(out)); |
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.
Let's move calculation of rows/bytes and assignment out of the branch to avoid code duplication.
void StorageMemory::mutate(const MutationCommands & commands, const Context & context) | ||
{ | ||
std::lock_guard lock(mutex); | ||
auto metadata_snapshot = getInMemoryMetadataPtr(); |
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.
Please add a test checking that ALTER ADD/REMOVE column is not supported right now (that is Ok).
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.
Ok.
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.
LGTM, only a few changes remain.
…tation-for-storagememory
Alright. |
I hereby agree to the terms of the CLA available at: https://yandex.ru/legal/cla/?lang=en
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
fix #9117
Detailed description / Documentation draft:
...
By adding documentation, you'll allow users to try your new feature immediately, not when someone else will have time to document it later. Documentation is necessary for all features that affect user experience in any way. You can add brief documentation draft above, or add documentation right into your patch as Markdown files in docs folder.
If you are doing this for the first time, it's recommended to read the lightweight Contributing to ClickHouse Documentation guide first.
Information about CI checks: https://clickhouse.tech/docs/en/development/continuous-integration/