-
Notifications
You must be signed in to change notification settings - Fork 2k
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
ADO.NET Grain Directory #9263
base: main
Are you sure you want to change the base?
ADO.NET Grain Directory #9263
Conversation
I've now added support for PostgreSQL. Unfortunately, I'm unable to add support for MariaDB due to its lack of support for table locking. The usual alternatives such as FOR UPDATE and TRANSACTION ISOLATION LEVEL SERIALIZABLE are ineffective at protecting from deadlocks in this context. Given this stalls the PR from proceeding, please advise on how to move forward. |
src/AdoNet/Orleans.GrainDirectory.AdoNet/AdoNetGrainDirectory.cs
Outdated
Show resolved
Hide resolved
I've refactored the SQL Server artefacts to use an alternate implementation of what we have. This new implementation is now based on a non-unique clustered index. Surprisingly, this approach does not appear to show the churn related performance issues we observed with our first naive go at it (which used a unique clustered index with a surrogate key). This alternate approach may also be viable for PostgreSQL and MariaDB, will look into these again. |
PostgreSQL & MySQL support is now added. |
This PR adds support for an ADO.NET Grain Directory.
A similar implementation to the one proposed here has been battle tested in our main application for a few months now using SQL Server 2019.
There are two main demands that drive the design decisions taken, especially with the SQL artefacts:
Given the above, the SQL Server implementation uses a non-unique clustered index based on the GrainId hash where uniqueness is guaranteed via careful locking hints in the stored procedures.
Important artefacts:
OrleansGrainDirectory
This is the directory table proper.
GrainIdHash
holds theStableHash
of theGrainId
. This is considered an (unfortunate) low-level implementation detail, and is therefore kept hidden behind the repository-likeRelationalOrleansQueries
class.CreatedOn
is purely for troubleshooting and not exposed outside the database at all.CI_OrleansGrainDirectory
This index turns the table into a clustered index that allows duplicates, namely on the
GrainIdHash
. This allows for individual changes without requiring full table locking, even if indexingGrainId
directly is not possible.Uniqueness of the
GrainId
proper is ensured via careful page locking hints in the stored procedures.Loss of perf due to concurrency will happen whenever the
GrainIdHash
collides or whenever the individual rows are stored on the same page. High fragmentation is inevitable due to the non-ordered nature of the hash key. However, the ordered nature of the index itself is what permits the acquisition of page locks in a consistent order, thereby preventing deadlocks from manifesting.This index must be maintained on a regular basis.
PostgreSQL & MySQL/MariaDB:
I was unable to figure out any granular way to prevent deadlocks in both PostgreSQL and MariaDB in this context. Both RDBMSs show lack of support for both non-unique clustered tables and explicit page locking. Alternates approaches utilizing what they do support always ended up failing the chaos tests with duplicates, deadlocks or both. Therefore both of the implementations rely on full table locks to prevent both duplicates and deadlocks.
Microsoft Reviewers: Open in CodeFlow