Skip to content

Conversation

ywelsch
Copy link
Contributor

@ywelsch ywelsch commented Oct 15, 2024

This is a follow-up to #13712, using a more fine-granular locking approach.

#13712 has fixed an issue where checkpoints together with concurrent queries that referenced the same table multiple times could lead to deadlocks. The locking approach in that PR used a transaction-level lock to coordinate lock acquisition for the same table.

In case of a query having many table scans (for different tables), this could potentially now block all executor threads if only a single table lock could not be acquired (e.g. due to a concurrent checkpoint). One thread would be blocked trying to acquire the checkpoint lock for the given table, and many others on the active_locks_lock (even though they would only be interested in acquiring the checkpoint lock for another table that wasn't being checkpointed).

Copy link
Collaborator

@Mytherin Mytherin left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! LGTM - one comment:

return lock;
}
unique_lock<mutex> transaction_lock(active_locks_lock);
auto &active_table_lock = active_locks[info];
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this might not be safe. We're keeping a reference to an ActiveTableLock, which is an object that sits in an unordered_map. Other threads can then modify the unordered_map (and add new elements to it). My suspicion is that, if the unordered_map is resized, this can potentially blow up.

Can we turn ActiveTableLock into a unique_ptr to prevent this from happening?

Copy link
Contributor

@carlopi carlopi Oct 15, 2024

Choose a reason for hiding this comment

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

People talking about unordered_map! I think iterators can become invalid on resize, but reference to object in the std::unordered_map are always valid.

This is confirmed by:

References to elements in the unordered_map container remain valid in all cases, even after a rehash.
at https://cplusplus.com/reference/unordered_map/unordered_map/insert/

This is one of the classic complaints on std::unordered_map, that basically always require an extra level of indirection (and so it's impossible to make them faster while keeping the same interface, and changing interface to not rely on element validity might break stuff in hidden ways).

That said, making this explicit might be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've reworked this in 43237a6.

@duckdb-draftbot duckdb-draftbot marked this pull request as draft October 15, 2024 15:36
@ywelsch ywelsch marked this pull request as ready for review October 15, 2024 15:36
@ywelsch ywelsch requested review from Mytherin and carlopi October 16, 2024 06:46
@Mytherin Mytherin merged commit 4756244 into duckdb:main Oct 16, 2024
45 checks passed
@Mytherin
Copy link
Collaborator

Thanks!

github-actions bot pushed a commit to duckdb/duckdb-r that referenced this pull request Oct 19, 2024
Use table-level locking when acquiring shared locks (duckdb/duckdb#14370)
Increase bounds for `test/sql/copy/file_size_bytes.test` (duckdb/duckdb#14367)
github-actions bot pushed a commit to duckdb/duckdb-r that referenced this pull request Oct 19, 2024
Use table-level locking when acquiring shared locks (duckdb/duckdb#14370)
Increase bounds for `test/sql/copy/file_size_bytes.test` (duckdb/duckdb#14367)
krlmlr added a commit to duckdb/duckdb-r that referenced this pull request Oct 20, 2024
Use table-level locking when acquiring shared locks (duckdb/duckdb#14370)
Increase bounds for `test/sql/copy/file_size_bytes.test` (duckdb/duckdb#14367)
github-actions bot pushed a commit to duckdb/duckdb-r that referenced this pull request Nov 2, 2024
Use table-level locking when acquiring shared locks (duckdb/duckdb#14370)
Increase bounds for `test/sql/copy/file_size_bytes.test` (duckdb/duckdb#14367)
github-merge-queue bot pushed a commit to duckdb/duckdb-r that referenced this pull request Nov 2, 2024
Use table-level locking when acquiring shared locks (duckdb/duckdb#14370)
Increase bounds for `test/sql/copy/file_size_bytes.test` (duckdb/duckdb#14367)

Co-authored-by: krlmlr <krlmlr@users.noreply.github.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.

3 participants